/*++ * * 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); }