tid_t type_builder_t::get_structure(const qstring name) { tid_t struct_type_id = add_struc(BADADDR, name.c_str()); if (struct_type_id != 0 || struct_type_id != -1) { struc_t * struc = get_struc(struct_type_id); if(struc != NULL) { opinfo_t opinfo; opinfo.tid = struct_type_id; int j = 0; for(std::map<int, struct_filed>::iterator i = structure.begin(); i != structure.end() ; i ++) { VTBL_info_t vtbl; flags_t member_flgs = 0; if(i->second.size == 1) member_flgs = byteflag(); else if (i->second.size == 2) member_flgs = wordflag(); else if (i->second.size == 4) member_flgs = dwrdflag(); else if (i->second.size == 8) member_flgs = qwrdflag(); char field_name[258]; memset(field_name, 0x00, sizeof(field_name)); if((i->second.vftbl != BADADDR) && get_vbtbl_by_ea(i->second.vftbl, vtbl)) { qstring vftbl_name = name; vftbl_name.cat_sprnt("_VTABLE_%X_%p", i->second.offset, i->second.vftbl); tid_t vtbl_str_id = create_vtbl_struct(vtbl.ea_begin, vtbl.ea_end, (char *)vftbl_name.c_str(), 0); if (vtbl_str_id != BADADDR) { sprintf_s(field_name, sizeof(field_name), "vftbl_%d_%p", j, i->second.vftbl); int iRet = add_struc_member(struc, field_name, i->second.offset, member_flgs, NULL, i->second.size); member_t * membr = get_member_by_name(struc, field_name); if (membr != NULL) { tinfo_t new_type = create_typedef((char *)vftbl_name.c_str()); if(new_type.is_correct()) { smt_code_t dd = set_member_tinfo2(struc, membr, 0, make_pointer(new_type), SET_MEMTI_COMPATIBLE); } } } } else { sprintf_s(field_name, sizeof(field_name), "field_%X", i->second.offset); int iRet = add_struc_member(struc, field_name, i->second.offset, member_flgs, NULL, i->second.size); } j ++; } } } return struct_type_id; }
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; }