LinuxでのParsim独自の.lnk形式

この話の始まり:2つのサーバー間の同期が機能しなくなった。 サーバーの1つ(Windowsを実行中)ではドキュメントが共有フォルダーにあり、2番目(Debianを実行中)ではwebdavのApacheが発生しました。 最初のサーバーのフォルダーにいくつかのサブフォルダーがありました。 あるドキュメントではドキュメントが置かれ、残りのドキュメントではドキュメントのラベルが作成されたため、ドキュメントはサブフォルダに分類されました。 また、最初のサーバーのフォルダーの内容は、次のように2番目のサーバーのフォルダーと同期されました。フォルダーの内容がコピーされ、ショートカットがポイントしたファイルに置き換えられました。 つまり、たとえば、ラベルがcorporate-template-65178.docドキュメントを指している場合、ラベルは削除され、このcorporate-template-65178.docはその場所に配置されました。



このシステムは3年間機能し、その後、警告なしに突然動作を停止しました。

そして彼女はどうしても修理されなければなりませんでした。



まだ興味深い場合は、猫の下でウェルカム。





だから。 飛行報告会が行われ、多数の人々にインタビューが行われ、文書の海が掘り出されましたが、誰がそれをいつ行ったかについての情報はどこにも見つかりませんでした。 サーバーの掘り下げが始まると、メールゲートウェイであるサーバーが見つかりました。 そして、その上でvbsとcmdのスクリプトが発見され、それらは同期に関与していました。 最初に、コンテンツがrsyncによって共有フォルダーからローカルフォルダーにコピーされ、次にショートカットがvbs-scriptを使用してドキュメントに置き換えられ、次にWindows用scp(パスワードなし、キー付き)を使用してcmdを介して、ファイルがwebdavにコピーされ、最後にコピー中に失われました変更します。

また、sshdキーがそれぞれ変更され、ファイルがwebdavにコピーされなくなったため、このシステムは動作を停止しました。



メールゲートウェイの管理者は、メールを送信する以外の機能がないはずのサーバーで、こうした奇妙なスクリプトやこれらのアクションを実行するスケジューラーのタスクが発見されたことに非常に驚きました。 これに加えて、彼らはこのサーバーを積み替え基地として使用することについて否定的に検閲し、検閲しませんでした。



サーキットは本当に奇妙に整理されていました。

最初のサーバーから2番目のサーバーに、3番目のサーバーがコピーされました。これは通常、最初の2つのサーバーとは何の関係もありません。

ほぼすぐに、中間体を取り除くアイデアが生まれ、それによってシステムのスキームが簡素化されました。



2台のサーバーがあるため、そのうちの1台で同期スクリプトを実行する必要がありました。

Windowsでサーバーを使用することは不可能であることが判明しました。サーバーに対する管理者権限がなく、実行した唯一のタスクがファイルサーバーとして機能していたためです。



したがって、Linuxに同様の機能を実装するためのオプションは1つだけです。

パブリックドメインには、Windowsショートカットの独自形式(.lnk形式)を解析するための資金がなかったため、タスクはすぐに複雑になりました。 一方、これはタスクに興味を与えました。



この問題は早急に解決する必要があり、Googleは支援を求められました。このプログラムでは、すでに1つのプログラムがすべてあり、そのプログラムはすでにバイナリ形式でした。 何が内部にあるのかわからないため、このプログラムを使用せず、独自のプログラムを作成することにしました。



同じGoogleで、この形式のファイルの構造を説明するドキュメントがリバースエンジニアリングによって取得されました。

情報源として使用されました。



システム自体には、次のパーツが含まれていました。

1)ショートカットを解析するCプログラム

2)同期および処理スクリプト

3)王冠の課題



だから

