static void get_xrefs_to_vtbl() { ea_t cur_vt_ea = vtbl_t_list[current_line_pos].ea_begin; for (ea_t addr = get_first_dref_to(cur_vt_ea); addr != BADADDR; addr = get_next_dref_to(cur_vt_ea, addr)) { qstring name; get_func_name2(&name, addr); xref_addr.push_back(addr); qstring tmp; tmp.cat_sprnt(" 0x%x: %s", addr, name); xref_list.push_back(tmp); } }
inline bool func_name_has_prefix(qstring &prefix, ea_t startEA) { qstring func_name; if (prefix.length() <= 0) return false; if (get_func_name2(&func_name, startEA) == 0) return false; if (func_name.length() <= 0) return false; if (func_name.find(prefix.c_str(), 0) != 0) return false; return true; }
bool idaapi dump_funcs_ctree(void *ud, qstring &crypto_prefix) { logmsg(DEBUG, "dump_funcs_ctree entered\n"); std::map<ea_t, ctree_dump_line> data_to_dump; // enumerate through all the functions in the idb file bool heuristic_flag; size_t count = 0, heur_count = 0, crypto_count = 0; size_t total_func_qty = get_func_qty(); for (size_t i = 0 ; i < total_func_qty ; i ++) { heuristic_flag = 0; func_t *function = getn_func(i); if (function != NULL) { bool crypto_flag = func_name_has_prefix(crypto_prefix, function->startEA); // skip libs that are not marked as crypto if ( ((function->flags & FUNC_LIB) != 0) && !crypto_flag ) continue; // From this point on, we have a function outside of lib or a crypto one // Ignore functions less than MIN_FUNC_SIZE_DUMP bytes if ( ((function->endEA - function->startEA) < MIN_FUNC_SIZE_DUMP) && !crypto_flag ) continue; // If function is bigger than MIN_HEURISTIC_FUNC_SIZE_DUMP, mark as being triggered by the heuristic if (function->endEA - function->startEA > MIN_HEURISTIC_FUNC_SIZE_DUMP) heuristic_flag = 1; // dump up to N_CRYPTO_FUNCS_TO_DUMP crypto functions // dump up to N_HEUR_FUNCS_TO_DUMP heuristic functions // at least N_FUNCS_TO_DUMP functions will be dumped if ((count < N_FUNCS_TO_DUMP) || (crypto_flag && (crypto_count < N_CRYPTO_FUNCS_TO_DUMP)) || (heuristic_flag && (heur_count < N_HEUR_FUNCS_TO_DUMP))) { hexrays_failure_t hf; cfuncptr_t cfunc = decompile(function, &hf); logmsg(DEBUG, "\nafter decompile()\n"); if (cfunc != NULL) { ctree_dumper_t ctree_dumper; ctree_dumper.apply_to(&cfunc->body, NULL); ctree_dump_line func_dump; func_dump.ctree_dump = ctree_dumper.ctree_dump; func_dump.ctree_for_hash = ctree_dumper.ctree_for_hash; func_dump.func_depth = -1; func_dump.func_start = function->startEA; func_dump.func_end = function->endEA; qstring func_name; if (get_func_name2(&func_name, function->startEA) != 0) { if (func_name.length() > 0) { func_dump.func_name = func_name; } } func_parent_iterator_t fpi(function); for (ea_t addr = get_first_cref_to(function->startEA); addr != BADADDR; addr = get_next_cref_to(function->startEA, addr)) { func_t *referer = get_func(addr); if (referer != NULL) { func_dump.referres.push_back(referer->startEA); } } func_dump.heuristic_flag = heuristic_flag; // 0 or 1 depending on code above if (heuristic_flag) heur_count++; if (crypto_flag) crypto_count++; count++; data_to_dump[function->startEA] = func_dump; } } } } dump_ctrees_in_file(data_to_dump, crypto_prefix); return true; }
bool idaapi extract_all_types(void *ud) { logmsg(DEBUG, "extract_types()"); // find vtables in the binary search_objects(false); qvector <VTBL_info_t>::iterator vtbl_iter; std::map<ea_t, VTBL_info_t> vtbl_map; for (vtbl_iter = vtbl_t_list.begin(); vtbl_iter != vtbl_t_list.end(); vtbl_iter++) vtbl_map[(*vtbl_iter).ea_begin] = (*vtbl_iter); int file_id = create_open_file("types.txt"); if (file_id != BADADDR) { int struct_no = 0; for (vtbl_iter = vtbl_t_list.begin(); vtbl_iter != vtbl_t_list.end(); vtbl_iter++) { qstring info_msg; info_msg.cat_sprnt("Processing vtable %s\n", (*vtbl_iter).vtbl_name.c_str()); logmsg(DEBUG, info_msg.c_str()); qstring type_name; type_name.sprnt("struc_2_%d", struct_no); ea_t cur_vt_ea = (*vtbl_iter).ea_begin; int struct_subno = 0; qvector <qstring> types_to_merge; for (ea_t addr = get_first_dref_to(cur_vt_ea); addr != BADADDR; addr = get_next_dref_to(cur_vt_ea, addr)) { qstring name; get_func_name2(&name, addr); qstring info_msg1; info_msg1.cat_sprnt("\t%s", name.c_str()); logmsg(DEBUG, info_msg1.c_str()); func_t *pfn = get_func(addr); if (pfn != NULL) { hexrays_failure_t hf; cfuncptr_t cfunc = decompile(pfn, &hf); if (cfunc != NULL) { qstring var_name; info_msg.clear(); if (find_var(cfunc, (*vtbl_iter).vtbl_name, var_name)) { info_msg.cat_sprnt(" : %s\n", var_name.c_str()); logmsg(DEBUG, info_msg.c_str()); qstring sub_type_name = type_name; sub_type_name.cat_sprnt("_%d", struct_subno); struct_subno++; if (reconstruct_type(cfunc, var_name, sub_type_name)) { if (check_subtype((*vtbl_iter), sub_type_name)) { types_to_merge.push_back(sub_type_name); } } } else { info_msg.cat_sprnt(" : none\n", var_name.c_str()); logmsg(DEBUG, info_msg.c_str()); } } } } struct_no++; merge_types(types_to_merge, type_name); dump_type_info(file_id, (*vtbl_iter), type_name, vtbl_map); } qclose(file_id); } return true; }