私が気にする100の事象

気にしなければ始まらない。

12021-05-28

昨日の日記(12021-05-28)です。 天気忘れた。 電波は悪い。

exeファイルを読んでみる 3日目

続きをしました。

オプションヘッダ

   Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 00000100:                         0B 02 0E 1C 00 0E 00 00            ........
!                                  0B 02 <------------------- Magic
!                                        0E <---------------- MajorLinkerVersion
!                                           1C <------------- MinorLinkerVersion
!                                              00 0E 00 00 <- SizeOfCode
 00000110: 00 1E 00 00 00 00 00 00 A4 12 00 00 00 10 00 00    ........$.......
!          00 1E 00 00 <------------------------------------- SizeOfInitializedData
!                      00 00 00 00 <----------------------- SizeOfUninitializedData
!                                  A4 12 00 00 <------------- AddressOfEntryPoint
!                                              00 10 00 00 <- BaseOfCode
 00000120: 00 00 00 40 01 00 00 00 00 10 00 00 00 02 00 00    ...@............
 00000130: 06 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00    ................
 00000140: 00 70 00 00 00 04 00 00 00 00 00 00 03 00 60 81    .p............`.
 00000150: 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00    ................
 00000160: 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00    ................
 00000170: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00    ................
 00000180: D4 27 00 00 A0 00 00 00 00 50 00 00 E0 01 00 00    T'.......P..`...
 00000190: 00 40 00 00 5C 01 00 00 00 00 00 00 00 00 00 00    .@..\...........
 000001a0: 00 60 00 00 2C 00 00 00 30 22 00 00 70 00 00 00    .`..,...0"..p...
 000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000001c0: 00 00 00 00 00 00 00 00 A0 22 00 00 38 01 00 00    ........."..8...
 000001d0: 00 00 00 00 00 00 00 00 00 20 00 00 88 01 00 00    ................
 000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000001f0: 00 00 00 00 00 00 00 00                            ........```

1日目はここまでわかっていました。 ここでMagic(マジックナンバー)が0B 02、つまり20Bhですね。 20Bhだとドキュメントによると PE formatがPE32+とわかるので、 ここから更に解析できます。

   Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 00000100:                         0B 02 0E 1C 00 0E 00 00            ........
!                                  0B 02 <------------------- Magic
!                                        0E <---------------- MajorLinkerVersion
!                                           1C <------------- MinorLinkerVersion
!                                              00 0E 00 00 <- SizeOfCode
 00000110: 00 1E 00 00 00 00 00 00 A4 12 00 00 00 10 00 00    ........$.......
!          00 1E 00 00 <------------------------------------- SizeOfInitializedData
!                      00 00 00 00 <----------------------- SizeOfUninitializedData
!                                  A4 12 00 00 <------------- AddressOfEntryPoint
!                                              00 10 00 00 <- BaseOfCode
 00000120: 00 00 00 40 01 00 00 00 00 10 00 00 00 02 00 00    ...@............
!          00 00 00 40 01 00 00 00 <------------------------- ImageBase
!                                  00 10 00 00 <------------- SectionAlignment
!                                              00 02 00 00 <- FileAlignment
 00000130: 06 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00    ................
!          06 00 <------------------------------------- MajorOperatingSystemVersion
!                00 00 <------------------------------- MinorOperatingSystemVersion
!                      00 00 <------------------------------- MajorImageVersion
!                            00 00 <------------------------- MinorImageVersion
!                                  06 00 <------------------- MajorSubsystemVersion
!                                        00 00 <------------- MinorSubsystemVersion
!                                              00 00 00 00 <- Win32VersionValue
 00000140: 00 70 00 00 00 04 00 00 00 00 00 00 03 00 60 81    .p............`.
!          00 70 00 00 <------------------------------------- SizeOfImage
!                      00 04 00 00 <------------------------- SizeOfHeaders
!                                  00 00 00 00 <------------- CheckSum
!                                              03 00 <------- Subsystem
!                                                    60 81 <- DllCharacteristics
 00000150: 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00    ................
!          00 00 10 00 00 00 00 00 <------------------------- SizeOfStackReserve
!                                  00 10 00 00 00 00 00 00 <- SizeOfStackCommit
 00000160: 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00    ................
!          00 00 10 00 00 00 00 00 <------------------------- SizeOfHeapReserve
!                                  00 10 00 00 00 00 00 00 <- SizeOfHeapCommit
 00000170: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00    ................
!          00 00 00 00 <------------------------------------- LoaderFlags
!                      10 00 00 00 <------------------------- NumberOfRvaAndSizes
!                                  00 00 00 00 00 00 00 00 <- Export Table
 00000180: D4 27 00 00 A0 00 00 00 00 50 00 00 E0 01 00 00    T'.......P..`...
