參考網站:
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 |
沒有留言:
張貼留言