1)プログラム

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> struct TLinkHeaderInfo{ //4 bytes Always 4C 00 00 00 This is how windows knows it is a shortcut file unsigned long Signature; //16 bytes GUID for shortcut files The current GUID for shortcuts. //It may change in the future. 01 14 02 00 00 00 00 00 C0 00 00 00 00 00 46 unsigned char GUID[16]; //4 bytes Shortcut flags Shortcut flags are explained below unsigned long ShortcutFlags; //4 bytes Target file flags Flags are explained below unsigned long TargetFileFlags; //8 bytes Creation time unsigned char CreationTime[8]; //8 bytes Last Access time unsigned char LastAccessTime[8]; //8 bytes Modification time unsigned char ModificationTime[8]; //4 bytes File length //The length of the target file. 0 if the target is not a file. //This value is used to find the target when the link is broken. unsigned long FileLength; //4 bytes Icon number //If the file has a custom icon (set by the flags bit 6), //then this long integer indicates the index of the icon to use. Otherwise it is zero. unsigned long IconNumber; //4 bytes Show Window //the ShowWnd value to pass to the target application when starting it. //1:Normal Window 2:Minimized 3:Maximized unsigned long ShowWindow; // 4 bytes Hot Key The hot key assigned for this shortcut unsigned long HotKey; // 4 bytes Reserved Always 0 unsigned long Reserved1; // 4 bytes Reserved Always 0 unsigned long Reserved2; }; void main(int argc, char** argv) { const int HEADER_SIZE=76; const int FILE_ALLOCATION_INFO_HEADER_SIZE=28; char TempString[255]; int i, LinkFileSize; char LinkFileName[255]; char ExtractedFileName[255]; FILE* LinkFile; struct stat FileStatInfo; struct TLinkHeaderInfo HeaderStructure; size_t result; long TempInt=0; char LinkFileContent[10240]; if(strcmp(argv[1],"")==0) { printf("No parameter used.\n"); return; }; printf("FileName: %s\n",argv[1]); LinkFile=fopen(argv[1],"r"); if(LinkFile==NULL) { fclose(LinkFile); printf("No file found.\n"); return; }; // Open LNK File and parse it for file name // Get it size stat(argv[1],&FileStatInfo); printf("Link Filesize: %d\n", FileStatInfo.st_size); LinkFileSize=FileStatInfo.st_size; // read file to array result = fread (LinkFileContent,1,LinkFileSize,LinkFile); if (result != LinkFileSize) { printf ("Reading error\n"); }; fclose(LinkFile); HeaderStructure.Signature=LinkFileContent[0]*65536*256; HeaderStructure.Signature+=LinkFileContent[1]*65536; HeaderStructure.Signature+=LinkFileContent[2]*256+LinkFileContent[3]; printf("Signature: %X\n",HeaderStructure.Signature); printf("GUID: "); for(i=0;i<16;i++) { HeaderStructure.GUID[i]=LinkFileContent[4+i]; printf(" %X",HeaderStructure.GUID[i]); }; printf("\n"); HeaderStructure.ShortcutFlags=LinkFileContent[23]*65536*256; HeaderStructure.ShortcutFlags+=LinkFileContent[22]*65536; HeaderStructure.ShortcutFlags+=LinkFileContent[21]*256+LinkFileContent[20]; printf("Shortcut Flags: %X\n",HeaderStructure.ShortcutFlags); HeaderStructure.TargetFileFlags=LinkFileContent[27]*65536*256; HeaderStructure.TargetFileFlags+=LinkFileContent[26]*65536; HeaderStructure.TargetFileFlags+=LinkFileContent[25]*256+LinkFileContent[24]; printf("Target File Flags: %X\n",HeaderStructure.TargetFileFlags); for(i=0;i<8;i++){HeaderStructure.CreationTime[i]=LinkFileContent[28+i];}; for(i=0;i<8;i++){HeaderStructure.LastAccessTime[i]=LinkFileContent[36+i];}; for(i=0;i<8;i++){HeaderStructure.LastAccessTime[i]=LinkFileContent[44+i];}; HeaderStructure.FileLength=LinkFileContent[55]*65536*256; HeaderStructure.FileLength+=LinkFileContent[54]*65536; HeaderStructure.FileLength+=LinkFileContent[53]*256+LinkFileContent[52]; printf("Target File Size (bytes): %d\n",HeaderStructure.FileLength); HeaderStructure.IconNumber=LinkFileContent[59]*65536*256; HeaderStructure.IconNumber+=LinkFileContent[58]*65536; HeaderStructure.IconNumber+=LinkFileContent[57]*256+LinkFileContent[56]; printf("IconNumber: %X\n",HeaderStructure.IconNumber); HeaderStructure.ShowWindow=LinkFileContent[63]*65536*256; HeaderStructure.ShowWindow+=LinkFileContent[62]*65536; HeaderStructure.ShowWindow+=LinkFileContent[61]*256+LinkFileContent[60]; printf("ShowWindow Attributes: %X\n",HeaderStructure.IconNumber); HeaderStructure.HotKey=LinkFileContent[67]*65536*256; HeaderStructure.HotKey+=LinkFileContent[66]*65536; HeaderStructure.HotKey+=LinkFileContent[65]*256+LinkFileContent[64]; printf("HotKey Attributes: %X\n",HeaderStructure.HotKey); // Now extract file name and path unsigned int OFFSET=76+(unsigned char)LinkFileContent[76]; OFFSET+=(unsigned char)LinkFileContent[77]*256+(unsigned char)LinkFileContent[78]+2; OFFSET+=LinkFileContent[OFFSET]; printf("Share name: "); printf("%s\n",&LinkFileContent[OFFSET]); OFFSET+=strlen(&LinkFileContent[OFFSET]); OFFSET++; printf("File name: "); printf("%s\n",&LinkFileContent[OFFSET]); }
      
      







プログラムには洗練されたものはありません。

コンパイルする

 gcc ./lnkinfo.c -o lnkinfo
      
      







デバッグ情報を捨てる

 strip ./lnkinfo
      
      







ソースコードには、ファイルの場所(ネットワークフォルダー、リムーバブルディスクなど)などの解析フラグが含まれていません。必要に応じて、上記のドキュメントを注意深く読んでソースを補足できます。



最も重要な機能の準備ができたので、今それを適用する必要があります。



2)スクリプト。