!          D4 27 00 00 A0 00 00 00 <------------------------- Import Table
!                                  00 50 00 00 E0 01 00 00 <- Resource Table
 00000190: 00 40 00 00 5C 01 00 00 00 00 00 00 00 00 00 00    .@..\...........
!          00 40 00 00 5C 01 00 00 <------------------------- Exception Table
!                                  00 00 00 00 00 00 00 00 <- Certificate Table
 000001a0: 00 60 00 00 2C 00 00 00 30 22 00 00 70 00 00 00    .`..,...0"..p...
!          00 60 00 00 2C 00 00 00 <------------------------- Base Relocation
!                                                             Table
!                                  30 22 00 00 70 00 00 00 <- Debug
 000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
!          00 00 00 00 00 00 00 00 <------------------------- Architecture
!                                  00 00 00 00 00 00 00 00 <- Global Ptr
 000001c0: 00 00 00 00 00 00 00 00 A0 22 00 00 38 01 00 00    ........."..8...
!          00 00 00 00 00 00 00 00 <------------------------- TLS Table
!                                  A0 22 00 00 38 01 00 00 <- Load Config Table
 000001d0: 00 00 00 00 00 00 00 00 00 20 00 00 88 01 00 00    ................
!          00 00 00 00 00 00 00 00 <------------------------- Bound Import
!                                  00 20 00 00 88 01 00 00 <- IAT
 000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
!          00 00 00 00 00 00 00 00 <------------------------- Delay Import
!                                                             Descriptor
!                                  00 00 00 00 00 00 00 00 <- CLR Runtime Header
 000001f0: 00 00 00 00 00 00 00 00                            ........
!          00 00 00 00 00 00 00 00 <------------------------- Reserved, must be
!                                                             zero

MajorLinkerVersionとMinorLinkerVersionでリンカーのバージョンが14.28であることがわかります。

SizeOfCodeでコード(テキスト)セクションのサイズがわかります。 複数のセクションがある場合は、すべてのコードセクションの合計となりますが、今回は一つしかないので、そのままです。 0E00hなので、コードセクションのサイズは3584バイトですね。

SizeOfInitializedDataで初期化されたデータセクションのサイズがわかります。 複数のデータセクションがある場合は、すべてのセクションの合計で、今回は複数あるので、合計となります。 1E00hなので、初期化されたデータセクションのサイズは7680バイトですね。

SizeOfUninitializedDataで初期化されていないデータセクション(BSS)のサイズがわかりますが、 今回は0なので、関係ありません。

BaseOfCodeは、メモリにロードされたときの実行可能ファイルに含まれる、コードセクションの先頭のイメージベース相対アドレスです。 今回の場合は1000hから始まります。

ImageBaseは、メモリに読み込まれるときの望ましいイメージベース相対アドレスです。 今回の場合は1040000000hですね。

MajorOperatingSystemVersionとMinorOperatingSystemVersionで必要なオペレーティングシステムのバージョンがわかります。 今回の場合は6.0です。 どうやらこの値は使われていないようです。

このPEファイルがメモリ上にロードされた時、各セクションは、SectionAlignmentの値の倍数になるアドレスに配置されます。 今回は1000hですね。

FileAlignmentは ここ を見ましょう。

MajorImageVersionとMinorImageVersionとMajorSubsystemVersionとMinorSubsystemVersionでイメージのバージョンがわかりますが、 特に設定していないので、0.0.0.0になります。

Win32VersionValueは予約済みの部分で、0にする必要があります。

SizeOfImageはイメージがメモリに読み込まれるときの、すべてのヘッダーを含むイメージのサイズで今回は7000hです。

SizeOfHeadersはFileAlignmentの倍数に切り上げられた、MS-DOSスタブ、PEヘッダー、セクションヘッダーの合計サイズで今回は4000hです。

CheckSumは文字通りチェックサムです。

Subsystemはこのイメージを実行するために必要なサブシステムです。 今回は03hですが、これはIMAGE_SUBSYSTEM_WINDOWS_CUIWindows CUI(コンソール)アプリケーション)を意味します。

DllCharacteristicsにはDLLの特性についての情報があります。 8160h
= 20h IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA (イメージは、高エントロピ64ビットの仮想アドレス空間を処理できる) + 40h IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE (DLL は読み込み時に再配置できる) + 100h IMAGE_DLLCHARACTERISTICS_NX_COMPAT (イメージはNXと互換性がある) + 8000h IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE (ターミナルサーバーを認識する)
まあ僕もよくわかりません。

さてここより後ろは、データディレクトリのゾーンになります。 データディレクトリは前の4バイトがアドレス、後ろの4バイトがサイズを表します。 詳しくは ここ を読めばわかります。 Import TableとIATについてだけは話します。 Import Tableは、他の実行可能ファイルにアクセスして呼び出す関数についての情報が書かれているアドレスとサイズが書かれています。 IATは、他の実行可能ファイルにアクセスして呼び出す関数についてのアドレスが書かれているアドレスとサイズが書かれています。 違うっぽい

セクションテーブル

   Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 000001f0:                         2E 74 65 78 74 00 00 00            .text...
 00000200: 0C 0D 00 00 00 10 00 00 00 0E 00 00 00 04 00 00    ................
 00000210: 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60    ...............`
 00000220: 2E 72 64 61 74 61 00 00 2A 0E 00 00 00 20 00 00    .rdata..*.......
 00000230: 00 10 00 00 00 12 00 00 00 00 00 00 00 00 00 00    ................
 00000240: 00 00 00 00 40 00 00 40 2E 64 61 74 61 00 00 00    ....@..@.data...
 00000250: 48 06 00 00 00 30 00 00 00 02 00 00 00 22 00 00    H....0......."..
 00000260: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0    ............@..@
 00000270: 2E 70 64 61 74 61 00 00 5C 01 00 00 00 40 00 00    .pdata..\....@..
 00000280: 00 02 00 00 00 24 00 00 00 00 00 00 00 00 00 00    .....$..........
 00000290: 00 00 00 00 40 00 00 40 2E 72 73 72 63 00 00 00    ....@..@.rsrc...
 000002a0: E0 01 00 00 00 50 00 00 00 02 00 00 00 26 00 00    `....P.......&..
 000002b0: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 40    ............@..@
 000002c0: 2E 72 65 6C 6F 63 00 00 2C 00 00 00 00 60 00 00    .reloc..,....`..
 000002d0: 00 02 00 00 00 28 00 00 00 00 00 00 00 00 00 00    .....(..........
 000002e0: 00 00 00 00 40 00 00 42                            ....@..B

セクションですが、6つのセクションがあることがこの時点でわかります。 めんどくさいので、最初のセクションだけささっと見てみましょう。

   Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 000001f0:                         2E 74 65 78 74 00 00 00            .text...
 00000200: 0C 0D 00 00 00 10 00 00 00 0E 00 00 00 04 00 00    ................
 00000210: 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60    ...............`

1つのセクションはこんな感じです。

   Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 000001f0:                         2E 74 65 78 74 00 00 00            .text...
!                                  2E 74 65 78 74 00 00 00 <- Name
 00000200: 0C 0D 00 00 00 10 00 00 00 0E 00 00 00 04 00 00    ................
!          0C 0D 00 00 <------------------------------------- VirtualSize
!                      00 10 00 00 <------------------------- VirtualAddress
!                                  00 0E 00 00 <------------- SizeOfRawData
!                                              00 04 00 00 <- PointerToRawData
 00000210: 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60    ...............`
!          00 00 00 00 <------------------------------------- PointerToRelocations
!                      00 00 00 00 <------------------------- PointerToLinenumbers
!                                  00 00 <------------------- NumberOfRelocations
!                                        00 00 <------------- NumberOfLinenumbers
!                                              20 00 00 60 <- Characteristics

.textというセクションの名前ですが、 これがコードに関する情報です。 SizeOfRawDataはこのファイルにおけるセクションのサイズ、 PointerToRawDataはこのファイルにおけるセクションのアドレス を表します。 つまり、00000400h~00001200h(0E00h)の部分がコードです。

えーーーと、疲れました。 今日はここで終わり。

次回からは00000400hを読みましょう。

   Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 000002e0:                         00 00 00 00 00 00 00 00            ........
 000002f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00000390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000003a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000003b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000003c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000003d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000003e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 000003f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

ここの部分はあまりですね。

セクションテーブルとセクションの間の隙間です。 今日は隙間を眺めて、 終わりましょう。