1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #ifndef __PE_HEADER_
19 #define __PE_HEADER_
20
21 #include <endian.h>
22 #include <sys/types.h>
23
24 //
25 // Directory Entries
26 //
27 static constexpr size_t IMAGE_DIRECTORY_ENTRY_EXPORT = 0;
28 static constexpr size_t IMAGE_DIRECTORY_ENTRY_IMPORT = 1;
29 static constexpr size_t IMAGE_DIRECTORY_ENTRY_RESOURCE = 2;
30 static constexpr size_t IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3;
31 static constexpr size_t IMAGE_DIRECTORY_ENTRY_SECURITY = 4;
32 static constexpr size_t IMAGE_DIRECTORY_ENTRY_BASERELOC = 5;
33 static constexpr size_t IMAGE_DIRECTORY_ENTRY_DEBUG = 6;
34 static constexpr size_t IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7;
35 static constexpr size_t IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8;
36 static constexpr size_t IMAGE_DIRECTORY_ENTRY_TLS = 9;
37 static constexpr size_t IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10;
38
39 static constexpr size_t IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
40 static constexpr size_t IMAGE_SIZEOF_SHORT_NAME = 8;
41
42 static constexpr uint32_t kPEHeader = 0x4550;
43 struct IMAGE_NT_HEADERS64;
44
45 struct IMAGE_DOS_HEADER { // DOS .EXE header
46 u16 e_magic; // Magic number
47 u16 e_cblp; // Bytes on last page of file
48 u16 e_cp; // Pages in file
49 u16 e_crlc; // Relocations
50 u16 e_cparhdr; // Size of header in paragraphs
51 u16 e_minalloc; // Minimum extra paragraphs needed
52 u16 e_maxalloc; // Maximum extra paragraphs needed
53 u16 e_ss; // Initial (relative) SS value
54 u16 e_sp; // Initial SP value
55 u16 e_csum; // Checksum
56 u16 e_ip; // Initial IP value
57 u16 e_cs; // Initial (relative) CS value
58 u16 e_lfarlc; // File address of relocation table
59 u16 e_ovno; // Overlay number
60 u16 e_res[4]; // Reserved words
61 u16 e_oemid; // OEM identifier (for e_oeminfo)
62 u16 e_oeminfo; // OEM information; e_oemid specific
63 u16 e_res2[10]; // Reserved words
64 u32 e_lfanew; // File address of new exe header
65
CheckMagicIMAGE_DOS_HEADER66 constexpr bool CheckMagic() const { return LE32(e_magic) == 0x5A4D; }
GetPEHeaderIMAGE_DOS_HEADER67 IMAGE_NT_HEADERS64 *GetPEHeader() {
68 auto address = reinterpret_cast<char *>(this);
69 const auto pe_header =
70 reinterpret_cast<IMAGE_NT_HEADERS64 *>(address + e_lfanew);
71 return pe_header;
72 }
GetPEHeaderIMAGE_DOS_HEADER73 const IMAGE_NT_HEADERS64 *GetPEHeader() const {
74 auto address = reinterpret_cast<const char *>(this);
75 const auto pe_header =
76 reinterpret_cast<const IMAGE_NT_HEADERS64 *>(address + e_lfanew);
77 return pe_header;
78 }
79 } __attribute__((packed));
80
81 enum class ArchitectureType : u16 {
82 Unknown = 0x00,
83 ALPHAAXPOld = 0x183,
84 ALPHAAXP = 0x184,
85 ALPHAAXP64Bit = 0x284,
86 AM33 = 0x1D3,
87 AMD64 = 0x8664,
88 ARM = 0x1C0,
89 ARM64 = 0xAA64,
90 ARMNT = 0x1C4,
91 CLRPureMSIL = 0xC0EE,
92 EBC = 0xEBC,
93 I386 = 0x14C,
94 I860 = 0x14D,
95 IA64 = 0x200,
96 LOONGARCH32 = 0x6232,
97 LOONGARCH64 = 0x6264,
98 M32R = 0x9041,
99 MIPS16 = 0x266,
100 MIPSFPU = 0x366,
101 MIPSFPU16 = 0x466,
102 MOTOROLA68000 = 0x268,
103 POWERPC = 0x1F0,
104 POWERPCFP = 0x1F1,
105 POWERPC64 = 0x1F2,
106 R3000 = 0x162,
107 R4000 = 0x166,
108 R10000 = 0x168,
109 RISCV32 = 0x5032,
110 RISCV64 = 0x5064,
111 RISCV128 = 0x5128,
112 SH3 = 0x1A2,
113 SH3DSP = 0x1A3,
114 SH4 = 0x1A6,
115 SH5 = 0x1A8,
116 THUMB = 0x1C2,
117 WCEMIPSV2 = 0x169
118 };
119
120 struct IMAGE_FILE_HEADER {
121 u32 Signature;
122 ArchitectureType Machine;
123 u16 NumberOfSections;
124 u32 TimeDateStamp;
125 u32 PointerToSymbolTable;
126 u32 NumberOfSymbols;
127 u16 SizeOfOptionalHeader;
128 u16 Characteristics;
129 } __attribute__((packed));
130
131 struct IMAGE_DATA_DIRECTORY {
132 u32 VirtualAddress;
133 u32 Size;
134 } __attribute__((packed));
135
136 enum SubsystemType : u16 {
137 Unknown = 0x00,
138 Native = 0x01,
139 WindowsGUI = 0x02,
140 WindowsCUI = 0x03,
141 OS2CUI = 0x05,
142 POSIXCUI = 0x07,
143 Windows9xNative = 0x08,
144 WindowsCEGUI = 0x09,
145 EFIApplication = 0x0A,
146 EFIBootServiceDriver = 0x0B,
147 EFIRuntimeDriver = 0x0C,
148 EFIROM = 0x0D,
149 Xbox = 0x0E,
150 WindowsBootApplication = 0x10
151 };
152
ToString(SubsystemType type)153 constexpr const char *ToString(SubsystemType type) {
154 switch (type) {
155 case Native:
156 return "Native";
157 case WindowsGUI:
158 return "WindowsGUI";
159 case WindowsCUI:
160 return "WindowsCUI";
161 case OS2CUI:
162 return "OS2CUI";
163 case POSIXCUI:
164 return "POSIXCUI";
165 case Windows9xNative:
166 return "Windows9xNative";
167 case WindowsCEGUI:
168 return "WindowsCEGUI";
169 case EFIApplication:
170 return "EFIApplication";
171 case EFIBootServiceDriver:
172 return "EFIBootServiceDriver";
173 case EFIRuntimeDriver:
174 return "EFIRuntimeDriver";
175 case EFIROM:
176 return "EFIROM";
177 case Xbox:
178 return "Xbox";
179 case WindowsBootApplication:
180 return "WindowsBootApplication";
181 default:
182 return "Unknown";
183 }
184 }
185
186 struct IMAGE_OPTIONAL_HEADER64 {
187 u16 Magic;
188 u8 MajorLinkerVersion;
189 u8 MinorLinkerVersion;
190 u32 SizeOfCode;
191 u32 SizeOfInitializedData;
192 u32 SizeOfUninitializedData;
193 u32 AddressOfEntryPoint;
194 u32 BaseOfCode;
195 u64 ImageBase;
196 u32 SectionAlignment;
197 u32 FileAlignment;
198 u16 MajorOperatingSystemVersion;
199 u16 MinorOperatingSystemVersion;
200 u16 MajorImageVersion;
201 u16 MinorImageVersion;
202 u16 MajorSubsystemVersion;
203 u16 MinorSubsystemVersion;
204 u32 Win32VersionValue;
205 u32 SizeOfImage;
206 u32 SizeOfHeaders;
207 u32 CheckSum;
208 SubsystemType Subsystem;
209 u16 DllCharacteristics;
210 u64 SizeOfStackReserve;
211 u64 SizeOfStackCommit;
212 u64 SizeOfHeapReserve;
213 u64 SizeOfHeapCommit;
214 u32 LoaderFlags;
215 u32 NumberOfRvaAndSizes;
216 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
217 } __attribute__((packed));
218
219 struct IMAGE_OPTIONAL_HEADER32 {
220 u16 Magic;
221 u8 MajorLinkerVersion;
222 u8 MinorLinkerVersion;
223 u32 SizeOfCode;
224 u32 SizeOfInitializedData;
225 u32 SizeOfUninitializedData;
226 u32 AddressOfEntryPoint;
227 u32 BaseOfCode;
228 u32 BaseOfData;
229 u32 ImageBase;
230 u32 SectionAlignment;
231 u32 FileAlignment;
232 u16 MajorOperatingSystemVersion;
233 u16 MinorOperatingSystemVersion;
234 u16 MajorImageVersion;
235 u16 MinorImageVersion;
236 u16 MajorSubsystemVersion;
237 u16 MinorSubsystemVersion;
238 u32 Win32VersionValue;
239 u32 SizeOfImage;
240 u32 SizeOfHeaders;
241 u32 CheckSum;
242 u16 Subsystem;
243 u16 DllCharacteristics;
244 u32 SizeOfStackReserve;
245 u32 SizeOfStackCommit;
246 u32 SizeOfHeapReserve;
247 u32 SizeOfHeapCommit;
248 u32 LoaderFlags;
249 u32 NumberOfRvaAndSizes;
250 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
251 } __attribute__((packed));
252
253 struct IMAGE_SECTION_HEADER {
254 char Name[IMAGE_SIZEOF_SHORT_NAME];
255 union {
256 u32 PhysicalAddress;
257 u32 VirtualSize;
258 } Misc;
259 u32 VirtualAddress;
260 u32 SizeOfRawData;
261 u32 PointerToRawData;
262 u32 PointerToRelocations;
263 u32 PointerToLinenumbers;
264 u16 NumberOfRelocations;
265 u16 NumberOfLinenumbers;
266 u32 Characteristics;
267 } __attribute__((packed));
268
269 struct IMAGE_NT_HEADERS64 {
270 IMAGE_FILE_HEADER FileHeader;
271 IMAGE_OPTIONAL_HEADER64 OptionalHeader;
272 } __attribute__((packed));
273
274 struct EFI_IMAGE_BASE_RELOCATION {
275 uint32_t VirtualAddress;
276 uint32_t SizeOfBlock;
277 };
278
279 static constexpr size_t EFI_IMAGE_REL_BASED_ABSOLUTE = 0;
280 static constexpr size_t EFI_IMAGE_REL_BASED_HIGH = 1;
281 static constexpr size_t EFI_IMAGE_REL_BASED_LOW = 2;
282 static constexpr size_t EFI_IMAGE_REL_BASED_HIGHLOW = 3;
283 static constexpr size_t EFI_IMAGE_REL_BASED_HIGHADJ = 4;
284 static constexpr size_t EFI_IMAGE_REL_BASED_MIPS_JMPADDR = 5;
285 static constexpr size_t EFI_IMAGE_REL_BASED_ARM_MOV32A = 5;
286 static constexpr size_t EFI_IMAGE_REL_BASED_ARM_MOV32T = 7;
287 static constexpr size_t EFI_IMAGE_REL_BASED_IA64_IMM64 = 9;
288 static constexpr size_t EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 = 9;
289 static constexpr size_t EFI_IMAGE_REL_BASED_DIR64 = 10;
290
291 #endif
292