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;
}
Esempio n. 2
0
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);
}