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 19 static status_t 20 parse_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 30 static status_t 31 parse_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 */ 45 status_t 46 pe_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