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 ..."); }
void process_rtti() { ea_t start = getnseg(0)->startEA; while (TRUE) { ea_t rt = find_RTTI(start, inf.maxEA); start = rt + 4; if (rt == BADADDR) break; char* name = get_demangle_name(rt); ea_t rtd = rt - 8; rtti_addr.push_back(rtd); qstring tmp; #ifndef __EA64__ tmp.cat_sprnt(" 0x%x: %s", rtd, name); #else tmp.cat_sprnt(_T(" 0x%I64X: %s"), rtd, name); #endif rtti_list.push_back(tmp); } }
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; }
static BOOL process_vtbl(ea_t &ea_sect) { VTBL_info_t vftable_info_t; if(get_vtbl_info(ea_sect, vftable_info_t)) { ea_sect = vftable_info_t.ea_end; ea_t ea_assumed; verify_32_t((vftable_info_t.ea_begin - 4), ea_assumed); if(vftable_info_t.methods > 1) { if(has_user_name(getFlags(vftable_info_t.ea_begin))) { vftable_info_t.vtbl_name = get_short_name(vftable_info_t.ea_begin); qstring vtbl_info_str; vtbl_info_str.cat_sprnt(" 0x%x - 0x%x: %s methods count: %d", vftable_info_t.ea_begin, vftable_info_t.ea_end, vftable_info_t.vtbl_name.c_str(), vftable_info_t.methods); vtbl_list.push_back(vtbl_info_str); vtbl_t_list.push_back(vftable_info_t); return(TRUE); } } return(FALSE); } ea_sect += sizeof(UINT); 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; }
//queue up a received datagram for eventual handlng via IDA's execute_sync mechanism //call no sdk functions other than execute_sync void disp_request_t::queueObject(json_object *obj) { bool call_exec = false; qmutex_lock(mtx); objects.push_back(obj); call_exec = objects.size() == 1; qmutex_unlock(mtx); if (call_exec) { //only invoke execute_sync if the buffer just added was at the head of the queue //in theory this allows multiple datagrams to get queued for handling //in a single execute_sync callback execute_sync(*this, MFF_WRITE); } }
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); } }
ea_t map_port(ea_t from) { for ( int i=0; i < map.size(); i++ ) if ( map[i].from == from ) return map[i].to; return from; }
int does_exist(TFuncMallocWrapper new_func_malloc) { for(int i = 0; i< funcMalloc_wrappers.size(); i++){ if(funcMalloc_wrappers[i].address == new_func_malloc.address)return 1; } return 0; }
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; }
static BOOL process_vtbl(ea_t &ea_sect) { VTBL_info_t vftable_info_t; if (get_vtbl_info(ea_sect, vftable_info_t)) { ea_sect = vftable_info_t.ea_end; ea_t ea_assumed; #ifndef __EA64__ verify_32_t((vftable_info_t.ea_begin - 4), ea_assumed); #else verify_64_t((vftable_info_t.ea_begin - sizeof(UINT64)), ea_assumed); #endif if (vftable_info_t.methods > 0) { /*if(has_user_name(getFlags(vftable_info_t.ea_begin))) { */ vftable_info_t.vtbl_name = f_get_short_name(vftable_info_t.ea_begin); qstring vtbl_info_str; #ifndef __EA64__ vtbl_info_str.cat_sprnt(" 0x%x - 0x%x: %s methods count: ", vftable_info_t.ea_begin, vftable_info_t.ea_end, vftable_info_t.vtbl_name); vtbl_info_str.cat_sprnt(" %u", vftable_info_t.methods); #else vtbl_info_str.cat_sprnt(_T(" 0x%I64X - 0x%I64X: %s methods count: "), vftable_info_t.ea_begin, vftable_info_t.ea_end, vftable_info_t.vtbl_name); vtbl_info_str.cat_sprnt(_T(" %d"), (vftable_info_t.methods)); #endif vtbl_list.push_back(vtbl_info_str); vtbl_t_list.push_back(vftable_info_t); return(TRUE); //} } return(FALSE); } #ifndef __EA64__ ea_sect += sizeof(UINT); #else ea_sect += sizeof(UINT64); #endif return(FALSE); }
static void add_mapping(ea_t from, ea_t to) { if ( from != to ) { deb(IDA_DEBUG_IDP, "add_mapping %a -> %a\n", from, to); portmap_t &p = map.push_back(); p.from = from; p.to = to; } }
//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; }
int writeQIntVec(qvector & qv, string fname, int buffsize) { int j, nrows, fmt, ncols, nnz; uint64 v; ostream *ofstr = open_out_buf(fname, buffsize); ncols = qv.size(); nrows = 4; nnz = nrows * ncols; fmt = 110; ofstr->write((const char *)&fmt, 4); ofstr->write((const char *)&nrows, 4); ofstr->write((const char *)&ncols, 4); ofstr->write((const char *)&nnz, 4); for (j = 0; j < qv.size(); j++) { v = qv[j].bottom; ofstr->write((const char *)&v, 8); v = qv[j].top; ofstr->write((const char *)&v, 8); } closeos(ofstr); return 0; }
static void get_xrefs_to_vtbl() { // the list is repeat while select another vtable xref_list.clear(); xref_addr.clear(); 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; f_get_func_name2(&name, addr); xref_addr.push_back(addr); qstring tmp; #ifndef __EA64__ tmp.cat_sprnt(" 0x%x: %s", addr, name); #else tmp.cat_sprnt(_T(" 0x%I64X: %s"), addr, name); #endif xref_list.push_back(tmp); } }
//--------------------------------------------------------------------------- bool x86seh_ctx_t::get_sehlist() { uint64 fs_sel; ea_t fs_base; uint32 excr_ea; handlers.clear(); if ( !get_reg_val("fs", &fs_sel) || internal_get_sreg_base(tid, int(fs_sel), &fs_base) <= 0 || read_dbg_memory(fs_base, &excr_ea, sizeof(excr_ea)) != sizeof(excr_ea) ) { warning("Failed to build the SEH list for thread %08X", tid); return false; } struct EXC_REG_RECORD { uint32 p_prev; uint32 p_handler; }; EXC_REG_RECORD rec; std::set<uint32> seen; while ( excr_ea != 0xffffffff ) { if ( read_dbg_memory(excr_ea, &rec, sizeof(rec)) != sizeof(rec) ) break; if ( !seen.insert(excr_ea).second ) { msg("Circular SEH record has been detected\n"); break; } handlers.push_back(rec.p_handler); excr_ea = rec.p_prev; } return true; }
int writeQIntVecx(qvector & im, string fname, int buffsize) { int fmt, nrows, ncols, nnz; ostream *ofstr = open_out_buf(fname.c_str(), buffsize); fmt = 170; nrows = im.size(); ncols = 1; nnz = nrows; ofstr->write((const char *)&fmt, 4); ofstr->write((const char *)&nrows, 4); ofstr->write((const char *)&ncols, 4); ofstr->write((const char *)&nnz, 4); ofstr->write((const char *)&im[0], 16 * nrows); closeos(ofstr); return 0; }
void pretty_printing_ex(FILE* f, TFuncMallocWrapper func) { func_t *callee_func; qstring name_of_malloc_callee_function; int func_name_set = 0; for(int i = 0; i < Malloc_calls.size(); i++){ //qfprintf(f,"%s ----> %s xref: at %a \n", func.alloc_func_name, func.ancestor, Malloc_calls[i].address); qfprintf(f,"\r\n"); callee_func = get_func(Malloc_calls[i].address); func_name_set = 0; if(callee_func){ func_name_set = 1; get_short_name(&name_of_malloc_callee_function, callee_func->startEA); //generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); //tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); } if(func_name_set) qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, name_of_malloc_callee_function.c_str()); else qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, "CISSRT_undefined_function"); //qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function"); if(Malloc_calls[i].type == CONSTVALUE){ qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value); } else if(Malloc_calls[i].type == VARVALUE){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); else qfprintf(f,"Type: VAR, last modif lost :("); //qfprintf(f,"last modif: %s\n", instr_clean); } else if(Malloc_calls[i].type == VARVALUEVULN){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); else qfprintf(f,"Type: VAR, last modif lost :("); } else if(Malloc_calls[i].type == UNDEFINED){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); //qfprintf(f,"Type:var bytes, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, instr_clean);//shouldnt be here else qfprintf(f,"Type: UNDEFINED, last modif lost :("); } } }
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; }
void analyze_malloc_xref_ex(char *name, ea_t xref_addr, int push_count) { qstring buffer; int value = 0; int type; op_t memory_size_var; if(is_trampoline(xref_addr)){ func_t *func = get_func(xref_addr); //msg("analyze_malloc_xref: %s %a - trampoline!\n", name, xref_addr); //too easy, how about mov ebp,esp jmp:malloc? if(func){ qstring buff; get_short_name(&buff, func->startEA); //get_long_name(BADADDR, func->startEA, buffer, MAXSTR); TFuncMallocWrapper new_malloc = TFuncMallocWrapper((char *)buff.c_str(), name, push_count, xref_addr, TRAMPOLINE); if(!does_exist(new_malloc)) funcMalloc_wrappers.push_back(new_malloc); } else{ TFuncMallocWrapper new_malloc = TFuncMallocWrapper("new malloc", name, push_count, xref_addr, TRAMPOLINE); if(!does_exist(new_malloc)) funcMalloc_wrappers.push_back(new_malloc); } } ea_t push_malloc_size_addr = find_instruction_N_times_backward(xref_addr, NN_push, push_count); if(push_malloc_size_addr != BADADDR){ memory_size_var = get_first_operand_new(push_malloc_size_addr); //Allocation of const memory size if(memory_size_var.type == o_imm){ //msg("analyze_malloc_xref: %s %a - immediate!\n", name, push_malloc_size_addr); Malloc_calls.push_back(TFuncMalloc_call(xref_addr, CONSTVALUE, memory_size_var.value)); //msg("analyze_malloc_xref: %s Malloc_call_list.size() = %d!\n", name, Malloc_calls.size()); return; } //Allocation of var memory size //Allocation of var by register if(memory_size_var.type == o_reg){ ea_t addr_of_src = find_instruction_that_changes_operand_backward_smart(push_malloc_size_addr, memory_size_var); msg("analyze_malloc_xref: %s %a - var!\n", name, push_malloc_size_addr); if(addr_of_src != BADADDR){ type = assign_type(addr_of_src, &value); Malloc_calls.push_back(TFuncMalloc_call(xref_addr, type, value, addr_of_src)); } else Malloc_calls.push_back(TFuncMalloc_call(xref_addr, UNDEFINED)); msg("analyze_malloc_xref: %s Malloc_call_list.size() = %d!\n", name, Malloc_calls.size()); return; } //Allocation of var by argument - new trampoline //TODO: better algo! if( (memory_size_var.type == o_displ) && (memory_size_var.reg == 5) && (memory_size_var.phrase == 5) && (memory_size_var.value == 0) && ( (int)memory_size_var.addr > 0) ){ func_t *func = get_func(xref_addr); //too easy, how about mov ebp,esp call:malloc? if(func) get_short_name(&buffer, func->startEA); //get_long_name(BADADDR, func->startEA, buffer, MAXSTR); TFuncMallocWrapper new_malloc = TFuncMallocWrapper((char *)buffer.c_str(), name, memory_size_var.addr / sizeof(ea_t) - 1, func->startEA, WRAPPER); if(!does_exist(new_malloc)) funcMalloc_wrappers.push_back(new_malloc); //funcMalloc.push_back(TFuncMalloc("here var name", memory_size_var.addr / sizeof(ea_t),func->startEA, WRAPPER)); else{ TFuncMallocWrapper new_malloc = TFuncMallocWrapper("new malloc", name, memory_size_var.addr / sizeof(ea_t) - 1, xref_addr, WRAPPER);//maybetter name malloc_at_%a? if(!does_exist(new_malloc)) funcMalloc_wrappers.push_back(new_malloc); //funcMalloc.push_back(TFuncMalloc("here name of addr", memory_size_var.addr / sizeof(ea_t), xref_addr, WRAPPER)); } return; msg("analyze_malloc_xref: %s Malloc_call_list.size() = %d!\n", name, Malloc_calls.size()); } else{ Malloc_calls.push_back(TFuncMalloc_call(xref_addr, VARVALUE)); } } else{ Malloc_calls.push_back(TFuncMalloc_call(xref_addr, UNDEFINED)); } msg("analyze_malloc_xref: %s Malloc_call_list.size() = %d!\n", name, Malloc_calls.size()); }
void pretty_printing_ex(FILE* f, TFuncMalloc func) { func_t *callee_func; qstring name_of_malloc_callee_function; int func_name_set = 0; for(int i = 0; i < Malloc_calls.size(); i++){ qfprintf(f,"\r\n"); callee_func = get_func(Malloc_calls[i].address); func_name_set = 0; if(callee_func){ func_name_set = 1; get_short_name(&name_of_malloc_callee_function, callee_func->startEA); //generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); //tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); } if(func_name_set) qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, name_of_malloc_callee_function.c_str()); else qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function"); if(Malloc_calls[i].type == CONSTVALUE){ qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value); } if(Malloc_calls[i].type == VARVALUE){ char buffer[MAXSTR]; //char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer); else qfprintf(f,"Type: VAR, last modif lost :( \n"); //qfprintf(f,"last modif: \n", instr_clean); } if(Malloc_calls[i].type == VARVALUEVULN){ char buffer[MAXSTR]; //char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, Possible Integer Overflow %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer); else qfprintf(f,"Type: VAR, last modif lost :( \n");//shouldnt be here } if(Malloc_calls[i].type == UNDEFINED){ char buffer[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, buffer);//shouldnt be here else qfprintf(f,"Type: UNDEFINED, last modif lost :("); } } }
void IDAP_run(int arg) { FILE *f, *f2; char *filename = construct_output_filename(".import_allocs.txt"); f = qfopen(filename, "wb"); char *filename2 = construct_output_filename(".import_allocs_wrappers.txt"); f2 = qfopen(filename2, "wb"); //r0 allocators funcMalloc.push_back(TFuncMalloc(" ExAllocatePoolWithQuota", 2)); funcMalloc.push_back(TFuncMalloc(" __imp__ExAllocatePoolWithQuota@8", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc(" ExAllocatePoolWithQuotaTag", 2)); funcMalloc.push_back(TFuncMalloc(" __imp__ExAllocatePoolWithQuotaTag@12", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("ExAllocatePoolWithTag", 2)); funcMalloc.push_back(TFuncMalloc("__imp__ExAllocatePoolWithTag@12", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("ExAllocatePoolWithTagPriority", 2)); funcMalloc.push_back(TFuncMalloc("__imp__ExAllocatePoolWithTagPriority@16", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("IoAllocateMdl", 2)); funcMalloc.push_back(TFuncMalloc("__imp__IoAllocateMdl@20", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("RtlAllocateHeap", 3)); funcMalloc.push_back(TFuncMalloc("__imp__RtlAllocateHeap", 3));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("EngAllocMem", 2)); funcMalloc.push_back(TFuncMalloc("__imp__EngAllocMem", 2));//win32k.sys funcMalloc.push_back(TFuncMalloc("__imp__EngAllocMem@12", 2));//win32k.sys //type pointer to size!!! //funcMalloc.push_back(TFuncMalloc("ZwAllocateVirtualMemory", 4)); //funcMalloc.push_back(TFuncMalloc("__imp__ZwAllocateVirtualMemory@24", 4));//ntoskrnl.exe //funcMalloc.push_back(TFuncMalloc("NtAllocateVirtualMemory", 4)); //funcMalloc.push_back(TFuncMalloc("__imp__NtAllocateVirtualMemory@24", 4));//ntoskrnl.exe //funcMalloc.push_back(TFuncMalloc("RtlReAllocateHeap", 4)); //funcMalloc.push_back(TFuncMalloc("HeapAlloc", 3)); //r3 allocators funcMalloc.push_back(TFuncMalloc("GlobalAlloc", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("HeapAlloc", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__HeapAlloc@12", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__HeapReAlloc@16", 4));//kernel32.dll funcMalloc.push_back(TFuncMalloc("HeapReAlloc", 4));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__LocalAlloc@8", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("LocalAlloc", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__LocalReAlloc@12", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("LocalReAlloc", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("VirtualAlloc", 2)); funcMalloc.push_back(TFuncMalloc("__imp__VirtualAlloc@16", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__MpHeapAlloc", 3));//msdart.dll export funcMalloc.push_back(TFuncMalloc("__imp__MpHeapReAlloc", 3));//msdart.dll export funcMalloc.push_back(TFuncMalloc("__imp__GdipAlloc@4", 1));//gdiplus.dll export //funcMalloc.push_back(TFuncMalloc("GpMalloc", 1));//gdiplus.dll funcMalloc.push_back(TFuncMalloc("__imp__malloc", 1));//msvcrt.dll funcMalloc.push_back(TFuncMalloc("_malloc", 1));//msvcrt.dll, the same as __imp__malloc funcMalloc.push_back(TFuncMalloc("__imp__realloc", 2));//msvcrt.dll funcMalloc.push_back(TFuncMalloc("_realloc", 2));//msvcrt.dll //funcMalloc.push_back(TFuncMalloc("_alloca", 1)); //funcMalloc.push_back(TFuncMalloc("_malloca", 1)); uint i = 0, j = funcMalloc.size(); msg("standart funcMalloc.size() = %d\n", funcMalloc.size()); for(; i< funcMalloc.size(); i++){ find_alloc_calls_ex(f, funcMalloc[i]); pretty_printing_ex(f, funcMalloc[i]); if(Malloc_calls.size() > 0 ) Malloc_calls.clear(); qfprintf(f,"\n\n"); qflush( f ); } qfclose( f ); j = funcMalloc_wrappers.size(); msg("standart funcMalloc_wrappers.size() = %d\n", j); //TODO: add level property i = 0; while( i < j){ find_alloc_calls_warreps_ex(f2, funcMalloc_wrappers[i]); msg("[%d].funcMalloc.size() = %d\n", i, funcMalloc_wrappers.size()); msg("[%d].Malloc_calls.size() = %d\n", i, Malloc_calls.size()); pretty_printing_ex(f2, funcMalloc_wrappers[i]); if(Malloc_calls.size() > 0 ) Malloc_calls.clear(); j = funcMalloc_wrappers.size(); i++; qflush( f2 ); } qfclose( f2 ); return ; }
static void free_mappings(void) { map.clear(); }