MCPcopy Index your code
hub / github.com/GJDuck/e9patch / parsePE

Function parsePE

src/e9patch/e9pe.cpp:163–256  ·  view source on GitHub ↗

* Parse a Windows PE executable. */

Source from the content-addressed store, hash-verified

161 * Parse a Windows PE executable.
162 */
163void parsePE(Binary *B)
164{
165 const char *filename = B->filename;
166 uint8_t *data = B->patched.bytes;
167 size_t size = B->size;
168 PEInfo &info = B->pe;
169
170 if (size < 0x3c + sizeof(uint32_t))
171 error("failed to parse PE file \"%s\"; file size (%zu) is too small "
172 "for MS-DOS header", filename, size);
173 if (data[0] != 'M' || data[1] != 'Z')
174 error("failed to parse PE file \"%s\"; invalid MS-DOS stub header "
175 "magic number, expected \"MZ\"", filename);
176 uint32_t pe_offset = *(const uint32_t *)(data + 0x3c);
177 const size_t pe_hdr_size = sizeof(uint32_t) + sizeof(IMAGE_FILE_HEADER) +
178 sizeof(IMAGE_OPTIONAL_HEADER64);
179 if (pe_offset < 0x3c + sizeof(uint32_t) || pe_offset + pe_hdr_size > size)
180 error("failed to parse PE file \"%s\"; file size (%zu) is too small"
181 "for PE header(s)", filename, size);
182 if (data[pe_offset] != 'P' ||
183 data[pe_offset+1] != 'E' ||
184 data[pe_offset+2] != 0x0 ||
185 data[pe_offset+3] != 0x0)
186 error("failed to parse PE file \"%s\"; invalid PE signature, "
187 "expected \"PE\\0\\0\"", filename);
188 PIMAGE_FILE_HEADER file_hdr =
189 (PIMAGE_FILE_HEADER)(data + pe_offset + sizeof(uint32_t));
190 if (file_hdr->Machine != IMAGE_FILE_MACHINE_AMD64)
191 error("failed to parse PE file \"%s\"; invalid machine (0x%x), "
192 "expected x86_64 (0x%x)", filename, file_hdr->Machine,
193 IMAGE_FILE_MACHINE_AMD64);
194 if (file_hdr->SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER64))
195 error("failed to parse PE file \"%s\"; invalid optional header "
196 "size (%zu), expected (>=%zu)", filename,
197 file_hdr->SizeOfOptionalHeader,
198 sizeof(IMAGE_OPTIONAL_HEADER64));
199 PIMAGE_OPTIONAL_HEADER64 opt_hdr =
200 (PIMAGE_OPTIONAL_HEADER64)(file_hdr + 1);
201 static const uint16_t PE64_MAGIC = 0x020b;
202 if (opt_hdr->Magic != PE64_MAGIC)
203 error("failed to parse PE file \"%s\"; invalid magic number (0x%x), "
204 "expected PE64 (0x%x)", filename, opt_hdr->Magic, PE64_MAGIC);
205 uint32_t section_align = opt_hdr->SectionAlignment;
206 if (section_align == 0 || !IS_POW_2(section_align))
207 error("failed to parse PE file \"%s\"; invalid section alignment (%u), "
208 "expected a power-of-two", filename, section_align);
209 uint32_t file_align = opt_hdr->FileAlignment;
210 if (file_align < 512 || !IS_POW_2(file_align))
211 error("failed to parse PE file \"%s\"; invalid file alignment (%u), "
212 "expected (>=512, power-of-two)", filename, file_align);
213 uint64_t image_base = opt_hdr->ImageBase;
214 if (image_base % WINDOWS_VIRTUAL_ALLOC_SIZE != 0)
215 error("failed to parse PE file \"%s\"; invalid image base (0x%lx), "
216 "expected a multiple of virtual allocation granularity (%u)",
217 filename, image_base, WINDOWS_VIRTUAL_ALLOC_SIZE);
218 PIMAGE_SECTION_HEADER shdr =
219 (PIMAGE_SECTION_HEADER)&opt_hdr->DataDirectory[
220 opt_hdr->NumberOfRvaAndSizes];

Callers 2

parseBinaryFunction · 0.85
parseBinaryMethod · 0.85

Calls 3

errorFunction · 0.85
strncmpFunction · 0.85
reserveFunction · 0.85

Tested by

no test coverage detected