EXEヘッダ(MZ)とPEヘッダの間にある Richの謎

小さい実行ファイルを作ろうとして気づいたのですが、 謎の Richという文字列が MZとPEの間にほぼ確実にあります。

4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ
B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00         @
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00
0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68         !     Th
69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno
74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS
6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode.   $
58 2B 84 77 1C 4A EA 24 1C 4A EA 24 1C 4A EA 24   $ J.$.$.J.J.$
92 42 8A 24 16 4A EA 24 9F 42 E5 24 14 4A EA 24   $ J.$   $.J.$
9F 42 B7 24 39 4A EA 24 1C 4A EB 24 21 48 EA 24   $ J.$.$.J.J.$
92 42 B5 24 5C 4A EA 24 9F 42 B4 24 1D 4A EA 24   $ J.$   $.J.$
9F 42 B0 24 1D 4A EA 24 52 69 63 68 1C 4A EA 24   $ J.$Rich.J.$
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 45 00 00 4C 01 03 00 AC 31 1E 42 00 00 00 00 PE  L   1 B
実はこれ、Microsoftのリンカのシグネチャみたいなんですよね。

このRich構造体は、
BC=Base Code

BC XOR 0x536e6144, BC, BC, BC,
BC XOR A1, BC XOR B1,
BC XOR A2, BC XOR B2,
              :
BC XOR An-1, BC XOR Bn-1,
"Rich", BC
AnやBnといった値は、objファイルのcomp.idセクションを符号化したものや、コンパイル時間などが含まれるようなのですが、詳しいことはわかりません。
ソース見てもわかるのはそこまでですね。

extern DWORD LinkID;
DWORD DansRich(LPVOID par0,LPVOID par1){
   DWORD *HeapReg,*HeapRegBase,*pos,*pos2=NULL;
   DWORD local[5],Tmp,Result;
        if(HeapReg=HeapAlloc(HeapHandle,0,0)==NULL){
          exceptionDebug();
        }
        HeapReg[0]=0;
        HeapReg[1]=0x05A0BEC;
        HeapReg[2]=1;
        local[0]=1;
        HeapRegBase=HeapReg
        local[4]=*par0[0x214];
        do{
          if(pos2){
            pos2=pos2[0x44];
          }
          else{
            pos2=local[4];
          }
          if(pos2==0){
            j=*par0[0x234];
            i=0;
            Tmp=j;
            if(j){
              Result=*par0[0x230];
              do{
                Tmp+=([Result+i]&0xff)<<i;
                i++;
              }while(i<j);
            }
            pos=HeapRegBase;
            while(pos){
              sig_b+=pos[1]<<pos[2];
              pos=*pos;
            }
        sig_size=(sig_b/0x20 %3 +local[0])*8+0x20;
            [par0]=sig_size;
            HeapReg=HeapAlloc(HeapHandle,HEAP_ZERO_MEMORY,sig_size);
            goto Sub03;
          }
          Result=0;
Sub01:
        if(Result){
            Result=Result[0x58];
          }
          else{
            Result=pos2[0x40];
          }
        }while(Result==0);

          Tmp=Result[0x38];
          if((Tmp&0xffff0000)==0){
            if(Result[0x6C]&0x40){
              Tmp=*LinkID[0x38];
            }
          }
          pos=HeapRegBase;
          while(pos){
            if(pos[1]==Tmp){
              HeapReg[2]++;
              goto    Sub01;
            }
            pos=*pos;
          }
        HeapReg=HeapAlloc(HeapHandle,0,12);
        if(HeapReg){
          *HeapReg=HeapRegBase;
          HeapReg[1]=Tmp;
          HeapReg[2]=1;
          HeapRegBase=HeapReg;
          ++local[0];
          goto    Sub01;
        }
Sub03:
        if(HeapReg==NULL)exceptionDebug();
          [*par1]=HeapReg;
          sig_a=Tmp ^ "DanS";
          pos=HeapReg;
          *(pos++)=sig_a;
          *(pos++)=sig_b;
          *(pos++)=sig_b;
          *(pos++)=sig_b;
        if(HeapReg){
          do{
            *(pos++)=[HeapReg+04h]^Tmp;
            *(pos++)=[HeapReg+08h]^Tmp;
            HeapReg=[HeapReg];
            HeapFree(HeapHandle,0,HeapReg);
          }while(HeapReg);
          Result=[par0];
        }
          *(pos++)="Rich";
          *pos=Tmp;
   return Result;
}

英語ですが、このあたりこの辺りが 詳しく載ってるサイトです。

おすすめ

3件のフィードバック

  1. EXEヘッダ/PEヘッダ/NEヘッダ

    PEヘッダ以外の扱いが適当な所が多いような気がしたのでメモ書きしてみる。

  2. EXEヘッダ/PEヘッダ/NEヘッダ

    PEヘッダ以外の扱いが適当な所が多いような気がしたのでメモ書きしてみる。

  3. EXEヘッダ/PEヘッダ/NEヘッダ

    PEヘッダ以外の扱いが適当な所が多いような気がしたのでメモ書きしてみる。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です