// check for abnormal dos stub (common in packed files) static bool normal_dos_stub(PE_FILE *pe, DWORD *stub_offset) { BYTE dos_stub[] = "\x0e" // push cs "\x1f" // pop ds "\xba\x0e\x00" // mov dx, 0x0e "\xb4\x09" // mov ah, 0x09 "\xcd\x21" // int 0x21 "\xb8\x01\x4c" // mov ax, 0x4c01 "\xcd\x21" // int 0x21 "This program cannot be run in DOS mode.\r\r\n$"; BYTE data[sizeof(dos_stub)-1]; // -1 to ignore ending null IMAGE_DOS_HEADER dos; if (!pe_get_dos(pe, &dos)) EXIT_ERROR("unable to retrieve PE DOS header"); *stub_offset = dos.e_cparhdr << 4; // dos stub starts at e_cparhdr shifted by 4 if (fseek(pe->handle, *stub_offset, SEEK_SET)) EXIT_ERROR("unable to seek in file"); if (!fread(&data, sizeof(data), 1, pe->handle)) EXIT_ERROR("unable to read DOS stub"); if (memcmp(dos_stub, data, sizeof(data))==0) return true; return false; }
/* Get the address of the coff header */ static WORD pe_get_addr_coff(r_binfmt_s *bin) { IMAGE_DOS_HEADER *dos; dos = pe_get_dos(bin); return dos->e_lfanew + 4; }
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; }