51 lines
1.7 KiB
C
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;
|
|
}
|