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;
}
Example #4
0
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;
}