最初のスクリプトは基本的な操作を実行します

たとえば、フォルダ/ usr / doc-syncにあります



 #!/bin/bash DOMAIN=MYDOMAIN USER=MYUSER PASSWORD=MYPASSWORD mount.cifs "//server/doc" /mnt/doc -o ro,dom=$DOMAIN,user=$USER,pass=$PASSWORD cd /usr/doc-sync WHERE_TO_PUT=/usr/local/webdav/files/docs rm -rf $WHERE_TO_PUT/* rsync -avz /mnt/doc/DocFolder1 $WHERE_TO_PUT rsync -avz /mnt/doc/DocFolder2 $WHERE_TO_PUT rsync -avz /mnt/doc/DocFolder3 $WHERE_TO_PUT umount /mnt/doc #      .lnk,    lnkinfo     #        (,    ) find $WHERE_TO_PUT -name "*.lnk" | sed -e 's/ /@/g' | awk '{printf "./lnkinfo "$1" | grep ile | grep ame:\n"}' \ | sed -e 's/@/ /g' \ | sed -e 's/(/\\(/g' \ | sed -e 's/)/\\)/g' \ | sed -e 's/ /\\ /g' \ | sed -e 's/lnkinfo\\ /lnkinfo /g' \ | sed -e 's/\\ grep/ grep/g'\ | sed -e 's/grep\\/grep/g'\ | sed -e 's/\\ |/ |/g'\ > ./haba-haba.sh && chmod a+x ./haba-haba.sh #      : PARAMETERS=`./haba-haba.sh | sed -e 's/ /@/g'` rm ./haba-haba.sh HABA2_EXIST=`ls | grep haba-haba2.sh` if [ "$HABA2_EXIST" != "" ] then rm ./haba-haba2.sh fi #      lnk   ,    . i="1" for PARAMETER in $PARAMETERS do if [ "$i" == "2" ] then #    ,       cp1251,     #  utf-8,     PARAMETER=`echo $PARAMETER | iconv -f windows-1251 -t utf8` echo $PARAMETER >> ./haba-haba2.sh i="1" continue fi if [ "$i" == "1" ] then i="2" echo $PARAMETER >> ./haba-haba2.sh continue fi done #        - exchange-lnk.sh #     -  -       cat ./haba-haba2.sh \ | sed -e 's/FileName:@/.\/exchange-lnk.sh /'\ | sed -e 's/File@name:@//'\ | sed -e 's/\\/\//g'\ | sed -e 's/\.lnk/\.lnk \\/g'\ | sed -e 's/@/\\ /g'\ | sed -e 's/(/\\(/g'\ | sed -e 's/)/\\)/g'\ >./haba-haba.sh rm ./haba-haba2.sh sh ./haba-haba.sh rm ./haba-haba.sh
      
      







ショートカットを削除し、その場所にドキュメントをコピーする2番目のスクリプト



 #!/bin/sh # remove first parameter and copy second parameter to first parameter's path LINK_NAME=`echo $1 | sed -e '{s/ /\\ /g}' | sed -e 's/(/\\(/g'` LINK_PATH=$(dirname "$LINK_NAME") echo $LINK_PATH echo Copy $2 to path of $1 cp "$2" "$LINK_PATH" rm "$1"
      
      







3)cron

さて、最後に残っているのは、クラウンにタスクを追加して、プロセスが自動的に行われるようにすることです。

 0 4 * * * root /usr/sync/doc-sync.sh
      
      







質問がある場合は、書いて、答えるか、補足/修正しようとします



All Articles