mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.2 KiB
138 lines
3.2 KiB
/*++
|
|
*
|
|
* Copyright (c) 1996 FirePower Systems, Inc.
|
|
* Copyright (c) 1995 FirePower Systems, Inc.
|
|
* Copyright (c) 1994 FirmWorks, Mountain View CA USA. All rights reserved.
|
|
* Copyright (c) 1994 FirePower Systems Inc.
|
|
*
|
|
* $RCSfile: vrpehdr.c $
|
|
* $Revision: 1.7 $
|
|
* $Date: 1996/02/17 00:50:30 $
|
|
* $Locker: $
|
|
|
|
Module Name:
|
|
|
|
vrpehdr.c
|
|
|
|
Abstract:
|
|
|
|
These routines read and parse the Microsoft PE header.
|
|
|
|
Author:
|
|
|
|
Mike Tuciarone 9-May-1994
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "veneer.h"
|
|
|
|
|
|
|
|
|
|
#define HEADER_CHR (IMAGE_FILE_EXECUTABLE_IMAGE | \
|
|
IMAGE_FILE_BYTES_REVERSED_LO | \
|
|
IMAGE_FILE_32BIT_MACHINE | \
|
|
IMAGE_FILE_BYTES_REVERSED_HI)
|
|
|
|
/*
|
|
* For some reason NT 3.5 changed the OSLoader header.
|
|
*/
|
|
#define HEADER_CHR_35 (IMAGE_FILE_EXECUTABLE_IMAGE | \
|
|
IMAGE_FILE_32BIT_MACHINE | \
|
|
IMAGE_FILE_LINE_NUMS_STRIPPED)
|
|
|
|
void *
|
|
load_file(ihandle bootih)
|
|
{
|
|
IMAGE_FILE_HEADER FileHdr;
|
|
IMAGE_OPTIONAL_HEADER OptHdr;
|
|
IMAGE_SECTION_HEADER *SecHdr, *hdr;
|
|
int res, size, i;
|
|
PCHAR BaseAddr;
|
|
|
|
if ((res = OFRead(bootih, (char *) &FileHdr, IMAGE_SIZEOF_FILE_HEADER))
|
|
!= IMAGE_SIZEOF_FILE_HEADER) {
|
|
fatal("Couldn't read entire file header: got %d\n", res);
|
|
}
|
|
|
|
/*
|
|
* Sanity check.
|
|
*/
|
|
if (FileHdr.Machine != IMAGE_FILE_MACHINE_POWERPC) {
|
|
fatal("Wrong machine type: %x\n", FileHdr.Machine);
|
|
}
|
|
#ifdef NOT
|
|
/*
|
|
* Don't bother to check the flags. They change every release anyway.
|
|
*/
|
|
if ((FileHdr.Characteristics & HEADER_CHR ) != HEADER_CHR &&
|
|
(FileHdr.Characteristics & HEADER_CHR_35) != HEADER_CHR_35) {
|
|
fatal("Wrong header characteristics: %x\n",
|
|
FileHdr.Characteristics);
|
|
}
|
|
#endif
|
|
|
|
size = FileHdr.SizeOfOptionalHeader;
|
|
if ((res = OFRead(bootih, (char *) &OptHdr, size)) != size) {
|
|
fatal("Couldn't read optional header: expect %x got %x\n",
|
|
size, res);
|
|
}
|
|
|
|
/*
|
|
* More sanity.
|
|
*/
|
|
if (OptHdr.Magic != 0x010b) {
|
|
fatal("Wrong magic number in header: %x\n", OptHdr.Magic);
|
|
}
|
|
|
|
/*
|
|
* Compute image size and claim memory at specified virtual address.
|
|
* We assume the SizeOfImage field is sufficient.
|
|
*/
|
|
BaseAddr = (PCHAR) OptHdr.ImageBase;
|
|
if (CLAIM(BaseAddr, OptHdr.SizeOfImage) == -1) {
|
|
fatal("Couldn't claim %x bytes of VM at %x\n",
|
|
OptHdr.SizeOfImage, BaseAddr);
|
|
}
|
|
bzero(BaseAddr, OptHdr.SizeOfImage);
|
|
|
|
/*
|
|
* Allocate section headers.
|
|
*/
|
|
size = FileHdr.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
|
|
SecHdr = (PIMAGE_SECTION_HEADER) malloc(size);
|
|
if ((res = OFRead(bootih, (char *) SecHdr, size)) != size) {
|
|
fatal("Couldn't read section headers: expect %x got %x\n",
|
|
size, res);
|
|
}
|
|
|
|
/*
|
|
* Loop through section headers, reading in each piece at the
|
|
* specified virtual address.
|
|
*/
|
|
for (i = 0; i < FileHdr.NumberOfSections; ++i) {
|
|
hdr = &SecHdr[i];
|
|
debug(VRDBG_PE, "Processing section %d: %s\n", i, hdr->Name);
|
|
if (hdr->SizeOfRawData == 0) {
|
|
continue;
|
|
}
|
|
if (OFSeek(bootih, 0, hdr->PointerToRawData) == -1) {
|
|
fatal("seek to offset %x failed\n",
|
|
hdr->PointerToRawData);
|
|
}
|
|
res = OFRead(bootih,
|
|
(PCHAR) hdr->VirtualAddress + (ULONG) BaseAddr,
|
|
hdr->SizeOfRawData);
|
|
if ((ULONG)res != hdr->SizeOfRawData) {
|
|
fatal("Couldn't read data: exp %x got %x\n",
|
|
hdr->SizeOfRawData, res);
|
|
}
|
|
}
|
|
free((char *)SecHdr);
|
|
|
|
return (void *)(BaseAddr + OptHdr.AddressOfEntryPoint);
|
|
}
|