bool idaapi check_subtype(const VTBL_info_t &vtbl_info, const qstring &subtype_name) { bool bResult = false; qstring search_str; search_str.sprnt("_%p", vtbl_info.ea_begin); tid_t type_id = get_struc_id(subtype_name.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) { qstring member_name = get_member_name2(member_info->id); if (member_name.find(search_str, 0) != -1) { bResult = true; break; } } } } } return bResult; }
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; }
void enum_members3(struc_t *st) { asize_t ofs = get_struc_first_offset(st); ssize_t m_idx; char buf[MAXSTR]; while ((m_idx = get_next_member_idx(st, ofs)) != BADADDR) { member_t *mem = get_member(st, ofs); get_member_name(mem->id, buf, sizeof(buf)); msg("name=%s idx=%a ; ofs=%a\n", buf, m_idx, ofs); ofs += mem->eoff; } }
bool idaapi check_subtype(VTBL_info_t vtbl_info, qstring subtype_name) { qstring search_str; search_str.sprnt("_%a", vtbl_info.ea_begin); struc_t * struc_type = get_struc(get_struc_id(subtype_name.c_str())); if (!struc_type) return false; // 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; qstring member_name = get_member_name(member_info->id); if (member_name.find(search_str, 0) != member_name.npos) return true; } return false; }
void get_struct_key(struc_t * struc_type, const VTBL_info_t& vtbl_info, qstring &file_entry_key, bool &filtered, const std::map<ea_t, VTBL_info_t>& vtbl_map) { qstring sub_key; qstring vtables_sub_key; int vftbales_num = 0; int members_count = 0; 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) { 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) { ea_t vtable_addr = 0; int i; if (qsscanf(member_name.c_str(), "vftbl_%d_%" FMT_EA "x", &i, &vtable_addr) > 0) { if (vtbl_map.count(vtable_addr) != 0) { vtables_sub_key.cat_sprnt("_%d", vtbl_map.at(vtable_addr).methods); } } vftbales_num ++; } sub_key.cat_sprnt("_%d", member_size); members_count ++; } } file_entry_key.sprnt("t_%d_%d", vtbl_info.methods, vftbales_num); file_entry_key += vtables_sub_key; file_entry_key += sub_key; if (members_count < STRUCT_DUMP_MIN_MEMBER_COUNT) filtered = true; }