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;
}
Пример #2
0
void idaapi dump_type_info(int file_id, const VTBL_info_t& vtbl_info, const qstring& type_name, const std::map<ea_t, VTBL_info_t>& vtbl_map) {
	struc_t * struc_type = get_struc(get_struc_id(type_name.c_str()));
	if (!struc_type)
		return;

	qstring file_entry_key;
	qstring key_hash;
	bool filtered = false;

	get_struct_key(struc_type, vtbl_info, file_entry_key, filtered, vtbl_map);
	get_hash_of_string(file_entry_key, key_hash);

	if (filtered)
		return;

	qstring file_entry_val;
	tinfo_t new_type = create_typedef(type_name.c_str());

	if (new_type.is_correct() && new_type.print(&file_entry_val, NULL, PRTYPE_DEF | PRTYPE_1LINE)) {
		qstring line;

		line = key_hash + ";" + file_entry_key + ";";
		line.cat_sprnt("%a;", vtbl_info.ea_begin);
		line += file_entry_val + ";";

		if (rtti_vftables.count(vtbl_info.ea_begin) != 0) {
			VTBL_info_t vi = rtti_vftables[vtbl_info.ea_begin];
			line += vi.vtbl_name;
		}
		line.rtrim();
		line += "\r\n";
		qwrite(file_id, line.c_str(), line.length());
	}
}
Пример #3
0
void idaapi run(int arg)
{
  char *st_name = "struc_2";
  char buf[MAXSTR];
  static char st_name_buf[100];

  if (arg == 0)
  {
    strcpy(buf, st_name);

    CWin32InputBox::InputBox("Struct name", "Enter struct name:", st_name_buf, sizeof(st_name_buf));
    st_name = st_name_buf;
  }
  
  size_t st_qty = get_struc_qty();

  msg("we have: %d structs\n", st_qty);

  // find the structure by name
  tid_t id = get_struc_id(st_name);

  // get the size of the structure
  asize_t st_sz = get_struc_size(id);

  msg("sizeof(%s) = %d\n", st_name, st_sz);

  struc_t *st = get_struc(id);

  enum_members2(st);
  return;
}
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;
}
Пример #5
0
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;
}
Пример #6
0
//--------------------------------------------------------------------------
static void declare_class(ea_t ea, const char *entryname)
{
  static const char class_name[] = "ClassStruct";
  struc_t *sptr = get_struc(get_struc_id(class_name));
  if ( sptr == NULL )
  {
    sptr = get_struc(add_struc(BADADDR, class_name));
    if ( sptr == NULL )
      return;
    opinfo_t mt;
    mt.ri.flags = REF_OFF32;
    mt.ri.target = BADADDR;
    mt.ri.base = 0;
    mt.ri.tdelta = 0;
    add_struc_member(sptr, "superClass",   BADADDR, offflag()|dwrdflag(), &mt,  4);
    add_struc_member(sptr, "masterOffset", BADADDR, wordflag(), NULL, 2);
    add_struc_member(sptr, "methodCount",  BADADDR, decflag()|wordflag(), NULL, 2);
    add_struc_member(sptr, "instanceSize", BADADDR, decflag()|wordflag(), NULL, 2);
    add_struc_member(sptr, "vdRelocTable", BADADDR, wordflag(), NULL, 2);
    add_struc_member(sptr, "relocTable",   BADADDR, wordflag(), NULL, 2);
    mt.ec.tid = get_class_struct_flags_enum();
    mt.ec.serial = 0;
    add_struc_member(sptr, "flags",        BADADDR, enumflag()|byteflag(), &mt, 1);
    add_struc_member(sptr, "masterMethods",BADADDR, byteflag(), NULL, 1);
  }
  asize_t size = get_struc_size(sptr);
  doStruct(ea, size, sptr->id);
  int count = get_word(ea+6);
//  bool c_handlers = get_byte(ea+14) & (1<<6);
  ea += size;
  ea_t messages = ea;
  doWord(ea, count*2);
  op_dec(ea, 0);
  ea += 2*count;
  doDwrd(ea, count*4);
  set_offset(ea, 0, 0);
  for ( int i=0; i < count; i++ )
  {
    ea_t idx = ea + 4*i;
    ea_t pea = toEA(get_word(idx+2), get_word(idx));
    auto_make_proc(pea);
    char name[MAXSTR];
    qsnprintf(name, sizeof(name), "%s_%u", entryname, get_word(messages+2*i));
    add_entry(pea, pea, name, true);
  }
// commented out because it doesn't work properly
// see geoplan.geo, entry number 1 for example
//  if ( c_handlers )
//    declare_parameter_types(ea+count*4, count);
}
Пример #7
0
static void declare_parameter_types(ea_t ea, int count)
{
  static const char class_name[] = "CMethodDef";
  struc_t *sptr = get_struc(get_struc_id(class_name));
  if ( sptr == NULL )
  {
    sptr = get_struc(add_struc(-1, class_name));
    if ( sptr == NULL ) return;
    add_struc_member(sptr, "methodParameterDef",   -1, wordflag(), NULL,  2);
    add_struc_member(sptr, "handlerTypeDef",   -1, byteflag(), NULL,  1);
  }
  size_t size = get_struc_size(sptr);
  doStruct(ea, size*count, sptr->id);
}
Пример #8
0
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;
}
Пример #9
0
void idaapi dump_type_info(int file_id, VTBL_info_t vtbl_info, qstring type_name, std::map<ea_t, VTBL_info_t> vtbl_map) {
	tid_t type_id = get_struc_id(type_name.c_str());
	if (type_id != BADADDR) {
		struc_t * struc_type = get_struc(type_id);
		if(struc_type != NULL) {
			qstring file_entry_key;
			qstring key_hash;
			bool filtered = false;
			
			get_struct_key(struc_type, vtbl_info, file_entry_key, filtered, vtbl_map);
			get_hash_of_string(file_entry_key, key_hash);

			if (!filtered) {
				qstring file_entry_val;
				tinfo_t new_type = create_typedef(type_name.c_str());
				if(new_type.is_correct()) {
					if (new_type.print(&file_entry_val, NULL, PRTYPE_DEF | PRTYPE_1LINE)) {
						qstring line;

						line = key_hash + ";" + file_entry_key + ";";
						line.cat_sprnt("%p;", vtbl_info.ea_begin);
						line += file_entry_val + ";";
						
						if (rtti_vftables.count(vtbl_info.ea_begin) != 0) {
							vftable::vtinfo vi = rtti_vftables[vtbl_info.ea_begin];
							line += vi.type_info;
						}
						line.rtrim();
						line += "\r\n";
						qwrite(file_id, line.c_str(), line.length());
					}
				}
			}
		}
	}
}
Пример #10
0
// check if there is a typedef with a given name and equivalent content in the db
// equivalent content means e.g. structures, unions and enums have the same members
// return its ordinal if the typedef is found. (0 otherwise)
uint32 get_equivalent_typedef_ordinal(DieHolder &typedef_holder, uint32 const type_ordinal)
{
  uint32 ordinal = 0;
  char const *typedef_name = typedef_holder.get_name();
  type_t const *type = NULL;
  char const *name = NULL;
  bool ok = get_numbered_type(idati, type_ordinal, &type);

  if(ok)
  {
    type_t const *existing_type = NULL;
    // already an existing type with the same name?
    ok = get_named_type(idati, typedef_name, NTF_TYPE | NTF_NOBASE, &existing_type);

    if(ok)
    {
      // existing type is a typedef?
      if(is_type_typedef(*existing_type))
      {
        // typedef to a structure/union?
        if(is_type_struni(*type))
        {
          name = get_typedef_name(existing_type);

          if(name != NULL)
          {
            tid_t struc_id = get_struc_id(name);

            ok = (struc_id != BADNODE);
            if(ok)
            {
              Dwarf_Off offset = 0;

              ok = diecache.get_type_offset(type_ordinal, &offset);
              if(ok)
              {
                DieHolder structure_holder(typedef_holder.get_dbg(), offset);
                StrucCmp struc_cmp(name);

                ok = struc_cmp.equal(structure_holder);
              }
            }
          }
        }
        // typedef to an enum
        else if(is_type_enum(*type))
        {
          name = get_typedef_name(existing_type);

          if(name != NULL)
          {
            enum_t enum_id = get_enum(name);

            ok = (enum_id != BADNODE);
            if(ok)
            {
              Dwarf_Off offset = 0;

              ok = diecache.get_type_offset(type_ordinal, &offset);
              if(ok)
              {
                DieHolder enumeration_holder(typedef_holder.get_dbg(), offset);
                EnumCmp enum_cmp(name);

                ok = enum_cmp.equal(enumeration_holder);
              }
            }
          }
        }
      }
    }
  }

  if(name != NULL)
  {
    if(ok)
    {
      ordinal = get_type_ordinal(idati, typedef_name);

      DEBUG("found equivalent typedef typedef_name='%s' name='%s' type_ordinal=%u ordinal=%u\n",
            typedef_name, name, type_ordinal, ordinal);
    }
  }

  return ordinal;
}
Пример #11
0
int
RP_mapping::process_string(char *str, int ln)
{
  char *arg1, *arg2;
  for ( arg1 = arg2 = str; !isspace( *arg2) && *arg2; arg2++ )
    ;
  if ( !*arg2 )
   return 0;
  *arg2++ = 0x0;
  if ( !*arg2)
   return 0;
  for ( ; *arg2 && isspace(*arg2); arg2++ )
   ;
  if ( !*arg2 )
   return 0;
  // next - just trim all spaces at end
  char *ptr = arg2 + 1;
  for ( ; !isspace(*ptr) && *ptr; ptr++ )
   ;
  *ptr = 0x0;
  /* O`k, now arg1 contains address or name and arg2 contains name of struct */
  // first check for struct presence
  tid_t tid = get_struc_id(arg2);
  if ( BADADDR == tid )
  {
    if ( verbose )
      msg("Cannot find struct '%s'\n", arg2);
    return 0;
  }
  // next try to resolve first arg as name
  ea_t ea = get_name_ea(BADADDR, arg1);
  if ( ea != BADADDR )
  {
   /* first check for already presenting */
   dnode_t *again = is_presented(ea);
   if ( NULL != again )
   {
    if ( verbose )
      msg("Warning, address %X already in dictionary, overwrite\n", ea);
    dnode_put(again, (void *)tid);
   } else {
    /* place to dict new mapping name -> tid_t */
    dict_alloc_insert(mapping, (const void *)ea, (void *)tid);
   }
#ifdef RP_DEBUG
 msg("Mapping %X (%s) -> %s (%X) \n", ea, arg1, arg2, tid);
#endif
   return 1;
  }
  /* well may be we shold add yet one underscore at begin of name ? */
  {
   int len = strlen(arg1);
   char *dup = (char *)qalloc(len + 2);
   *dup = '_';
   strcpy(dup + 1, arg1);
   ea = get_name_ea(BADADDR, dup);
   if ( BADADDR != ea )
   {
     dnode_t *again = is_presented(ea);
     if ( NULL != again )
     {
      if ( verbose )
       msg("Warning, address %X already in dictionary, overwrite\n", ea);
      dnode_put(again, (void *)tid);
     } else {
      dict_alloc_insert(mapping, (const void *)ea, (void *)tid);
     }
#ifdef RP_DEBUG
 msg("Mapping %X (%s) -> %s (%X) \n", ea, dup, arg2, tid);
#endif
     qfree(dup);
     return 1;
   }
   qfree(dup);
  }
  /* well - may be we has address ? */
  if ( *arg1 == '0' && ( arg1[1] == 'x' || arg1[1] == 'X' ) )
  {
   arg1 += 2;
   if ( ! *arg1 )
   {
    if ( verbose )
      msg("Line %d. Bad address '%s'\n", ln, arg1 - 2);
    return 0;
   }
  }
  char *notused;
  ea = strtol(arg1, &notused, 0x10);
  if ( !ea )
  {
   if ( verbose )
     msg("Line %d. Bad address '%s'\n", ln, arg1);
   return 0;
  }
  // O`k it seems that we really has some address. Lets check it
  if ( NULL == getseg(ea) )
  {
   if ( verbose )
     msg("Line %d. Address %X is not in your file\n", ln, ea);
   return 0;
  }
  dnode_t *again = is_presented(ea);
  if ( NULL != again )
  {
   if ( verbose )
    msg("Warning, address %X already in dictionary, overwrite\n", ea);
   dnode_put(again, (void *)tid);
  } else {
   dict_alloc_insert(mapping, (const void *)ea, (void *)tid);
  }
#ifdef RP_DEBUG
 msg("Mapping %X -> %s (%X) \n", ea, arg2, tid);
#endif
  return 1;  
}