/* Get the machine type */ static r_binfmt_arch_e pe_get_machine(r_binfmt_s *bin) { IMAGE_COFF_HEADER *coff; WORD arch; coff = pe_get_coff(bin); arch = pe_get_arch(bin); if(arch != PE32 && arch != PE64) return R_BINFMT_ARCH_UNDEF; switch(coff->Machine) { case PE_MACHINE_I386: return R_BINFMT_ARCH_X86; case PE_MACHINE_IA64: case PE_MACHINE_AMD64: return R_BINFMT_ARCH_X86_64; default: return R_BINFMT_ARCH_UNDEF; } return R_BINFMT_ARCH_UNDEF; }
int main(int argc, char *argv[]) { PE_FILE pe; FILE *fp = NULL; DWORD ep, stub_offset; int callbacks; double entropy; // unsigned int num_sections; if (argc < 2) { usage(); exit(1); } parse_options(argc, argv); // opcoes if ((fp = fopen(argv[argc-1], "rb")) == NULL) EXIT_ERROR("file not found or unreadable"); pe_init(&pe, fp); // inicializa o struct pe if (!is_pe(&pe)) EXIT_ERROR("not a valid PE file"); // File entropy entropy = calculate_entropy_file(&pe); if(entropy < 7.0) snprintf(value, MAX_MSG, "normal (%f)", entropy); else snprintf(value, MAX_MSG, "packed (%f)", entropy); output("file entropy", value); memset(&value, 0, sizeof(value)); if (!pe_get_optional(&pe)) return 1; ep = (pe.optional_ptr->_32 ? pe.optional_ptr->_32->AddressOfEntryPoint : (pe.optional_ptr->_64 ? pe.optional_ptr->_64->AddressOfEntryPoint : 0)); // fake ep if (ep == 0) snprintf(value, MAX_MSG, "null"); else if (pe_check_fake_entrypoint(&pe, &ep)) if (config.verbose) snprintf(value, MAX_MSG, "fake - va: %#x - raw: %#"PRIx64, ep, rva2ofs(&pe, ep)); else snprintf(value, MAX_MSG, "fake"); else if (config.verbose) snprintf(value, MAX_MSG, "normal - va: %#x - raw: %#"PRIx64, ep, rva2ofs(&pe, ep)); else snprintf(value, MAX_MSG, "normal"); output("entrypoint", value); // dos stub memset(&value, 0, sizeof(value)); if (!normal_dos_stub(&pe, &stub_offset)) { if (config.verbose) snprintf(value, MAX_MSG, "suspicious - raw: %#x", stub_offset); else snprintf(value, MAX_MSG, "suspicious"); } else snprintf(value, MAX_MSG, "normal"); output("DOS stub", value); // tls callbacks callbacks = pe_get_tls_callbacks(&pe); if (callbacks == 0) snprintf(value, MAX_MSG, "not found"); else if (callbacks == -1) snprintf(value, MAX_MSG, "found - no functions"); else if (callbacks >0) snprintf(value, MAX_MSG, "found - %d function(s)", callbacks); output("TLS directory", value); memset(&value, 0, sizeof(value)); // section analysis print_strange_sections(&pe); // no imagebase if (!normal_imagebase(&pe)) { if (config.verbose) snprintf(value, MAX_MSG, "suspicious - %#"PRIx64, pe.imagebase); else snprintf(value, MAX_MSG, "suspicious"); } else { if (config.verbose) snprintf(value, MAX_MSG, "normal - %#"PRIx64, pe.imagebase); else snprintf(value, MAX_MSG, "normal"); } output("imagebase", value); // invalid timestamp IMAGE_COFF_HEADER coff; if (!pe_get_coff(&pe, &coff)) EXIT_ERROR("unable to read coff header"); print_timestamp(&coff.TimeDateStamp); pe_deinit(&pe); return 0; }
int main(int argc, char *argv[]) { PE_FILE pe; FILE *fp = NULL; if (argc < 2) { usage(); exit(1); } parse_options(argc, argv); // opcoes if ((fp = fopen(argv[argc-1], "rb")) == NULL) EXIT_ERROR("file not found or unreadable"); pe_init(&pe, fp); // inicializa o struct pe if (!is_pe(&pe)) EXIT_ERROR("not a valid PE file"); // dos header if (config.dos || config.all_headers || config.all) { IMAGE_DOS_HEADER dos; if (pe_get_dos(&pe, &dos)) print_dos_header(&dos); else { EXIT_ERROR("unable to read DOS header"); } } // coff/file header if (config.coff || config.all_headers || config.all) { IMAGE_COFF_HEADER coff; if (pe_get_coff(&pe, &coff)) print_coff_header(&coff); else { EXIT_ERROR("unable to read COFF file header"); } } // optional header if (config.opt || config.all_headers || config.all) { if (pe_get_optional(&pe)) print_optional_header(&pe); else { EXIT_ERROR("unable to read Optional (Image) file header"); } } // directories if (config.dirs || config.all) { if (pe_get_directories(&pe)) print_directories(&pe); else { EXIT_ERROR("unable to read the Directories entry from Optional header"); } } // imports if (config.imports || config.all) { if (pe_get_directories(&pe)) print_imports(&pe); else { EXIT_ERROR("unable to read the Directories entry from Optional header"); } } // exports if (config.exports || config.all) { if (pe_get_directories(&pe)) print_exports(&pe); else { EXIT_ERROR("unable to read directories from optional header"); } } // sections if (config.all_sections || config.all) { if (pe_get_sections(&pe)) print_sections(&pe); else { EXIT_ERROR("unable to read sections"); } } // free pe_deinit(&pe); return 0; }
static int r_binfmt_pe_check(r_binfmt_s *bin) { IMAGE_DOS_HEADER *dos; IMAGE_COFF_HEADER *coff; IMAGE_SECTION_HEADER *shdr; DWORD addr_optional, addr_sections, numberOfRvaAndSizes; WORD arch; size_t size_optional; u32 tmp, i; /********************/ /* Check DOS header */ /********************/ if(bin->mapped_size < sizeof(*dos)) return 0; dos = (IMAGE_DOS_HEADER*)(bin->mapped); /*********************/ /* Check COFF header */ /*********************/ if(bin->mapped_size < (DWORD)dos->e_lfanew) return 0; /* COFF+magic+arch */ if(!r_utils_add32(&tmp, 8+sizeof(*coff), dos->e_lfanew)) return 0; if(bin->mapped_size < tmp) return 0; coff = pe_get_coff(bin); /**************************/ /* Check optionnal header */ /**************************/ arch = pe_get_arch(bin); switch(arch) { case PE32: size_optional = sizeof(IMAGE_OPTIONAL_HEADER_32); break; case PE64: size_optional = sizeof(IMAGE_OPTIONAL_HEADER_64); break; default: return 0; } if(!r_utils_add32(&tmp, 4+sizeof(*coff)+dos->e_lfanew, size_optional)) return 0; if(bin->mapped_size < tmp) return 0; addr_optional = pe_get_addr_coff(bin) + sizeof(*coff); /******************/ /* Check sections */ /******************/ switch(arch) { case PE32: numberOfRvaAndSizes = ((IMAGE_OPTIONAL_HEADER_32*)(bin->mapped + addr_optional))->NumberOfRvaAndSizes; break; case PE64: numberOfRvaAndSizes = ((IMAGE_OPTIONAL_HEADER_32*)(bin->mapped + addr_optional))->NumberOfRvaAndSizes; break; default: return 0; } if(!r_utils_mul32(&addr_sections, numberOfRvaAndSizes, sizeof(IMAGE_DATA_DIRECTORY))) return 0; if(bin->mapped_size < addr_sections) return 0; if(!r_utils_mul32(&tmp, sizeof(IMAGE_SECTION_HEADER), coff->NumberOfSections)) return 0; if(!r_utils_add32(&tmp, tmp, addr_sections)) return 0; if(bin->mapped_size < tmp) return 0; shdr = (IMAGE_SECTION_HEADER*)(bin->mapped + pe_get_addr_sections(bin)); for(i = 0; i < coff->NumberOfSections; i++) { if(!r_utils_add32(&tmp, shdr[i].PointerToRawData, shdr[i].SizeOfRawData)) return 0; if(bin->mapped_size < tmp) return 0; } return 1; }