/* find stack cookies, a.k.a canary, buffer security check option in MVS 2010 */ static bool stack_cookies(pe_ctx_t *ctx) { static const unsigned char mvs2010[] = { 0x55, 0x8b, 0xec, 0x83, 0x33, 0xc5, 0x33, 0xcd, 0xe8, 0xc3 }; if (ctx == NULL) return false; size_t found = 0; const uint8_t *file_bytes = LIBPE_PTR_ADD(ctx->map_addr, 0); const uint64_t filesize = pe_filesize(ctx); for (uint64_t ofs=0; ofs < filesize; ofs++) { for (size_t i=0; i < sizeof(mvs2010); i++) { if (file_bytes[ofs] == mvs2010[i] && found == i) found++; } } return found == sizeof(mvs2010); }
int main(int argc, char *argv[]) { if (argc < 2) { usage(); exit(EXIT_FAILURE); } options_t *options = parse_options(argc, argv); // opcoes const char *path = argv[argc-1]; pe_ctx_t ctx; pe_err_e err = pe_load_file(&ctx, path); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } err = pe_parse(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } if (!pe_is_pe(&ctx)) EXIT_ERROR("not a valid PE file"); const uint64_t pe_size = pe_filesize(&ctx); const uint8_t *pe_raw_data = ctx.map_addr; uint64_t pe_raw_offset = 0; unsigned char buff[LINE_BUFFER]; memset(buff, 0, LINE_BUFFER); uint64_t buff_index = 0; uint32_t ascii = 0; uint32_t utf = 0; while (pe_raw_offset < pe_size) { const uint8_t byte = pe_raw_data[pe_raw_offset]; if (isprint(byte)) { ascii++; buff[buff_index++] = byte; pe_raw_offset++; continue; } else if (ascii == 1 && byte == '\0') { utf++; buff[buff_index++] = byte; ascii = 0; pe_raw_offset++; continue; } else { if (ascii >= (options->strsize ? options->strsize : 4)) { printb(&ctx, options, buff, 0, ascii, pe_raw_offset - ascii); } else if (utf >= (options->strsize ? options->strsize : 4)) { printb(&ctx, options, buff, 0, utf*2, pe_raw_offset - utf*2); } ascii = utf = buff_index = 0; memset(buff, 0, LINE_BUFFER); } pe_raw_offset++; } // libera a memoria free_options(options); // free err = pe_unload(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { pev_config_t config; PEV_INITIALIZE(&config); if (argc < 2) { usage(); return EXIT_FAILURE; } output_set_cmdline(argc, argv); options_t *options = parse_options(argc, argv); pe_ctx_t ctx; pe_err_e err = pe_load_file(&ctx, argv[argc-1]); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } err = pe_parse(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } if (!pe_is_pe(&ctx)) EXIT_ERROR("not a valid PE file"); const IMAGE_SECTION_HEADER *section_ptr = NULL; const unsigned char *data = NULL; uint64_t data_size = 0; unsigned c = pe_sections_count(&ctx); IMAGE_SECTION_HEADER ** const sections = pe_sections(&ctx); data = ctx.map_addr; data_size = pe_filesize(&ctx); output_open_document(); if (options->headers.all || options->headers.dos || options->headers.coff || options->headers.optional || options->sections.name || options->sections.index) { options->all = false; options->content = false; } if (options->all) { options->content = true; options->headers.all = true; } if (options->content) { output_open_scope("file", OUTPUT_SCOPE_TYPE_OBJECT); output("filepath", ctx.path); print_basic_hash(data, data_size); char *imphash = NULL; // imphash = pe_imphash(&ctx, LIBPE_IMPHASH_FLAVOR_MANDIANT); // output("imphash (Mandiant)", imphash); // free(imphash); imphash = pe_imphash(&ctx, LIBPE_IMPHASH_FLAVOR_PEFILE); output("imphash", imphash); free(imphash); output_close_scope(); // file if (!options->all) // whole file content only goto BYE; } if (options->headers.all) { options->headers.dos = true; options->headers.coff = true; options->headers.optional = true; } if (options->headers.all || options->headers.dos || options->headers.coff || options->headers.optional) output_open_scope("headers", OUTPUT_SCOPE_TYPE_ARRAY); if (options->headers.all || options->headers.dos) { const IMAGE_DOS_HEADER *dos_hdr = pe_dos(&ctx); data = (const unsigned char *)dos_hdr; data_size = sizeof(IMAGE_DOS_HEADER); output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_DOS_HEADER"); print_basic_hash(data, data_size); output_close_scope(); // header } if (options->headers.all || options->headers.coff) { const IMAGE_COFF_HEADER *coff_hdr = pe_coff(&ctx); data = (const unsigned char *)coff_hdr; data_size = sizeof(IMAGE_COFF_HEADER); output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_COFF_HEADER"); print_basic_hash(data, data_size); output_close_scope(); // header } if (options->headers.all || options->headers.optional) { const IMAGE_OPTIONAL_HEADER *opt_hdr = pe_optional(&ctx); switch (opt_hdr->type) { case MAGIC_ROM: // Oh boy! We do not support ROM. Abort! fprintf(stderr, "ROM image is not supported\n"); break; case MAGIC_PE32: if (!pe_can_read(&ctx, opt_hdr->_32, sizeof(IMAGE_OPTIONAL_HEADER_32))) { // TODO: Should we report something? break; } data = (const unsigned char *)opt_hdr->_32; data_size = sizeof(IMAGE_OPTIONAL_HEADER_32); break; case MAGIC_PE64: if (!pe_can_read(&ctx, opt_hdr->_64, sizeof(IMAGE_OPTIONAL_HEADER_64))) { // TODO: Should we report something? break; } data = (const unsigned char *)opt_hdr->_64; data_size = sizeof(IMAGE_OPTIONAL_HEADER_64); break; } output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_OPTIONAL_HEADER"); print_basic_hash(data, data_size); output_close_scope(); // header } if (options->headers.all || options->headers.dos || options->headers.coff || options->headers.optional) output_close_scope(); // headers if (options->all || options->sections.name || options->sections.index) output_open_scope("sections", OUTPUT_SCOPE_TYPE_ARRAY); if (options->all) { for (unsigned int i=0; i<c; i++) { data_size = sections[i]->SizeOfRawData; data = LIBPE_PTR_ADD(ctx.map_addr, sections[i]->PointerToRawData); if (!pe_can_read(&ctx, data, data_size)) { EXIT_ERROR("Unable to read section data"); } output_open_scope("section", OUTPUT_SCOPE_TYPE_OBJECT); output("section_name", (char *)sections[i]->Name); if (data_size) { print_basic_hash(data, data_size); } output_close_scope(); // section } //output_close_scope(); // sections } else if (options->sections.name != NULL) { const IMAGE_SECTION_HEADER *section = pe_section_by_name(&ctx, options->sections.name); if (section == NULL) { EXIT_ERROR("The requested section could not be found on this binary"); } section_ptr = section; } else if (options->sections.index > 0) { const uint16_t num_sections = pe_sections_count(&ctx); if (num_sections == 0 || options->sections.index > num_sections) { EXIT_ERROR("The requested section could not be found on this binary"); } IMAGE_SECTION_HEADER ** const sections = pe_sections(&ctx); const IMAGE_SECTION_HEADER *section = sections[options->sections.index - 1]; section_ptr = section; } if (section_ptr != NULL) { if (section_ptr->SizeOfRawData > 0) { const uint8_t *section_data_ptr = LIBPE_PTR_ADD(ctx.map_addr, section_ptr->PointerToRawData); // printf("map_addr = %p\n", ctx.map_addr); // printf("section_data_ptr = %p\n", section_data_ptr); // printf("SizeOfRawData = %u\n", section_ptr->SizeOfRawData); if (!pe_can_read(&ctx, section_data_ptr, section_ptr->SizeOfRawData)) { EXIT_ERROR("The requested section has an invalid size"); } data = (const unsigned char *)section_data_ptr; data_size = section_ptr->SizeOfRawData; } else { data = (const unsigned char *)""; data_size = 0; } } if (!options->all && data != NULL) { output_open_scope("section", OUTPUT_SCOPE_TYPE_OBJECT); output("section_name", options->sections.name); print_basic_hash(data, data_size); output_close_scope(); } if (options->all || options->sections.name || options->sections.index) output_close_scope(); BYE: output_close_document(); // free free_options(options); err = pe_unload(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } PEV_FINALIZE(&config); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { pev_config_t config; PEV_INITIALIZE(&config); if (argc < 2) { usage(); return EXIT_FAILURE; } output_set_cmdline(argc, argv); OpenSSL_add_all_digests(); options_t *options = parse_options(argc, argv); pe_ctx_t ctx; pe_err_e err = pe_load_file(&ctx, argv[argc-1]); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } err = pe_parse(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } if (!pe_is_pe(&ctx)) EXIT_ERROR("not a valid PE file"); const IMAGE_SECTION_HEADER *section_ptr = NULL; const unsigned char *data = NULL; uint64_t data_size = 0; unsigned c = pe_sections_count(&ctx); IMAGE_SECTION_HEADER ** const sections = pe_sections(&ctx); char hash_value[EVP_MAX_MD_SIZE * 2 + 1]; data = ctx.map_addr; data_size = pe_filesize(&ctx); output_open_document(); if (options->all) { output_open_scope("file", OUTPUT_SCOPE_TYPE_OBJECT); output("filepath", ctx.path); print_basic_hash(data, data_size); output_close_scope(); // file } output_open_scope("headers", OUTPUT_SCOPE_TYPE_ARRAY); if (options->all || options->headers.all || options->headers.dos) { const IMAGE_DOS_HEADER *dos_hdr = pe_dos(&ctx); data = (const unsigned char *)dos_hdr; data_size = sizeof(IMAGE_DOS_HEADER); output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_DOS_HEADER"); PRINT_HASH_OR_HASHES; output_close_scope(); // header } if (options->all || options->headers.all || options->headers.coff) { const IMAGE_COFF_HEADER *coff_hdr = pe_coff(&ctx); data = (const unsigned char *)coff_hdr; data_size = sizeof(IMAGE_COFF_HEADER); output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_COFF_HEADER"); PRINT_HASH_OR_HASHES; output_close_scope(); // header } if (options->all || options->headers.all || options->headers.optional) { const IMAGE_OPTIONAL_HEADER *opt_hdr = pe_optional(&ctx); switch (opt_hdr->type) { case MAGIC_ROM: // Oh boy! We do not support ROM. Abort! fprintf(stderr, "ROM image is not supported\n"); break; case MAGIC_PE32: if (!pe_can_read(&ctx, opt_hdr->_32, sizeof(IMAGE_OPTIONAL_HEADER_32))) { // TODO: Should we report something? break; } data = (const unsigned char *)opt_hdr->_32; data_size = sizeof(IMAGE_OPTIONAL_HEADER_32); break; case MAGIC_PE64: if (!pe_can_read(&ctx, opt_hdr->_64, sizeof(IMAGE_OPTIONAL_HEADER_64))) { // TODO: Should we report something? break; } data = (const unsigned char *)opt_hdr->_64; data_size = sizeof(IMAGE_OPTIONAL_HEADER_64); break; } output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_OPTIONAL_HEADER"); PRINT_HASH_OR_HASHES; output_close_scope(); // header } output_close_scope(); // headers if (options->all) { output_open_scope("sections", OUTPUT_SCOPE_TYPE_ARRAY); for (unsigned int i=0; i<c; i++) { data_size = sections[i]->SizeOfRawData; data = LIBPE_PTR_ADD(ctx.map_addr, sections[i]->PointerToRawData); output_open_scope("section", OUTPUT_SCOPE_TYPE_OBJECT); output("section_name", (char *)sections[i]->Name); if (data_size) { PRINT_HASH_OR_HASHES; } output_close_scope(); // section } output_close_scope(); // sections } else if (options->sections.name != NULL) { const IMAGE_SECTION_HEADER *section = pe_section_by_name(&ctx, options->sections.name); if (section == NULL) { EXIT_ERROR("The requested section could not be found on this binary"); } section_ptr = section; } else if (options->sections.index > 0) { const uint16_t num_sections = pe_sections_count(&ctx); if (num_sections == 0 || options->sections.index > num_sections) { EXIT_ERROR("The requested section could not be found on this binary"); } IMAGE_SECTION_HEADER ** const sections = pe_sections(&ctx); const IMAGE_SECTION_HEADER *section = sections[options->sections.index - 1]; section_ptr = section; } if (section_ptr != NULL) { if (section_ptr->SizeOfRawData > 0) { const uint8_t *section_data_ptr = LIBPE_PTR_ADD(ctx.map_addr, section_ptr->PointerToRawData); // printf("map_addr = %p\n", ctx.map_addr); // printf("section_data_ptr = %p\n", section_data_ptr); // printf("SizeOfRawData = %u\n", section_ptr->SizeOfRawData); if (!pe_can_read(&ctx, section_data_ptr, section_ptr->SizeOfRawData)) { EXIT_ERROR("The requested section has an invalid size"); } data = (const unsigned char *)section_data_ptr; data_size = section_ptr->SizeOfRawData; } else { data = (const unsigned char *)""; data_size = 0; } } if (!options->all && data != NULL) { char hash_value[EVP_MAX_MD_SIZE * 2 + 1]; if (options->algorithms.all && options->all) { print_basic_hash(data, data_size); } else if (options->algorithms.alg_name != NULL) { calc_hash(options->algorithms.alg_name, data, data_size, hash_value); output(options->algorithms.alg_name, hash_value); } else { print_basic_hash(data, data_size); } } output_close_document(); // free free_options(options); err = pe_unload(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } EVP_cleanup(); // Clean OpenSSL_add_all_digests. PEV_FINALIZE(&config); return EXIT_SUCCESS; }