[toc] ## Windows `winnt.h` 型別 `BYTE` 1 byte `WORD` 2 bytes `DWORD` 4 bytes `QWORD` 8 bytes ## Headers 範例: ![image](https://hackmd.io/_uploads/S1Mripwhxl.png) ### IMAGE_DOS_HEADER 64 bytes ![image](https://hackmd.io/_uploads/BJbhjRvnxx.png) ```c typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; ``` - `e_magic` Magic Number `4D 5A` hex: `5A4D` Ascii: `MZ` -> MS-DOS Executable ![image](https://hackmd.io/_uploads/HyshV0P3xl.png) - `e_lfanew` File address of new exe header, 指向NT Header的位置 `10 01 00 00` hex:`00000110` ![image](https://hackmd.io/_uploads/Hkhi4ADnge.png) ### DOS Stub ![image](https://hackmd.io/_uploads/ryr6oCwhlg.png) ### IMAGE_NT_HEADERS ![image](https://hackmd.io/_uploads/rkt0i0wnlx.png) https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_nt_headers32 https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_nt_headers64 ```c typedef struct _IMAGE_NT_HEADERS64 { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER64 OptionalHeader; } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; ``` - `Signature` 識別檔案為 PE 映射的 4 位元組簽章。 位元組為 「PE\0\0」。 A 4-byte signature identifying the file as a PE image. The bytes are "PE\0\0". `50 45 00 00` hex:`00004550` ASCII: `PE..` -> Portable Executable ![image](https://hackmd.io/_uploads/HkNRERP2lx.png) - `FileHeader` 指定檔頭 的`IMAGE_FILE_HEADER` 結構。 An `IMAGE_FILE_HEADER` structure that specifies the file header. - `OptionalHeader` 指定選擇性檔案標頭 的`IMAGE_OPTIONAL_HEADER` 結構。 An `IMAGE_OPTIONAL_HEADER` structure that specifies the optional file header. #### IMAGE_FILE_HEADER 20 bytes ![image](https://hackmd.io/_uploads/S1_lnRP3xx.png) https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_file_header ```c typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; ``` - `Machine` 計算機的架構類型。 圖像檔只能在指定的計算機上執行,或是模擬指定計算機的系統。 這個成員可以是下列其中一個值。 The architecture type of the computer. An image file can only be run on the specified computer or a system that emulates the specified computer. This member can be one of the following values. 完整列表: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types 常見: | Field | Value | | -------------------------- | --------:| | IMAGE_FILE_MACHINE_UNKNOWN | 0 | | IMAGE_FILE_MACHINE_I386 | 0x014c | | IMAGE_FILE_MACHINE_ALPHA | 0x0184 | | IMAGE_FILE_MACHINE_POWERPC | 0x01F0 | | IMAGE_FILE_MACHINE_AMD64 | 0x8664 | `64 86` hex:`8664` -> AMD64 ![image](https://hackmd.io/_uploads/Sy3yBAPhgx.png) - `TimeDateStamp` 映射時間戳的低 32 位。 這代表連結器建立影像的日期和時間。 根據系統時鐘,此值以自午夜(00:00:00:00)、1970 年 1 月 1 日起經過的秒數表示。 The low 32 bits of the time stamp of the image. This represents the date and time the image was created by the linker. The value is represented in the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Universal Coordinated Time, according to the system clock. - `SizeOfOptionalHeader` 選擇性標頭的大小,以位元組為單位。 對於物件檔,此值應該是0。 The size of the optional header, in bytes. This value should be 0 for object files. - `Characteristics` 影像的特性。 這個成員可以是下列其中一或多個值。 The characteristics of the image. This member can be one or more of the following values. 完整列表: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#characteristics 常見: | Field | Value | | --------------------------- | ------:| | IMAGE_FILE_EXECUTABLE_IMAGE | 0x0002 | | IMAGE_FILE_DLL | 0x2000 | `22 00` hex:`0022` -> `0x0002 | 0x0020` -> `IMAGE_FILE_EXECUTABLE_IMAGE` and `IMAGE_FILE_LARGE_ADDRESS_AWARE` ![image](https://hackmd.io/_uploads/ryAxBCDnxe.png) #### IMAGE_OPTIONAL_HEADER ![image](https://hackmd.io/_uploads/ryr-hCw2ex.png) https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header32 https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header64 ```c typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; ``` - `Magic` 圖像檔的狀態。 這個成員可以是下列其中一個值。 The state of the image file. This member can be one of the following values. | Value | Meaning | | ------------------------------------ |:-------------------- | | IMAGE_NT_OPTIONAL_HDR_MAGIC | 檔案是可執行的映像。 | | IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b | 檔案是可執行的映像。 | | IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b | 檔案是可執行的映像。 | | IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 | 檔案是 ROM 映像。 | `0B 02` hex: `020B` -> IMAGE_NT_OPTIONAL_HDR64_MAGIC ![image](https://hackmd.io/_uploads/HJ105CDhxe.png) - `AddressOfEntryPoint` 相對於映像基地址的進入點函式指標。 對於可執行檔,這是起始位址。 對於設備驅動器,這是初始化函式的位址。 DLL 的進入點函式是選擇性的。 當沒有任何進入點存在時,這個成員為零。 A pointer to the entry point function, relative to the image base address. For executable files, this is the starting address. For device drivers, this is the address of the initialization function. The entry point function is optional for DLLs. When no entry point is present, this member is zero. `58 09 37 00` hex: `00370958` ![image](https://hackmd.io/_uploads/SkLriAPnee.png) - `ImageBase` >[!Important] 在 IMAGE_OPTIONAL_HEADER32 中, 此欄位是 DWORD 在記憶體中載入影像時,影像第一個字節的慣用位址。 這個值是64K位元組的倍數。 DLL 的預設值為 0x10000000。 應用程式的預設值為 0x00400000,但0x00010000 Windows CE 除外。 The preferred address of the first byte of the image when it is loaded in memory. This value is a multiple of 64K bytes. The default value for DLLs is 0x10000000. The default value for applications is 0x00400000, except on Windows CE where it is 0x00010000. `00 00 00 40 01 00 00 00` -> hex: `0000000140000000` ![image](https://hackmd.io/_uploads/rybEnCwnlg.png) ### Section Headers ![image](https://hackmd.io/_uploads/ryYMACP3lg.png) 總共有八個IMAGE_SECTION_HEADER `IMAGE_SECTION_HEADER SectionHeaders[8]` #### IMAGE_SECTION_HEADER ![image](https://hackmd.io/_uploads/Byz-kkd2gx.png) https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_section_header ```c typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; ``` - `Name` >[!Note] 白話 區段名稱,佔8B 8 位元組、以 Null 填補的 UTF-8 字串。 如果字串長度剛好是八個字元,則不會終止 Null 字元。 對於較長的名稱,此成員包含正斜線 (/) ,後面接著十進位數的 ASCII 表示法,該數位是字串數據表中的位移。 可執行檔映像不使用字串數據表,且不支持超過八個字元的區段名稱。 An 8-byte, null-padded UTF-8 string. There is no terminating null character if the string is exactly eight characters long. For longer names, this member contains a forward slash (/) followed by an ASCII representation of a decimal number that is an offset into the string table. Executable images do not use a string table and do not support section names longer than eight characters. `2E 74 65 78 74 00 00 00` ASCII: `.text` ![image](https://hackmd.io/_uploads/SygN-JOhxg.png) - `Misc.VirtualSize` >[!Note] 白話 記憶體中佔的大小 載入記憶體時,區段的大小總計,以位元組為單位。 如果此值大於 SizeOfRawData 成員,則區段會填入零。 此欄位僅適用於可執行的影像,而且應該針對對象檔設定為 0。 The total size of the section when loaded into memory, in bytes. If this value is greater than the SizeOfRawData member, the section is filled with zeroes. This field is valid only for executable images and should be set to 0 for object files. `AE 4F 42 00` hex: `00424FAE` ![image](https://hackmd.io/_uploads/ByOQKJuneg.png) - `VirtualAddress` >[!Note] 白話 記憶體中的起始位置 載入記憶體時,區段第一個字節的位址,相對於映像基底。 對於對象檔,這是套用重新配置之前第一個字節的位址。 The address of the first byte of the section when loaded into memory, relative to the image base. For object files, this is the address of the first byte before relocation is applied. ![image](https://hackmd.io/_uploads/SkcMtyd3ll.png) - `SizeofRawData` >[!Note] 白話 檔案中佔的大小 磁碟上初始化數據的大小,以位元組為單位。 這個值必須是 IMAGE_OPTIONAL_HEADER 結構的 FileAlignment 成員的倍數。 如果此值小於 VirtualSize 成員,則區段的其餘部分會填入零。 如果區段只包含未初始化的數據,則成員為零。 The size of the initialized data on disk, in bytes. This value must be a multiple of the FileAlignment member of the IMAGE_OPTIONAL_HEADER structure. If this value is less than the VirtualSize member, the remainder of the section is filled with zeroes. If the section contains only uninitialized data, the member is zero. ![image](https://hackmd.io/_uploads/r1UEY1O2gg.png) - `PointerToRawData` >[!Note] 白話 檔案中的起始位置 COFF 檔案內第一頁的檔案指標。 這個值必須是 IMAGE_OPTIONAL_HEADER 結構的 FileAlignment 成員的倍數。 如果區段只包含未初始化的數據,請將此成員設定為零。 A file pointer to the first page within the COFF file. This value must be a multiple of the FileAlignment member of the IMAGE_OPTIONAL_HEADER structure. If a section contains only uninitialized data, set this member is zero. ![image](https://hackmd.io/_uploads/HJ4Bt1unxe.png) - `Characteristics` 影像的特性。 The characteristics of the image. 一樣,可以一次有多種,去查IMAGE_SECTION_HEADER內的表。 ![image](https://hackmd.io/_uploads/HkQ8Ykunge.png)