MCPcopy Create free account
hub / github.com/GJDuck/e9patch / parsePE

Method parsePE

src/e9tool/e9frontend.cpp:1345–1547  ·  view source on GitHub ↗

* Parse a PE file into an ELF structure. */

Source from the content-addressed store, hash-verified

1343 * Parse a PE file into an ELF structure.
1344 */
1345ELF *e9tool::parsePE(const char *filename)
1346{
1347 int fd = open(filename, O_RDONLY, 0);
1348 if (fd < 0)
1349 error("failed to open file \"%s\" for reading: %s", filename,
1350 strerror(errno));
1351
1352 struct stat stat;
1353 if (fstat(fd, &stat) != 0)
1354 error("failed to get statistics for file \"%s\": %s", filename,
1355 strerror(errno));
1356
1357 size_t size = (size_t)stat.st_size;
1358 void *ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
1359 if (ptr == MAP_FAILED)
1360 error("failed to map file \"%s\" into memory: %s", filename,
1361 strerror(errno));
1362 close(fd);
1363 const uint8_t *data = (const uint8_t *)ptr;
1364
1365 if (size < 0x3c + sizeof(uint32_t))
1366 error("failed to parse PE file \"%s\"; file size (%zu) is too small "
1367 "for MS-DOS header", filename, size);
1368 if (data[0] != 'M' || data[1] != 'Z')
1369 error("failed to parse PE file \"%s\"; invalid MS-DOS stub header "
1370 "magic number, expected \"MZ\"", filename);
1371 uint32_t pe_offset = *(const uint32_t *)(data + 0x3c);
1372 const size_t pe_hdr_size = sizeof(uint32_t) + sizeof(IMAGE_FILE_HEADER) +
1373 sizeof(IMAGE_OPTIONAL_HEADER64);
1374 if (pe_offset < 0x3c + sizeof(uint32_t) || pe_offset + pe_hdr_size > size)
1375 error("failed to parse PE file \"%s\"; file size (%zu) is too small"
1376 "for PE header(s)", filename, size);
1377 if (data[pe_offset] != 'P' ||
1378 data[pe_offset+1] != 'E' ||
1379 data[pe_offset+2] != 0x0 ||
1380 data[pe_offset+3] != 0x0)
1381 error("failed to parse PE file \"%s\"; invalid PE signature, "
1382 "expected \"PE\\0\\0\"", filename);
1383 const IMAGE_FILE_HEADER *file_hdr =
1384 (PIMAGE_FILE_HEADER)(data + pe_offset + sizeof(uint32_t));
1385 if (file_hdr->Machine != IMAGE_FILE_MACHINE_AMD64)
1386 error("failed to parse PE file \"%s\"; invalid machine (0x%x), "
1387 "expected x86_64 (0x%x)", filename, file_hdr->Machine,
1388 IMAGE_FILE_MACHINE_AMD64);
1389 if (file_hdr->SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER64))
1390 error("failed to parse PE file \"%s\"; invalid optional header "
1391 "size (%zu), expected (>=%zu)", filename,
1392 file_hdr->SizeOfOptionalHeader,
1393 sizeof(IMAGE_OPTIONAL_HEADER64));
1394 const IMAGE_OPTIONAL_HEADER64 *opt_hdr =
1395 (PIMAGE_OPTIONAL_HEADER64)(file_hdr + 1);
1396 static const uint16_t PE64_MAGIC = 0x020b;
1397 if (opt_hdr->Magic != PE64_MAGIC)
1398 error("failed to parse PE file \"%s\"; invalid magic number (0x%x), "
1399 "expected PE64 (0x%x)", filename, opt_hdr->Magic, PE64_MAGIC);
1400 BinaryType type = BINARY_TYPE_PE_EXE;
1401 if ((file_hdr->Characteristics & IMAGE_FILE_DLL) != 0)
1402 type = BINARY_TYPE_PE_DLL;

Callers

nothing calls this directly

Calls 10

openFunction · 0.85
errorFunction · 0.85
strerrorFunction · 0.85
fstatFunction · 0.85
mmapFunction · 0.85
closeFunction · 0.85
strDupFunction · 0.85
backMethod · 0.80
findPEDataFunction · 0.70
sizeMethod · 0.45

Tested by

no test coverage detected