1/* 2 * Copyright 2013-2014, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Alexander von Gluck IV, <kallisti5@unixzen.com> 7 */ 8 9 10#include "pe.h" 11 12#include <ctype.h> 13#include <dlfcn.h> 14#include <stdio.h> 15#include <stdlib.h> 16#include <string.h> 17 18 19static status_t 20parse_mz_header(MzHeader* mzHeader, off_t* peOffset) 21{ 22 if (memcmp(&mzHeader->magic, MZ_MAGIC, 2) != 0) 23 return B_NOT_AN_EXECUTABLE; 24 25 *peOffset = (off_t)mzHeader->lfaNew; 26 return B_OK; 27} 28 29 30static status_t 31parse_pe_header(PeHeader* peHeader) 32{ 33 if (memcmp(&peHeader->magic, PE_MAGIC, 2) != 0) 34 return B_NOT_AN_EXECUTABLE; 35 36 // Looks like an old BeOS R3 x86 program 37 if (peHeader->characteristics == 0x10E) 38 return B_LEGACY_EXECUTABLE; 39 40 return B_OK; 41} 42 43 44/*! Read and verify the PE header */ 45status_t 46pe_verify_header(void *header, size_t length) 47{ 48 if (length < sizeof(MzHeader)) 49 return B_NOT_AN_EXECUTABLE; 50 51 // Verify MZ header, pull PE header offset 52 off_t peOffset = 0; 53 if (parse_mz_header((MzHeader*)header, &peOffset) != B_OK) 54 return B_NOT_AN_EXECUTABLE; 55 56 // MS-DOS program 57 if (peOffset == 0) 58 return B_UNKNOWN_EXECUTABLE; 59 60 // Something is wrong with the binary 61 if (peOffset + sizeof(PeHeader) > length) 62 return B_UNKNOWN_EXECUTABLE; 63 64 // Find the PE header based on MZ provided offset 65 uint8* pePtr = (uint8*)header; 66 pePtr += peOffset; 67 68 // Win32 program or old BeOS R3 x86 program 69 return parse_pe_header((PeHeader*)pePtr); 70} 71