helos1/execformat/pe/struct.c
2021-10-10 14:39:17 +08:00

51 lines
1.7 KiB
C

#include "struct.h"
#include "../../runtime/panic_assert.h"
#include <string.h>
void execformat_pe_LoadMemory(execformat_pe_PortableExecutable *pe, void *image, uint32_t size) {
pe->begin = pe->pemagic = 0;
if (size < 2 || ((char *)image)[0] != 'M' || ((char *)image)[1] != 'Z')
return;
// look for the "PE\0\0" magic on a 8-byte boundary
for (int i = 8; i < size; i++) {
if (memcmp(image + i, EXECFORMAT_PE_HEADER_MAGIC, 4) == 0) {
pe->pemagic = image + i;
break;
}
}
if (pe->pemagic == 0)
return; // not found
pe->header = (execformat_pe_Header *)(pe->pemagic + 4);
pe->numSections = pe->header->numSections;
pe->optional = (void *)pe->header + sizeof(execformat_pe_Header);
pe->isPE32P = (*((uint16_t *)pe->optional) == EXECFORMAT_PE_OPTIONAL_HEADER_MAGIC_PE32P);
if (pe->isPE32P) {
pe->numDataDir = ((execformat_pe_OptionalHeader_PE32P *)pe->optional)->win.numRVAandSizes;
pe->sections =
pe->optional +
sizeof(execformat_pe_OptionalHeader_StandardFields_PE32P) +
sizeof(execformat_pe_OptionalHeader_WindowsFields_PE32P) +
sizeof(execformat_pe_OptionalHeader_DataDirectory) * pe->numDataDir;
assert((void *)pe->sections - pe->optional == pe->header->sizeofOptionalHeader && "PE32P OptionalHeader size mismatch");
} else {
pe->numDataDir = ((execformat_pe_OptionalHeader_PE32 *)pe->optional)->win.numRVAandSizes;
pe->sections =
pe->optional +
sizeof(execformat_pe_OptionalHeader_StandardFields_PE32) +
sizeof(execformat_pe_OptionalHeader_WindowsFields_PE32) +
sizeof(execformat_pe_OptionalHeader_DataDirectory) * pe->numDataDir;
assert((void *)pe->sections - pe->optional == pe->header->sizeofOptionalHeader && "PE32 OptionalHeader size mismatch");
}
pe->begin = image;
pe->size = size;
}