static bool idaapi show_vtbl_xrefs_window_cb(void *ud) { get_xrefs_to_vtbl(); if (!xref_list.empty()) { HWND hwnd = NULL; TForm *form = create_tform(vtbl_t_list[current_line_pos].vtbl_name.c_str(), &hwnd); object_explorer_info_t *si = new object_explorer_info_t(form); qvector <qstring>::iterator xref_iter; for (xref_iter = xref_list.begin(); xref_iter != xref_list.end(); xref_iter++) si->sv.push_back(simpleline_t(*xref_iter)); simpleline_place_t s1; simpleline_place_t s2(si->sv.size() - 1); si->cv = create_custom_viewer("", NULL, &s1, &s2, &s1, 0, &si->sv); si->codeview = create_code_viewer(form, si->cv, CDVF_STATUSBAR); set_custom_viewer_handlers(si->cv, NULL, NULL, ct_vtbl_xrefs_window_click, NULL, NULL, si); open_tform(form, FORM_ONTOP | FORM_RESTORE); return true; } warning("ObjectExplorer not found any xrefs here ..."); return false; }
void object_explorer_form_init() { if (!vtbl_list.empty() && !vtbl_t_list.empty()) { HWND hwnd = NULL; TForm *form = create_tform("Object Explorer", &hwnd); if (hwnd == NULL) { warning("Object Explorer window already open. Switching to it."); form = find_tform("Object Explorer"); if (form != NULL) switchto_tform(form, true); return; } object_explorer_info_t *si = new object_explorer_info_t(form); qvector <qstring>::iterator vtbl_iter; for (vtbl_iter = vtbl_list.begin(); vtbl_iter != vtbl_list.end(); vtbl_iter++) si->sv.push_back(simpleline_t(*vtbl_iter)); simpleline_place_t s1; simpleline_place_t s2(si->sv.size() - 1); si->cv = create_custom_viewer("", NULL, &s1, &s2, &s1, 0, &si->sv); si->codeview = create_code_viewer(form, si->cv, CDVF_STATUSBAR); set_custom_viewer_handlers(si->cv, ct_object_explorer_keyboard, ct_object_explorer_popup, ct_object_explorer_click, NULL, NULL, si); hook_to_notification_point(HT_UI, ui_object_explorer_callback, si); open_tform(form, FORM_TAB | FORM_MENU | FORM_RESTORE); } else warning("ObjectExplorer not found any virtual tables here ..."); }
static bool idaapi show_rtti_window_cb(void *ud) { if (!rtti_list.empty() && !rtti_addr.empty()) { HWND hwnd = NULL; TForm *form = create_tform("RTTI Objects List", &hwnd); object_explorer_info_t *si = new object_explorer_info_t(form); qvector <qstring>::iterator rtti_iter; for (rtti_iter = rtti_list.begin(); rtti_iter != rtti_list.end(); rtti_iter++) si->sv.push_back(simpleline_t(*rtti_iter)); simpleline_place_t s1; simpleline_place_t s2(si->sv.size() - 1); si->cv = create_custom_viewer("", NULL, &s1, &s2, &s1, 0, &si->sv); si->codeview = create_code_viewer(form, si->cv, CDVF_STATUSBAR); set_custom_viewer_handlers(si->cv, NULL, NULL, ct_rtti_window_click, NULL, NULL, si); open_tform(form, FORM_ONTOP | FORM_RESTORE); return true; } warning("ObjectExplorer not found any RTTI objects ..."); return false; }
void disp_request_t::flush() { qmutex_lock(mtx); for (qvector<json_object*>::iterator i = objects.begin(); i != objects.end(); i++) { json_object_put(*i); } objects.clear(); qmutex_unlock(mtx); }
tid_t idaapi merge_types(qvector<qstring> types_to_merge, qstring type_name) { tid_t struct_type_id = BADADDR; std::set<ea_t> offsets; if (types_to_merge.size() != 0) { struct_type_id = add_struc(BADADDR, type_name.c_str()); if (struct_type_id != 0 || struct_type_id != BADADDR) { struc_t * struc = get_struc(struct_type_id); if (struc != NULL) { qvector<qstring>::iterator types_iter; for (types_iter = types_to_merge.begin(); types_iter != types_to_merge.end(); types_iter++) { tid_t type_id = get_struc_id((*types_iter).c_str()); if (type_id != BADADDR) { struc_t * struc_type = get_struc(type_id); if (struc_type != NULL) { // enumerate members for (ea_t offset = get_struc_first_offset(struc_type); offset != BADADDR; offset = get_struc_next_offset(struc_type, offset)) { member_t * member_info = get_member(struc_type, offset); if (member_info != NULL) { if (offsets.count(member_info->soff) == 0) { qstring member_name = get_member_name2(member_info->id); asize_t member_size = get_member_size(member_info); if (member_name.find("vftbl_", 0) != -1) { tinfo_t tif; if (get_member_tinfo2(member_info, &tif)) { add_struc_member(struc, member_name.c_str(), member_info->soff, dwrdflag(), NULL, member_size); member_t * membr = get_member(struc, member_info->soff); if (membr != NULL) { set_member_tinfo2(struc, membr, 0, tif, SET_MEMTI_COMPATIBLE); } } } else { add_struc_member(struc, member_name.c_str(), member_info->soff, member_info->flag, NULL, member_size); } offsets.insert(member_info->soff); } } } } } } } } } return struct_type_id; }
tid_t idaapi merge_types(const qvector<qstring>& types_to_merge, const qstring& type_name) { tid_t struct_type_id = BADADDR; if (types_to_merge.empty()) return struct_type_id; std::set<ea_t> offsets; struct_type_id = add_struc(BADADDR, type_name.c_str()); if (struct_type_id == BADADDR) return struct_type_id; struc_t * struc = get_struc(struct_type_id); if (!struc) return struct_type_id; for (auto types_iter = types_to_merge.begin(), end = types_to_merge.end(); types_iter != end; ++types_iter) { struc_t * struc_type = get_struc(get_struc_id(types_iter->c_str())); if (!struc_type) continue; // enumerate members for ( ea_t offset = get_struc_first_offset(struc_type) ; offset != BADADDR ; offset = get_struc_next_offset(struc_type, offset)) { member_t * member_info = get_member(struc_type, offset); if (!member_info) continue; if (offsets.count(member_info->soff) == 0) { qstring member_name = get_member_name(member_info->id); asize_t member_size = get_member_size(member_info); if (member_name.find("vftbl_", 0) != -1) { tinfo_t tif; if (get_member_tinfo(&tif, member_info)) { add_struc_member(struc, member_name.c_str(), member_info->soff, dword_flag(), NULL, member_size); if (member_t * membr = get_member(struc, member_info->soff)) { set_member_tinfo(struc, membr, 0, tif, SET_MEMTI_COMPATIBLE); } } } else { add_struc_member(struc, member_name.c_str(), member_info->soff, member_info->flag, NULL, member_size); } offsets.insert(member_info->soff); } } } return struct_type_id; }
bool get_vbtbl_by_ea(ea_t vtbl_addr, VTBL_info_t &vtbl) { bool result = false; search_objects(false); qvector <VTBL_info_t>::iterator vtbl_iter; for (vtbl_iter = vtbl_t_list.begin(); vtbl_iter != vtbl_t_list.end(); vtbl_iter++) { if ((*vtbl_iter).ea_begin == vtbl_addr) { vtbl = *vtbl_iter; result = true; break; } } return result; }
//this is the callback that gets called by execute_sync, in theory new datagrams //can arrive and be processed during the loop since queue synchronization takes //place within the StringList int idaapi disp_request_t::execute(void) { while (objects.size() > 0) { qmutex_lock(mtx); qvector<json_object*>::iterator i = objects.begin(); json_object *obj = *i; objects.erase(i); qmutex_unlock(mtx); bool res = (*_disp)(obj); if (!res) { //not sure we really care what is returned here // msg(PLUGIN_NAME": connection to server severed at dispatch.\n"); // comm->cleanup(true); //probably not the right thing to do?? // break; } else { //msg(PLUGIN_NAME": dispatch routine called successfully.\n"); } } return 0; }
bool idaapi extract_all_types(void *ud) { logmsg(DEBUG, "extract_types()\n"); // 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 == -1) { logmsg(ERROR, "Failed to open file for dumping types.txt\r\n"); return false; } 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; if (get_func_name(&name, addr) <= 0) continue; qstring info_msg1; info_msg1.cat_sprnt("\t%s\n", name.c_str()); logmsg(DEBUG, info_msg1.c_str()); func_t *pfn = get_func(addr); if (!pfn) continue; 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"); 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; }