tid_t create_vtbl_struct(ea_t vtbl_addr, ea_t vtbl_addr_end, char* vtbl_name, uval_t idx, unsigned int* vtbl_len) { qstring struc_name = vtbl_name; tid_t id = add_struc(BADADDR, struc_name.c_str()); if (id == BADADDR) { struc_name.clear(); struc_name = askstr(HIST_IDENT, NULL, "Default name %s not correct. Enter other structure name: ", struc_name.c_str()); id = add_struc(BADADDR, struc_name.c_str()); set_struc_cmt(id, vtbl_name, true); } struc_t* new_struc = get_struc(id); if (!new_struc) return BADNODE; ea_t ea = vtbl_addr; int offset = 0; while (ea < vtbl_addr_end) { offset = ea - vtbl_addr; qstring method_name; ea_t method_ea = get_long(ea); if (method_ea == 0) break; if (!isEnabled(method_ea)) break; flags_t method_flags = getFlags(method_ea); char* struc_member_name = NULL; if (isFunc(method_flags)) { method_name = get_short_name(method_ea); if (method_name.length() != 0) struc_member_name = (char*)method_name.c_str(); } add_struc_member(new_struc, NULL, offset, dwrdflag(), NULL, 4); if (struc_member_name) { if (!set_member_name(new_struc, offset, struc_member_name)) { //get_name(NULL, method_ea, method_name, sizeof(method_name)); get_ea_name(&method_name, method_ea); set_member_name(new_struc, offset, struc_member_name); } } ea = ea + 4; flags_t ea_flags = getFlags(ea); if (has_any_name(ea_flags)) break; } return id; }
//------------------------------------------------------------------------- inline qstring py_get_ea_name(ea_t ea, int gtn_flags=0) { qstring out; get_ea_name(&out, ea, gtn_flags); return out; }
BOOL get_vtbl_info(ea_t ea_address, VTBL_info_t &vtbl_info) { flags_t flags = getFlags(ea_address); if(!(hasRef(flags) || has_any_name(flags) && (isDwrd(flags) || isUnknown(flags)))) return(FALSE); else { BOOL is_move_xref = FALSE; ea_t ea_code_ref = get_first_dref_to(ea_address); if(ea_code_ref && (ea_code_ref != BADADDR)) { do { if(isCode(getFlags(ea_code_ref))) { LPCTSTR disasm_line = get_text_disasm(ea_code_ref); if((*((PUINT) disasm_line) == 0x20766F6D /*"mov "*/) && (strstr(disasm_line+4, " offset ") != NULL)) { is_move_xref = TRUE; break; } } ea_code_ref = get_next_dref_to(ea_address, ea_code_ref); } while(ea_code_ref && (ea_code_ref != BADADDR)); } if(!is_move_xref) return(FALSE); ZeroMemory(&vtbl_info, sizeof(VTBL_info_t)); //get_name(BADADDR, ea_address, vtbl_info.vtbl_name, (MAXSTR - 1)); get_ea_name(&vtbl_info.vtbl_name, ea_address); ea_t ea_start = vtbl_info.ea_begin = ea_address; while(TRUE) { flags_t index_flags = getFlags(ea_address); if(!(hasValue(index_flags) && (isDwrd(index_flags) || isUnknown(index_flags)))) break; ea_t ea_index_value = get_32bit(ea_address); if(!(ea_index_value && (ea_index_value != BADADDR))) break; if(ea_address != ea_start) if(hasRef(index_flags)) break; flags_t value_flags = getFlags(ea_index_value); if(!isCode(value_flags)) { break; } else if(isUnknown(index_flags)) { doDwrd(ea_address, sizeof(DWORD)); } ea_address += sizeof(UINT); }; if((vtbl_info.methods = ((ea_address - ea_start) / sizeof(UINT))) > 0) { vtbl_info.ea_end = ea_address; return(TRUE); } else { return(FALSE); } } }