IMAGE_DATA_DIRECTORY DataDirectory[16];
} IMAGE_OPTIONAL_HEADER;
+typedef struct {
+ uint16 Magic;
+ uint8 MajorLinkerVersion;
+ uint8 MinorLinkerVersion;
+ uint32 SizeOfCode;
+ uint32 SizeOfInitializedData;
+ uint32 SizeOfUninitializedData;
+ uint32 AddressOfEntryPoint;
+ uint32 BaseOfCode;
+ uint64 ImageBase;
+ uint32 SectionAlignment;
+ uint32 FileAlignment;
+ uint16 MajorOperatingSystemVersion;
+ uint16 MinorOperatingSystemVersion;
+ uint16 MajorImageVersion;
+ uint16 MinorImageVersion;
+ uint16 MajorSubsystemVersion;
+ uint16 MinorSubsystemVersion;
+ uint32 Win32VersionValue;
+ uint32 SizeOfImage;
+ uint32 SizeOfHeaders;
+ uint32 CheckSum;
+ uint16 Subsystem;
+ uint16 DllCharacteristics;
+ uint64 SizeOfStackReserve;
+ uint64 SizeOfStackCommit;
+ uint64 SizeOfHeapReserve;
+ uint64 SizeOfHeapCommit;
+ uint32 LoaderFlags;
+ uint32 NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[16];
+} PE64_IMAGE_OPTIONAL_HEADER;
+
static int
match8(void *buf, char *cmp)
{
return strncmp((char*)buf, cmp, 8) == 0;
}
-/* TODO(czaplinski): 64b windows? */
/*
* Read from Windows PE/COFF .exe file image.
*/
IMAGE_FILE_HEADER fh;
IMAGE_SECTION_HEADER sh;
IMAGE_OPTIONAL_HEADER oh;
+ PE64_IMAGE_OPTIONAL_HEADER oh64;
uint8 sym[18];
- uint32 *valp, ib;
- int i;
+ uint32 *valp, ib, entry;
+ int i, ohoffset;
USED(hp);
seek(fd, 0x3c, 0);
return 0;
}
+ ohoffset = seek(fd, 0, 1);
if (readn(fd, &oh, sizeof(oh)) != sizeof(oh)) {
werrstr("crippled PE Optional Header");
return 0;
switch(oh.Magic) {
case 0x10b: // PE32
fp->type = FI386;
+ ib = leswal(oh.ImageBase);
+ entry = leswal(oh.AddressOfEntryPoint);
break;
case 0x20b: // PE32+
fp->type = FAMD64;
+ seek(fd, ohoffset, 0);
+ if (readn(fd, &oh64, sizeof(oh64)) != sizeof(oh64)) {
+ werrstr("crippled PE32+ Optional Header");
+ return 0;
+ }
+ ib = leswal(oh64.ImageBase);
+ entry = leswal(oh64.AddressOfEntryPoint);
break;
default:
- werrstr("invalid PE Optional magic number");
+ werrstr("invalid PE Optional Header magic number");
return 0;
}
- ib=leswal(oh.ImageBase);
- seek(fd, start+sizeof(magic)+sizeof(fh)+leswab(fh.SizeOfOptionalHeader), 0);
fp->txtaddr = 0;
fp->dataddr = 0;
for (i=0; i<leswab(fh.NumberOfSections); i++) {
return 0;
}
if (match8(sh.Name, ".text"))
- settext(fp, ib+leswal(oh.AddressOfEntryPoint), ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
+ settext(fp, ib+entry, ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
if (match8(sh.Name, ".data"))
setdata(fp, ib+leswal(sh.VirtualAddress), leswal(sh.SizeOfRawData), leswal(sh.PointerToRawData), leswal(sh.VirtualSize)-leswal(sh.SizeOfRawData));
}