參考網站:
Microsoft pe-format
Wiki Portable_Executable
osdev COFF
XPE Viewer
UEFI image都是遵循微軟所定義的 PE/COFF格式,PE/COFF的格式可以參考維基百科的這張
圖:
使用 EDK2的 CpuDxe.efi來觀察一下:
可以看到一開始的 0x40個 Byte,是 DOS Header,起始的開頭為"MZ"(0x4D 0x5A),在 EDK2 structure定義如下:
而 0x3C則定義了PE Signature的位置,長度為 4 Bytes。以 CpuDxe.efi來說,是在 0x000000B8的位置。可從 0x000000B8的位置看到"PE\0\0"(0x50 0x45 0x00 0x00)的 PE Signature。
而從 0x40到 0xb7的這段空間稱為 DOS Stub,以前為了與 DOS相容而遺留下的產物,現在則直
接全部都填上 0x00。
在 PE Signature之後是 COFF File Header,在 EDK2中的定義如下:
COFF File Header長度為 20 Bytes,將其獨立拿出來看:
| Offset | Size | Field | Value | Description |
|---|---|---|---|---|
| 0 | 2 | Machine | 0x8664 | 代表 x64系統使用。 |
| 2 | 2 | NumberOfSections | 0x0006 | Section Table 的數量。 |
| 4 | 4 | TimeDateStamp | 0x0 | |
| 8 | 4 | PointerToSymbolTable | 0x0 | |
| 12 | 4 | NumberOfSymbols | 0x0 | |
| 16 | 2 | SizeOfOptionalHeader | 0x00F0 | Optional Header的 size。 |
| 18 | 2 | Characteristics | 0x2022 | IMAGE_FILE_EXECUTABLE_IMAGE + IMAGE_FILE_LARGE_ADDRESS_AWARE + IMAGE_FILE_DLL |
緊接下來則是 Optional Header,其長度可以從 COFF File Header得知為 0xF0。
其分成 3個部分,Standard Fields、Windows Specific Fields和
Data Directories。
| Offset | Size | Field | Value | Description |
|---|---|---|---|---|
| 0 | 2 | Magic | 0x020B | PE32+格式。 |
| 2 | 1 | MajorLinkerVersion | 0x0E | |
| 3 | 1 | MinorLinkerVersion | 0x1D | |
| 4 | 4 | SizeOfCode | 0x0000BAE0 | code section的 size。 |
| 8 | 4 | SizeOfInitializedData | 0x00001AE0 | initialized data section的 size。 |
| 12 | 4 | SizeOfUninitializedData | 0x0 | uninitialized data section的 size。 |
| 16 | 4 | AddressOfEntryPoint | 0x00001268 | entry point對ImageBase的相對位址。 |
| 20 | 4 | BaseOfCode | 0x000002C0 | code section對ImageBase的相對位址。 |
Windows Specific Fields (PE32+)
| Offset | Size | Field | Value | Description |
|---|---|---|---|---|
| 24 | 8 | ImageBase | 0x0 | |
| 32 | 4 | SectionAlignment | 0x00000020 | section在記憶體中為 32 Bytes alignment。 |
| 36 | 4 | FileAlignment | 0x00000020 | section中的raw data為 32 Bytes alignment。 |
| 40 | 2 | MajorOperatingSystemVersion | 0x0 | |
| 42 | 2 | MinorOperatingSystemVersion | 0x0 | |
| 44 | 2 | MajorImageVersion | 0x0 | |
| 46 | 2 | MinorImageVersion | 0x0 | |
| 48 | 2 | MajorSubsystemVersion | 0x0 | |
| 50 | 2 | MinorSubsystemVersion | 0x0 | |
| 52 | 4 | Win32VersionValue | 0x0 | |
| 56 | 4 | SizeOfImage | 0x0000DC40 | Image的 size,包含所有 headers。 CpuDxe.efi的 size就是0xDC40。 |
| 60 | 4 | SizeOfHeaders | 0x000002C0 | DOS stub、PE Header和 section headers的 size總和。 |
| 64 | 4 | CheckSum | 0x0 | |
| 68 | 2 | Subsystem | 0x000B | 代表為 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_ DRIVER。 |
| 70 | 2 | DLL Characteristics | 0x0 | |
| 72 | 8 | SizeOfStackReserve | 0x0 | |
| 80 | 8 | SizeOfStackCommit | 0x0 | |
| 88 | 8 | SizeOfHeapReserve | 0x0 | |
| 96 | 8 | SizeOfHeapCommit | 0x0 | |
| 104 | 4 | LoaderFlags | 0x0 | |
| 108 | 4 | NumberOfRvaAndSizes | 0x00000010 | Data Directories的數量。 |
Data Directories (PE32+)
| Offset | Size | Field | Value | Description |
|---|---|---|---|---|
| 112 | 8 | Export Table | 0x0 | |
| 120 | 8 | Import Table | 0x0 | |
| 128 | 8 | Resource Table | 0x0 | |
| 136 | 8 | Exception Table | 0x0 | |
| 144 | 8 | Certificate Table | 0x0 | |
| 152 | 8 | Base Relocation Table | 0x0000DBC0 | |
| 160 | 8 | Debug | 0x0 | |
| 168 | 8 | Architecture | 0x0 | |
| 176 | 8 | Global Ptr | 0x0 | |
| 184 | 8 | TLS Table | 0x0 | |
| 192 | 8 | Load Config Table | 0x0 | |
| 200 | 8 | Bound Import | 0x0 | |
| 208 | 8 | IAT | 0x0 | |
| 216 | 8 | Delay Import Descriptor | 0x0 | |
| 224 | 8 | CLR Runtime Header | 0x0 | |
| 232 | 8 | Reserved | 0x0 |
Optional Header的下個部份則為 Section Headers,其數量可以從 COFF File Header的
NumberOfSections讀出。
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 8 | Name | 8 Bytes的 ASCII字串,代表此 section的名字。 |
| 8 | 4 | VirtualSize | 此section在記憶體中的 size,如果大於 SizeOfRawData 則後面會填上 0x0。 |
| 12 | 4 | VirtualAddress | 此 section在記憶體中相對於 ImageBase的起始位址。 |
| 16 | 4 | SizeOfRawData | initialized date的 size。 |
| 20 | 4 | PointerToRawData | section raw data的 offset。 |
| 24 | 4 | PointerToRelocations | Relocation table的 offset。 |
| 28 | 4 | PointerToLinenumbers | Line Number table的 offset。 |
| 32 | 2 | NumberOfRelocations | Relocatione table的數量。 |
| 34 | 2 | NumberOfLinenumbers | Line Number table的數量。 |
| 36 | 4 | Characteristics | 32 Bits flag。 |
CpuDxe.efi可以使用 xpeviewer讀出 6個 sections:
| Section Name | Content |
|---|---|
| .text | Executable code |
| .rodata | Read-only initialized data |
| .data | Initialized data |
| .xdata | Exception information |
| .reloc | Image relocations |





沒有留言:
張貼留言