12021-05-27
昨日の日記(12021年5月27日)です。 天気は曇り。 電波は悪い。
exeファイルを読んでみる 2日目
exeファイルのバイナリを読むことで2日間を消費した人 @skytomo221
— u1.5 (@u1_mas) 2021年5月27日
はい。
続きをしました。
MZスタブ
MZスタブでSignature以外にPEシグネチャのオフセットを見るべきでした。
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ.............. ! 4D 5A <------------------------------------------- Signature 00000010: B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 8.......@....... 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 F0 00 00 00 ............p... ! F0 00 00 00 <- PEシグネチャの ! オフセット 00000040: 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ..:..4.M!8.LM!Th 00000050: 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is.program.canno 00000060: 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t.be.run.in.DOS. 00000070: 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$....... 00000080: 45 DE DD 36 01 BF B3 65 01 BF B3 65 01 BF B3 65 E^]6.?3e.?3e.?3e 00000090: 08 C7 20 65 0B BF B3 65 BF CE B2 64 02 BF B3 65 .G.e.?3e?N2d.?3e 000000a0: BF CE B6 64 10 BF B3 65 BF CE B7 64 0B BF B3 65 ?N6d.?3e?N7d.?3e 000000b0: BF CE B0 64 02 BF B3 65 5A D7 B2 64 03 BF B3 65 ?N0d.?3eZW2d.?3e 000000c0: 01 BF B2 65 2E BF B3 65 97 CD BB 64 00 BF B3 65 .?2e.?3e.M;d.?3e 000000d0: 97 CD 4C 65 00 BF B3 65 97 CD B1 64 00 BF B3 65 .MLe.?3e.M1d.?3e 000000e0: 52 69 63 68 01 BF B3 65 00 00 00 00 00 00 00 00 Rich.?3e........
ドキュメントによると、
At location 0x3c, the stub has the file offset to the PE signature.
と書かれています。
つまり、 PEシグネチャがF0番目にある、 つまりF0番目からCOFFヘッダファイルが始まるということがわかります。
どうやら、 MZスタブには DOSヘッダとDOSスタブがあるみたいです。
DOSヘッダ
今日はちゃんと見ましょう。
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ.............. ! 4D 5A <------------------------------------------- Signature ! 90 00 <------------------------------------- Bytes on last page ! of file ! 03 00 <------------------------------- Pages in file ! 00 00 <------------------------- Relocations ! 04 00 <------------------- Size of header ! in paragraphs ! 00 00 <------------- Minimum extra ! paragraphs needed ! FF FF <------- Maximum extra ! paragraphs needed ! 00 00 <- Initial (relative) ! SS value 00000010: B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 8.......@....... ! B8 00 <------------------------------------------- Initial SP value ! 00 00 <------------------------------------- Checksum ! 00 00 <------------------------------- Initial IP value ! 00 00 <------------------------- Initial (relative) ! CS value ! 40 00 <------------------- File address of ! relocation table ! 00 00 <------------- Overlay number ! 00 00 00 00 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ! 00 00 00 00 <------------------------------------- Reserved words ! 00 00 <------------------------------- OEM identifier ! 00 00 <------------------------- OEM information ! 00 00 00 00 00 00 00 00 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 F0 00 00 00 ............p... ! 00 00 00 00 00 00 00 00 00 00 00 00 <------------- Reserved words ! F0 00 00 00 <- File address of ! new exe header
DOSスタブ
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000040: 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ..:..4.M!8.LM!Th ! 0E <---------------------------------------------- push cs ! 1F <------------------------------------------- pop ds ! BA 0E 00 <---------------------------------- mov dx, 0Eh ! B4 09 <---------------------------- mov ah, 09h ! CD 21 <---------------------- int 21h ! B8 01 4C <------------- mov ax, 4C01h ! CD 21 <------- int 21h ! 54 68 00000050: 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is.program.canno ! 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 00000060: 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t.be.run.in.DOS. ! 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 00000070: 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$....... ! 6D 6F 64 65 2E <---------------------------------- This program cannot ! be run in DOS mode. ! 0D <------------------------------- \r ! 0D <---------------------------- \r ! 0A <------------------------- \n ! 24 <---------------------- $
push cs pop ds mov dx, 0Eh mov ah, 09h int 21h mov ax, 4C01h int 21h
解説を追加します。
push cs pop ds ; CSレジスタをプッシュして、DSレジスタにポップしています。 mov dx, 0Eh ; 0EhをDXレジスタに転送します。 mov ah, 09h ; 09hをAHレジスタに転送します。 int 21h ; int はInterrupt(割り込み)という意味です。 ; 8086には「割り込みベクタ」という概念があり、割り込み処理の管理がしやすいようになっています。 ; 8086は int 00h から int FFh まで、合計で256種類の割り込みの利用ができます。 ; そして、MS-DOSでは、 int 21h で主なDOS APIを呼び出すことができます。 ; 具体的に提供される機能はAHレジスタに入っている値によって変わります。 ; AHレジスタに09hが入っている場合は、DXレジスタが指すアドレスにある文字列を表示します。 ; つまり、 ; mov dx, 0Eh ; mov ah, 09h ; int 21h ; の3行で「0Ehにある文字列(つまり'This program cannot be run in DOS mode.\r\r\n')を標準出力する」という意味になります。 ; ちなみに、0Ehというのは相対位置なので、コードが始まるアドレス00000040+DXレジスタが指すアドレス0Ehで絶対位置だと0000004Eとなります。 ; 文字列は24h($)のところで終わります。 mov ax, 4C01h ; 4ChをAHレジスタに、01をALレジスタに転送します。 int 21h ; また int 21h ですね。 ; AHレジスタに4Chが入っている場合は、ALレジスタに入っている値を戻り値として終了します。 ; つまり、 ; mov ax, 4C01h ; int 21h ; の2行で「1を返してプログラムを終了する」という意味になります。
「文字列は24h($)のところで終わります。」 これを見て、「あれ?ヌル文字じゃないの?」と思った方がいるかもしれません。 というか私はそうでした。 しかし、調べてみるとWikipediaの String の記事には次のことが書かれています。
Using a special byte other than null for terminating strings has historically appeared in both hardware and software, though sometimes with a value that was also a printing character. $ was used by many assembler systems, : used by CDC systems (this character had a value of zero), and the ZX80 used "[3] since this was the string delimiter in its BASIC language.
文字列を終了するためにnull以外の特別なバイトを使用することがあって、例えば$
は多くのアセンブラで使用されてたらしいですね。
ゴミ
00000080~000000e0は多分ゴミです。 余り?ですね。 ここに何書いても動きそうではあります。
00000080: 45 DE DD 36 01 BF B3 65 01 BF B3 65 01 BF B3 65 E^]6.?3e.?3e.?3e 00000090: 08 C7 20 65 0B BF B3 65 BF CE B2 64 02 BF B3 65 .G.e.?3e?N2d.?3e 000000a0: BF CE B6 64 10 BF B3 65 BF CE B7 64 0B BF B3 65 ?N6d.?3e?N7d.?3e 000000b0: BF CE B0 64 02 BF B3 65 5A D7 B2 64 03 BF B3 65 ?N0d.?3eZW2d.?3e 000000c0: 01 BF B2 65 2E BF B3 65 97 CD BB 64 00 BF B3 65 .?2e.?3e.M;d.?3e 000000d0: 97 CD 4C 65 00 BF B3 65 97 CD B1 64 00 BF B3 65 .MLe.?3e.M1d.?3e 000000e0: 52 69 63 68 01 BF B3 65 00 00 00 00 00 00 00 00 Rich.?3e........
いや、分かりません。 これについて詳しく書いてある資料があったら教えて下さい。
今日はこれで終わり。