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; }
std::vector<IDAStructure> GetStructsFromDb() { std::vector<IDAStructure> structures; constexpr size_t bufferSize = 256; std::array<char, bufferSize> buffer; for (auto i = get_first_struc_idx(); i != -1; i = get_next_struc_idx(i)) { IDAStructure newStruct; const struc_t* idaStruct = get_struc(get_struc_by_idx(i)); get_struc_name(idaStruct->id, buffer.data(), bufferSize); newStruct.m_name = std::string(buffer.data()); get_struc_cmt(idaStruct->id, true, buffer.data(), bufferSize); newStruct.m_comment = std::string(buffer.data()); newStruct.m_size = get_struc_size(idaStruct->id); msg("Struct %d = %s (%s) [%d bytes]\n", i, newStruct.m_name.c_str(), newStruct.m_comment.c_str(), newStruct.m_size); size_t offset = 0; member_t* idaStructMember = get_member(idaStruct, offset); while (idaStructMember != nullptr) { IDAStructure::Member newMember; get_member_fullname(idaStructMember->id, buffer.data(), bufferSize); newMember.m_name = std::string(buffer.data()); { tinfo_t typeInfo; get_member_tinfo2(idaStructMember, &typeInfo); qstring typeName; if (typeInfo.get_type_name(&typeName)) { newMember.m_type = std::string(typeName.c_str()); } else { newMember.m_type = "undefined"; } } get_member_cmt(idaStructMember->id, true, buffer.data(), bufferSize); newMember.m_comment = std::string(buffer.data()); newMember.m_size = get_member_size(idaStructMember); offset += newMember.m_size; msg(" %s {%s} (%s) [%d bytes]\n", newMember.m_name.c_str(), newMember.m_type.c_str(), newMember.m_comment.c_str(), newMember.m_size); newStruct.m_members.push_back(std::move(newMember)); idaStructMember = get_member(idaStruct, offset); } structures.push_back(std::move(newStruct)); } return std::move(structures); }