def apply(ea, st): '''Apply the structure ``st`` to the address at ``ea``.''' ea = interface.address.inside(ea) ti, fl = idaapi.opinfo_t(), database.type.flags(ea) res = idaapi.get_opinfo(ea, 0, fl, ti) ti.tid = st.id return idaapi.set_opinfo(ea, 0, fl | idaapi.struflag(), ti)
def yacheck_reference_views(self): addr = yaunit.load('reference_view_addr') ti = idaapi.opinfo_t() f = idc.GetFlags(addr) self.assertTrue(idaapi.get_opinfo(addr, self.operand, f, ti)) self.assertTrue(ti.ri.type()) self.assertEqual(ti.ri.base, self.reference_addr)
def yacheck_apply_struct(self): addrs = yaunit.load('apply_struct') for k in range(-1, 4): # retrieve struct id addr = addrs[k + 1] sid = idc.GetStrucIdByName('apply_struct_%x' % (k + 1)) self.assertNotEqual(sid, idaapi.BADADDR) # begin to check if something is applied flags = idaapi.get_flags_novalue(addr) self.assertTrue(idaapi.isStroff(flags, 1)) ti = idaapi.opinfo_t() flags = idc.GetFlags(addr) self.assertTrue(idaapi.get_opinfo(addr, 1, flags, ti)) # apply struct only if k == -1: # check struct is applied self.assertEqual(ti.path.ids[0], sid) continue # check union is selected & applied at target address uid = idc.GetStrucIdByName('apply_union_%x' % (k + 1)) self.assertNotEqual(uid, idaapi.BADADDR) fid = idc.GetMemberId(uid, k) self.assertNotEqual(fid, -1) # check union is applied self.assertEqual([x for x in ti.path.ids if x], [sid, fid])
def apply(ea, st): """Apply the structure ``st`` to the address at ``ea``""" ti = idaapi.opinfo_t() res = idaapi.get_opinfo(ea, 0, idaapi.getFlags(ea), ti) ti.tid = st.id return idaapi.set_opinfo(ea, 0, idaapi.getFlags(ea) | idaapi.struflag(), ti)
def id(ea): """Return the identifier of the structure at address ``ea``""" assert type( ea ) == idaapi.FF_STRU, 'Specified IDA Type is not an FF_STRU(%x) : %x' % ( idaapi.FF_STRU, type(ea)) ti = idaapi.opinfo_t() res = idaapi.get_opinfo(ea, 0, idaapi.getFlags(ea), ti) assert res, 'idaapi.get_opinfo returned %x at %x' % (res, ea) return ti.tid
def applied_structs(): dataseg = sark.Segment(name='seg004') for line in dataseg.lines: ti = idaapi.opinfo_t() f = idaapi.getFlags(line.ea) if idaapi.get_opinfo(line.ea, 0, f, ti): struct_name = idaapi.get_struc_name(ti.tid) if struct_name: print (line.ea - dataseg.ea, struct_name) yield line.ea - dataseg.ea, struct_name
def yacheck_reference_views(self): eas = yaunit.load('reference_views') idx = 0 for ea in eas: (operand, is_num, reference) = tests[idx] idx += 1 ti = idaapi.opinfo_t() f = idc.GetFlags(ea) self.assertTrue(idaapi.get_opinfo(ea, operand, f, ti)) self.assertTrue(ti.ri.type()) self.assertEqual(ti.ri.base, reference)
def get_reference_xrefs_at_ea(base_address, ea, references): # # REFERENCE # # we consider we have 2 operands max for op_index in xrange(0, 2): ti = idaapi.opinfo_t() f = idc.GetFlags(ea) if idaapi.get_opinfo(ea, op_index, f, ti): if ti.ri.type() != 0 and ti.ri.base != 0: if ea - base_address not in references: references[ea - base_address] = list() s = {'flags': ti.ri.flags} references[ea - base_address].append((op_index, s, ti.ri.base))
def _f1(idx, ctx): import idc import ida_bytes obj = ctx.get_memref('stroff') print "%x" % obj.ea ti = idaapi.opinfo_t() f = idc.GetFlags(obj.ea) if idaapi.get_opinfo(obj.ea, 0, f, ti): print("tid=%08x - %s" % (ti.tid, idaapi.get_struc_name(ti.tid))) print "Offset: {}".format(obj.offset) import ida_struct obj2 = ctx.get_obj('fcn') print "%x" % obj2.addr name_str = ida_name.get_name(obj2.addr) print "Name {}".format(name_str) ida_struct.set_member_name(ida_struct.get_struc(ti.tid), obj.offset, name_str)
def getOperandView(ea): operands = list() fl = idaapi.get_flags_novalue(ea) flags = [idaapi.get_optype_flags0(fl), idaapi.get_optype_flags1(fl) >> 4] for i in xrange(0, len(flags)): if flags[i] != 0: if (flags[i] & idaapi.FF_0STRO) != idaapi.FF_0STRO: # Offset property is independent : handle it first if flags[i] == idaapi.FF_0OFF: ti = idaapi.opinfo_t() if idaapi.get_opinfo(ea, i, fl, ti): try: offset_name = "-" + OFFSET_TYPE_MAP_NAMES[ti.ri.flags] except KeyError: logger.error( "OperandView at 0x%08X : no valid offset found for flags 0x%08X" % (ea, ti.ri.flags)) offset_name = "" operands.append((i, "offset" + offset_name)) elif flags[i] == idaapi.FF_0NUMD: value = "" operand = i if idaapi.is_invsign(ea, fl, i): value = "signeddecimal" else: value = "unsigneddecimal" operands.append((operand, value)) elif flags[i] == idaapi.FF_0NUMH: if idaapi.is_invsign(ea, fl, i): operands.append((i, "signedhexadecimal")) else: operands.append((i, "unsignedhexadecimal")) elif flags[i] == idaapi.FF_0CHAR: operands.append((i, "char")) elif flags[i] == idaapi.FF_0NUMB: operands.append((i, "binary")) elif flags[i] == idaapi.FF_0NUMO: operands.append((i, "octal")) return operands
def get_struc_enum_xrefs_at_ea(base_address, ea, strucs, enums, stackframe, func): # structures # TODO: fix use a lot of CPU !!!! (call twice) if idaapi.decode_insn(ea) == 0: logger.warning("Invalid instruction at %x." % (ea)) # TODO: check that it is a good thing not to exit """ Code Example : .text:000000010003D73A E8 CD FB 01+ call _CxxThrowException .text:000000010003D73A 00 ; --------------------------------------------------------------------------- .text:000000010003D73F CC db 0CCh .text:000000010003D73F sub_10003D6D8 endp .text:000000010003D73F .text:000000010003D740 CC CC CC CC+ db 8 dup(0CCh) .text:000000010003D748 90 90 90 90+ align 10h 0xCC can be used as padding : it is recognized as an illegal instruction by IDA The instruction should be just ignored, no need to exit """ # sys.exit(-1) else: # TODO: add 2 xrefs instead of one in struc operands """ following instruction : cmp eax, struc_1.field_1 should add 2 xrefs : (in XML format) <xrefs offset="0x0000004A" operand="0x00000001" delta="X">UUID(struc_1)</xrefstrucs> <xrefs offset="0x0000004A" operand="0x00000001">UUID(struc_1.field_1)</xrefstrucs> This way, if field_1 is moved inside struc_1 (between 2 different versions of binary), it will still be identified """ op_index = 0 for op in idaapi.cmd.Operands: if op.type != idaapi.o_void: ti = idaapi.opinfo_t() f = idc.GetFlags(ea) if isEnum(f, op_index): if idaapi.get_opinfo(ea, op_index, f, ti): name = idc.GetEnumName(ti.ec.tid) if name is not None: # name can be None if the enum was deleted try: ll = enums[ea - base_address] except KeyError: ll = list() enums[ea - base_address] = ll ll.append((op_index, ti.ec.tid, name)) elif isStroff(f, op_index): if idaapi.get_opinfo(ea, op_index, f, ti): struc_path = ti.path.ids struc_delta = ti.path.delta path_len = ti.path.len try: struc_xrefs = strucs[ea - base_address] except KeyError: struc_xrefs = list() strucs[ea - base_address] = struc_xrefs for path_idx in xrange(0, path_len): field_id = struc_path[path_idx] if path_len > 1: logger.debug("adding path_idx=%d, id=0x%08X, name=%s" % ( path_idx, field_id, idaapi.get_struc_name(field_id))) struc_dict = None if struc_delta != 0: struc_dict = {'delta': "0x%08X" % struc_delta} if path_idx != 0: if struc_dict is None: struc_dict = {'path_idx': "0x%08X" % path_idx} else: struc_dict['path_idx'] = "0x%08X" % path_idx struc_xrefs.append((op_index, struc_dict, field_id)) # # STACK VARIABLE # # check if op if var stack if func is not None and ( ((op_index == 0) and idaapi.isStkvar0(f)) or ((op_index == 1) and idaapi.isStkvar1(f)) ): t = idaapi.get_stkvar(op, op.addr) if t is not None: (member, actval) = t if ea - base_address not in stackframe: stackframe[ea - base_address] = list() stackframe[ea - base_address].append((op_index, member, idaapi.get_spd(func, ea))) op_index += 1
def getStructureId(ea): assert getType(ea) == idaapi.FF_STRU ti = idaapi.opinfo_t() res = idaapi.get_opinfo(ea, 0, idaapi.getFlags(ea), ti) assert res, 'idaapi.get_opinfo returned %x at %x' % (res, ea) return ti.tid
def getStructureId(ea): assert getType(ea) == idaapi.FF_STRU ti = idaapi.opinfo_t() res = idaapi.get_opinfo(ea, 0, idaapi.getFlags(ea), ti) assert res, 'idaapi.get_opinfo returned %x at %x'% (res,ea) return ti.tid