Ejemplo n.º 1
0
 def mt_ascii(self):
     ri = refinfo_t()
     ri.flags = ASCSTR_C
     ri.target = -1
     mt = opinfo_t()
     mt.ri = ri
     return mt
Ejemplo n.º 2
0
def getFieldName(ea, offset):
    '''
    Get an IDA Structure field for a given offset into a structure at a given
    field.  Display as full element name, qualified with array indices as appropriate.

    We assume that "offset" is into the sid alone, not relative to the start of the
    parent structure.  First get the sid of the top-level struct as given by ea.
    Then loop:
       get name of struct at current offset into current sid
       if name is none, we are in an array, and past the first element
           get last member of current sid
           get the next offset after the last member
           assume that offset is the size of the array elements
           use MOD to get offset into element strcture
           get name can continue; if no name, bail
    '''
    print('getFieldName 0x%x' % ea)
    full_name = None        
    ti = idaapi.opinfo_t()
    f = idaversion.get_full_flags(ea)
    if idaversion.get_opinfo(ti, ea, 0, f):
       #print ("tid=%08x - %s" % (ti.tid, idaversion.get_struc_name(ti.tid)))
       sid = ti.tid
       full_name = idaversion.get_struc_name(sid)
       cur_offset = offset
       while True:
           element = None
           prev = idaversion.get_prev_offset(sid, cur_offset)
           #print('prev is %d ' % (prev))
           mn = idaversion.get_member_name(sid, cur_offset)
           #print('get_member_name sid 0x%x offset %d got %s' % (sid, cur_offset, mn))
           if mn is None:
               #print('mn none')
               last = idaversion.get_last_member(sid)
               over = idaversion.get_next_offset(sid, last)
               #print('last %d  over %d' % (last, over))
               element = int(cur_offset / over)
               cur_offset = cur_offset % over
               mn = idaversion.get_member_name(sid, cur_offset)
               #print('in array get_member_name sid 0x%x offset %d got %s array element %d' % (sid, cur_offset, mn, element))
               if mn is None:
                   break
           mem_off = idaversion.get_member_offset(sid, mn)
           #print('mn now %s offset %d' % (mn, mem_off))
           if element is None:
               full_name = full_name+'.'+mn
           else:
               full_name = '%s[%d].%s' % (full_name, element, mn)
           sid = idaversion.get_member_strid(sid, cur_offset)
           #print('new sid 0x%x cur_offset %d' % (sid, cur_offset))
           cur_offset = cur_offset - mem_off

           if sid < 0:
               #print('sid bad')
               break
       #print('full name: %s' % full_name)

    else:
       print('failed to get opinfo for 0x%x' % ea)
    return full_name
Ejemplo n.º 3
0
 def mt_address(self):
     ri = refinfo_t()
     ri.flags = self.REF_OFF
     ri.target = 0
     mt = opinfo_t()
     mt.ri = ri
     return mt
Ejemplo n.º 4
0
    def dissolve(cls, flag, typeid, size):
        dt = flag & cls.FF_MASKSIZE
        sf = -1 if flag & idaapi.FF_SIGN == idaapi.FF_SIGN else +1
        if dt == idaapi.FF_STRU and isinstance(typeid, six.integer_types):
            # FIXME: figure out how to fix this recursive module dependency
            t = sys.modules.get('structure',
                                __import__('structure')).instance(typeid)
            sz = t.size
            return t if sz == size else [t, size // sz]
        if dt not in cls.inverted:
            logging.warn(
                "{:s}.dissolve({!r}, {!r}, {!r}) : Unable to identify a pythonic type."
                .format('.'.join(('internal', __name__, cls.__name__)), dt,
                        typeid, size))

        t, sz = cls.inverted[dt]
        # if the type and size are the same, then it's a string or pointer type
        if not isinstance(sz, six.integer_types):
            count = size // idaapi.get_data_elsize(idaapi.BADADDR, dt,
                                                   idaapi.opinfo_t())
            return [t, count] if count > 1 else t
        # if the size matches, then we assume it's a single element
        elif sz == size:
            return t, (sz * sf)
        # otherwise it's an array
        return [(t, sz * sf), size // sz]
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
    def __setstate__(self, state):
        ownername, index, name, (cmtt, cmtf), ofs, t = state
        fullname = '.'.join((owername, name))

        identifier = idaapi.get_struc_id(ownername)
        if identifier == idaapi.BADADDR:
            logging.warn(
                "{:s}.instance({:s}).member_t : Creating structure {:s} -- [{:#x}] {:s}{:s}"
                .format(
                    __name__, ownername, ownername, ofs, name,
                    " // {:s}".format(cmtt or cmtf) if cmtt or cmtf else ''))
            identifier = idaapi.add_struc(idaapi.BADADDR, ownername)
        self.__owner = owner = instance(identifier, offset=0)

        flag, mytype, nbytes = t

        # FIXME: handle .strtype (strings), .ec (enums), .cd (custom)
        opinfo = idaapi.opinfo_t()
        opinfo.tid = 0 if mytype is None else mytype.id

        res = idaapi.add_struc_member(owner.ptr, name, ofs, flag, opinfo,
                                      nbytes)

        # FIXME: handle these errors properly
        # duplicate name
        if res == idaapi.STRUC_ERROR_MEMBER_NAME:
            if idaapi.get_member_by_name(owner.ptr, name).soff != ofs:
                newname = "{:s}_{:x}".format(name, ofs)
                logging.warn(
                    "{:s}.instace({:s}).member_t : Duplicate name found for {:s}, renaming to {:s}."
                    .format(__name__, ownername, name, newname))
                idaapi.set_member_name(owner.ptr, ofs, newname)
            else:
                logging.info(
                    "{:s}.instance({:s}).member_t : Field at {:+#x} contains the same name {:s}."
                    .format(__name__, ownername, ofs, name))
        # duplicate field
        elif res == idaapi.STRUC_ERROR_MEMBER_OFFSET:
            logging.info(
                "{:s}.instance({:s}).member_t : Field already found at {:+#x}. Overwriting with {:s}."
                .format(__name__, ownername, ofs, name))
            idaapi.set_member_type(owner.ptr, ofs, flag, opinfo, nbytes)
            idaapi.set_member_name(owner.ptr, ofs, name)
        # invalid size
        elif res == idaapi.STRUC_ERROR_MEMBER_SIZE:
            logging.warn(
                "{:s}.instance({:s}).member_t : Issue creating structure member {:s} : {:#x}"
                .format(__name__, ownername, fullname, res))
        # unknown
        elif res != idaapi.STRUC_ERROR_MEMBER_OK:
            logging.warn(
                "{:s}.instance({:s}).member_t : Issue creating structure member {:s} : {:#x}"
                .format(__name__, ownername, fullname, res))

        self.__index = index
        self.__owner = owner

        idaapi.set_member_cmt(self.ptr, cmtt, True)
        idaapi.set_member_cmt(self.ptr, cmtf, False)
        return
Ejemplo n.º 7
0
    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])
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
 def type(self, type):
     '''Set the member's type.'''
     flag, typeid, size = interface.typemap.resolve(type)
     opinfo = idaapi.opinfo_t()
     opinfo.tid = typeid
     return idaapi.set_member_type(
         self.__owner.ptr, self.offset - self.__owner.members.baseoffset,
         flag, opinfo, size)
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
    def __setstate__(self, state):
        ownername, index, name, (cmtt, cmtf), ofs, t = state

        identifier = idaapi.get_struc_id(ownername)
        if identifier == idaapi.BADADDR:
            logging.warn('member_t : Creating structure %s -- [%x] %s%s' %
                         (ownername, ofs, name, ' // %s' %
                          (cmtt or cmtf) if cmtt or cmtf else ''))
            identifier = idaapi.add_struc(idaapi.BADADDR, ownername)
        self.__owner = owner = instance(identifier, offset=0)

        flag, mytype, nbytes = t

        # FIXME: handle .strtype (strings), .ec (enums), .cd (custom)
        opinfo = idaapi.opinfo_t()
        opinfo.tid = 0 if mytype is None else mytype.id

        res = idaapi.add_struc_member(owner.ptr, name, ofs, flag, opinfo,
                                      nbytes)

        # FIXME: handle these errors properly
        # duplicate name
        if res == idaapi.STRUC_ERROR_MEMBER_NAME:
            if idaapi.get_member_by_name(owner.ptr, name).soff != ofs:
                newname = '%s_%x' % (name, ofs)
                logging.warn(
                    'structure_t(%s).member_t : Duplicate name found for %s, renaming to %s'
                    % (ownername, name, newname))
                idaapi.set_member_name(owner.ptr, ofs, newname)
            else:
                logging.info(
                    'structure_t(%s).member_t : Field at %x contains the same name %s'
                    % (ownername, ofs, name))
        # duplicate field
        elif res == idaapi.STRUC_ERROR_MEMBER_OFFSET:
            logging.info(
                'structure_t(%s).member_t : Field already found at %x. Overwriting with %s'
                % (ownername, ofs, name))
            idaapi.set_member_type(owner.ptr, ofs, flag, opinfo, nbytes)
            idaapi.set_member_name(owner.ptr, ofs, name)
        # invalid size
        elif res == idaapi.STRUC_ERROR_MEMBER_SIZE:
            logging.warn(
                'member_t : Issue creating structure member %s.%s : %x' %
                (ownername, name, res))
        # unknown
        elif res != idaapi.STRUC_ERROR_MEMBER_OK:
            logging.warn(
                'member_t : Issue creating structure member %s.%s : %x' %
                (ownername, name, res))

        self.__index = index
        self.__owner = owner

        idaapi.set_member_cmt(self.ptr, cmtt, True)
        idaapi.set_member_cmt(self.ptr, cmtf, False)
        return
Ejemplo n.º 12
0
 def typeid(self):
     '''Return the `.tid` of the member's type.'''
     opinfo = idaapi.opinfo_t()
     if idaapi.__version__ < 7.0:
         res = idaapi.retrieve_member_info(self.ptr, opinfo)
         return None if res is None else res.tid if res.tid != idaapi.BADADDR else None
     else:
         res = idaapi.retrieve_member_info(opinfo, self.ptr)
     return None if opinfo.tid == idaapi.BADADDR else opinfo.tid
Ejemplo n.º 13
0
 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
Ejemplo n.º 14
0
 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)
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
 def __call__(self):
     mt = idaapi.opinfo_t()
     if idaapi.isStruct(self.flag):
         mt.tid = self.extra['id']
     if idaapi.isOff0(self.flag) or idaapi.isOff1(self.flag):
         mt.ri = idaapi.refinfo_t(self.extra['flags'], self.extra['base'],
                                  self.extra['target'],
                                  self.extra['tdelta'])
     if idaapi.isASCII(self.flag):
         mt.strtype = self.extra['strtype']
     sptr = idaapi.get_struc(self.sid)
     idaapi.set_member_type(sptr, self.soff, self.flag, mt,
                            self.eoff - self.soff)
Ejemplo n.º 17
0
 def __call__(self):
     mt = idaapi.opinfo_t()
     if idaapi.isStruct(self.flag):
         mt.tid = self.extra['id']
     if idaapi.isOff0(self.flag) or idaapi.isOff1(self.flag):
         mt.ri = idaapi.refinfo_t(self.extra['flags'], self.extra['base'],
                                  self.extra['target'],
                                  self.extra['tdelta'])
     if idaapi.isASCII(self.flag):
         mt.strtype = self.extra['strtype']
     sptr = idaapi.get_struc(self.sid)
     idaapi.add_struc_member(sptr, self.fieldname.encode('utf-8'),
                             self.offset, self.flag, mt, self.nbytes)
Ejemplo n.º 18
0
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))
Ejemplo n.º 19
0
    def resolve(cls, type):
        """Return ida's (flag,typeid,size) given the type (type,size) or (type/instance)
        (int,4)     -- a dword
        ([int,4],8) -- an array of 8 dwords
        (str,10)    -- an ascii string of 10 characters
        (int,2)     -- a word
        (chr,4)     -- an array of 4 characters
        """

        # FIXME: Array definitions seem awkward, I think they should look
        #        like [type, length] and so an array of 4 words should be
        #        [(int,2), 4]

        # return idaapi.FF_xxx, typeid, and size given a tuple (type,size) or just a type/instance
        type, nbytes = type if isinstance(type, tuple) else (type, None)

        # FIXME: this explicit checking of nbytes being None is sloppy
        size = 0 if nbytes is None else abs(nbytes)

        # structure -- structure_t
        if isinstance(type, structure_t):
            flag, typeid = idaapi.struflag(), type.id

        elif type is None:
            flag, typeid = idaapi.alignflag(), -1

        elif isinstance(type, [].__class__):
            flag, typeid, nb = cls.resolve(
                tuple(type)) if len(type) > 1 else cls.resolve(*type)
            size = nb if nbytes is None else (size * nb)  # FIXME

        # defined in typemap -- (type,size)
        else:
            table = cls.typemap[type]
            if type in (int, long, float, type):
                flag, typeid = table[None if nbytes is None else size]  # FIXME
            else:
                flag, typeid = table[type]

        # automatically determine the size for the requested typeid
        if nbytes is None:
            opinfo = idaapi.opinfo_t()
            opinfo.tid = typeid
            size = idaapi.get_data_type_size(flag, opinfo)

        elif nbytes < 0:
            flag |= idaapi.signed_data_flag()

        return flag, typeid, size
Ejemplo n.º 20
0
    def add(self, name, type, offset):
        """Add a member at ``offset`` with the given ``name`` and ``type``.
        To specify a particular size, ``type`` can be a tuple with the second element referring to the size.
        """
        flag, typeid, nbytes = interface.typemap.resolve(type)

        # FIXME: handle .strtype (strings), .ec (enums), .cd (custom)
        opinfo = idaapi.opinfo_t()
        opinfo.tid = typeid
        realoffset = offset - self.baseoffset

        if name is None:
            logging.warn(
                "{:s}.instance({:s}).members.add : name is undefined, defaulting to offset {:+#x}"
                .format(__name__, self.owner.name, realoffset))
            name = 'v', realoffset
        if isinstance(name, tuple):
            name = interface.tuplename(*name)

        res = idaapi.add_struc_member(self.owner.ptr, name, realoffset, flag,
                                      opinfo, nbytes)
        if res == idaapi.STRUC_ERROR_MEMBER_OK:
            logging.info(
                "{:s}.instance({:s}).members.add : idaapi.add_struc_member(sptr={!r}, fieldname={:s}, offset={:+#x}, flag={:#x}, mt={:#x}, nbytes={:#x}) : Success"
                .format(__name__, self.owner.name, self.owner.name, name,
                        realoffset, flag, typeid, nbytes))
        else:
            error = {
                idaapi.STRUC_ERROR_MEMBER_NAME: 'Duplicate field name',
                idaapi.STRUC_ERROR_MEMBER_OFFSET: 'Invalid offset',
                idaapi.STRUC_ERROR_MEMBER_SIZE: 'Invalid size',
            }
            callee = "idaapi.add_struc_member(sptr={!r}, fieldname={:s}, offset={:+#x}, flag={:#x}, mt={:#x}, nbytes={:#x})".format(
                self.owner.name, name, realoffset, flag, typeid, nbytes)
            logging.fatal(' : '.join(
                ('members_t.add', callee,
                 error.get(res, "Error code {:#x}".format(res)))))
            return None

        res = idaapi.get_member(self.owner.ptr, realoffset)
        if res is None:
            logging.fatal(
                "{:s}.instance({:s}.members.add : Failed creating member {!r} {:s}:{:+#x}"
                .format(__name__, self.owner.name, name, realoffset, nbytes))

        # sloppily figure out what the correct index is
        idx = self.index(idaapi.get_member(self.owner.ptr, realoffset))
        return member_t(self.owner, idx)
Ejemplo n.º 21
0
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)
Ejemplo n.º 22
0
    def add(self, name, offset, type):
        """Add a member at ``offset`` with the given ``name`` and ``type``.

        To specify a particular size, ``type`` can be a tuple with the second element referring to the size.
        """
        flag, typeid, nbytes = typemap.resolve(type)

        # FIXME: handle .strtype (strings), .ec (enums), .cd (custom)
        opinfo = idaapi.opinfo_t()
        opinfo.tid = typeid
        realoffset = offset - self.baseoffset
        if name is None:
            logging.warn(
                'members_t.add : name is undefined, defaulting to offset %x' %
                (realoffset))
            name = 'v_%x' % realoffset

        res = idaapi.add_struc_member(self.owner.ptr, name, realoffset, flag,
                                      opinfo, nbytes)
        if res == idaapi.STRUC_ERROR_MEMBER_OK:
            logging.info(
                'members_t.add : idaapi.add_struc_member(sptr=%s, fieldname=%s, offset=%x, flag=%x, mt=%x, nbytes=%x) : Success'
                % (self.owner.name, name, realoffset, flag, typeid, nbytes))
        else:
            error = {
                idaapi.STRUC_ERROR_MEMBER_NAME: 'Duplicate field name',
                idaapi.STRUC_ERROR_MEMBER_OFFSET: 'Invalid offset',
                idaapi.STRUC_ERROR_MEMBER_SIZE: 'Invalid size',
            }
            callee = 'idaapi.add_struc_member(sptr=%s, fieldname=%s, offset=%x, flag=%x, mt=%x, nbytes=%x)' % (
                self.owner.name, name, realoffset, flag, typeid, nbytes)
            logging.fatal(' : '.join(
                ('members_t.add', callee, error.get(res,
                                                    'Error code %x' % res))))
            return None

        res = idaapi.get_member(self.owner.ptr, realoffset)
        if res is None:
            logging.fatal("member_t.create : Failed creating member %s %x:+%x",
                          name, realoffset, nbytes)

        # sloppily figure out what the correct index is
        idx = self.index(idaapi.get_member(self.owner.ptr, realoffset))
        return member_t(self.owner, idx)
Ejemplo n.º 23
0
    def resolve(cls, pythonType):
        """Return ida's (flag,typeid,size) given the type (type,size) or (type/instance)
        (int,4)     -- a dword
        [(int,4),8] -- an array of 8 dwords
        (str,10)    -- an ascii string of 10 characters
        (int,2)     -- a word
        [chr,4]     -- an array of 4 characters
        """
        sz, count = None, 1
        # FIXME: figure out how to fix this recursive module dependency

        # figure out what format pythonType is in
        if isinstance(pythonType, ().__class__):
            (t, sz), count = pythonType, 1
            table = cls.typemap[t]
            flag, typeid = table[abs(sz) if t in (int, long, float,
                                                  type) else t]

        elif isinstance(pythonType, [].__class__):
            # an array, which requires us to recurse...
            res, count = pythonType
            flag, typeid, sz = cls.resolve(res)

        elif isinstance(
                pythonType,
                sys.modules.get('structure',
                                __import__('structure')).structure_t):
            # it's a structure, pass it through.
            flag, typeid, sz = idaapi.struflag(
            ), pythonType.id, pythonType.size

        else:
            # default size that we can lookup in the typemap table
            table = cls.typemap[pythonType]
            flag, typeid = table[None]

            opinfo = idaapi.opinfo_t()
            opinfo.tid = typeid
            return flag, typeid, idaapi.get_data_elsize(
                idaapi.BADADDR, flag, opinfo)

        return flag | (idaapi.FF_SIGN
                       if sz < 0 else 0), typeid, abs(sz) * count
Ejemplo n.º 24
0
    def struc_member_created(self, sptr, mptr):
        extra = {}

        sname = idaapi.get_struc_name(sptr.id)
        fieldname = idaapi.get_member_name2(mptr.id)
        offset = 0 if mptr.unimem() else mptr.soff
        flag = mptr.flag
        nbytes = mptr.eoff if mptr.unimem() else mptr.eoff - mptr.soff
        mt = idaapi.opinfo_t()
        is_not_data = idaapi.retrieve_member_info(mt, mptr)
        if is_not_data:
            if idaapi.isOff0(flag) or idaapi.isOff1(flag):
                extra['target'] = mt.ri.target
                extra['base'] = mt.ri.base
                extra['tdelta'] = mt.ri.tdelta
                extra['flags'] = mt.ri.flags
                self._send_event(
                    StrucMemberCreatedEvent(sname, fieldname, offset, flag,
                                            nbytes, extra))
            # Is it really possible to create an enum?
            elif idaapi.isEnum0(flag):
                extra['serial'] = mt.ec.serial
                self._send_event(
                    StrucMemberCreatedEvent(sname, fieldname, offset, flag,
                                            nbytes, extra))
            elif idaapi.isStruct(flag):
                extra['id'] = mt.tid
                self._send_event(
                    StrucMemberCreatedEvent(sname, fieldname, offset, flag,
                                            nbytes, extra))
            elif idaapi.isASCII(flag):
                extra['strtype'] = mt.strtype
                self._send_event(
                    StrucMemberCreatedEvent(sname, fieldname, offset, flag,
                                            nbytes, extra))
        else:
            self._send_event(
                StrucMemberCreatedEvent(sname, fieldname, offset, flag, nbytes,
                                        extra))
        return 0
Ejemplo n.º 25
0
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
Ejemplo n.º 26
0
    def check_field(self, sid, ftype, strid, offset, size, name):
        if ftype is None:
            for i in range(offset, offset + size):
                self.assertIsNone(idc.GetMemberName(sid, i))
                self.assertEqual(idc.GetMemberFlag(sid, i), -1)
            return

        try:
            self.assertNotEqual(idc.GetMemberName(sid, offset - 1), name)
        except:
            pass
        for k in range(offset, offset + size):
            self.assertEqual(idc.GetMemberName(sid, k), name)
            self.assertEqual(idc.GetMemberSize(sid, k), size)
            self.assertEqual(idc.GetMemberFlag(sid, k) & idaapi.DT_TYPE, ftype & 0xFFFFFFFF)
            if strid != -1:
                st = idaapi.get_struc(sid)
                mb = idaapi.get_member(st, offset)
                op = idaapi.opinfo_t()
                idaapi.retrieve_member_info(op, mb)
                self.assertEqual(op.tid, strid)
        self.assertNotEqual(idc.GetMemberName(sid, offset + size), name)
Ejemplo n.º 27
0
    def struc_member_changed(self, sptr, mptr):
        extra = {}

        soff = 0 if mptr.unimem() else mptr.soff
        flag = mptr.flag
        mt = idaapi.opinfo_t()
        is_not_data = idaapi.retrieve_member_info(mt, mptr)
        if is_not_data:
            if idaapi.isOff0(flag) or idaapi.isOff1(flag):
                extra['target'] = mt.ri.target
                extra['base'] = mt.ri.base
                extra['tdelta'] = mt.ri.tdelta
                extra['flags'] = mt.ri.flags
                self._send_event(StrucMemberChangedEvent(sptr.id, soff,
                                                         mptr.eoff, flag,
                                                         extra))
            # Is it really possible to create an enum?
            elif idaapi.isEnum0(flag):
                extra['serial'] = mt.ec.serial
                self._send_event(StrucMemberChangedEvent(sptr.id, soff,
                                                         mptr.eoff, flag,
                                                         extra))
            elif idaapi.isStruct(flag):
                extra['id'] = mt.tid
                self._send_event(StrucMemberChangedEvent(sptr.id, soff,
                                                         mptr.eoff, flag,
                                                         extra))
            elif idaapi.isASCII(flag):
                extra['strtype'] = mt.strtype
                self._send_event(StrucMemberChangedEvent(sptr.id, soff,
                                                         mptr.eoff, flag,
                                                         extra))
        else:
            self._send_event(StrucMemberChangedEvent(sptr.id, soff,
                                                     mptr.eoff, flag,
                                                     extra))
        return 0
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
def install_vtables_union(
    class_name, class_vtable_member=None, vtable_member_tinfo=None, offset=0
):
    logging.debug(
        "install_vtables_union(%s, %s, %s)",
        class_name,
        class_vtable_member,
        str(vtable_member_tinfo),
    )
    if class_vtable_member and vtable_member_tinfo:
        old_vtable_sptr = utils.extract_struct_from_tinfo(vtable_member_tinfo)
        old_vtable_class_name = ida_struct.get_struc_name(old_vtable_sptr.id)
    else:
        old_vtable_class_name = get_class_vtable_struct_name(class_name, offset)
        old_vtable_sptr = utils.get_sptr_by_name(old_vtable_class_name)
    vtables_union_name = old_vtable_class_name
    if old_vtable_sptr and not ida_struct.set_struc_name(
        old_vtable_sptr.id, old_vtable_class_name + "_orig"
    ):
        logging.exception(
            f"Failed changing {old_vtable_class_name}->"
            f"{old_vtable_class_name+'orig'}"
        )
        return -1
    vtables_union_id = utils.get_or_create_struct_id(vtables_union_name, True)
    vtable_member_tinfo = utils.get_typeinf(old_vtable_class_name + "_orig")
    if vtables_union_id == BADADDR:
        logging.exception(
            f"Cannot create union vtable for {class_name}(){vtables_union_name}"
        )
        return -1

    vtables_union = ida_struct.get_struc(vtables_union_id)
    if not vtables_union:
        logging.exception(f"Could retrieve vtables union for {class_name}")
    if vtable_member_tinfo is not None:
        vtables_union_vtable_field_name = get_class_vtables_field_name(class_name)
    else:
        vtables_union_vtable_field_name = get_interface_empty_vtable_name()
    utils.add_to_struct(
        vtables_union, vtables_union_vtable_field_name, vtable_member_tinfo
    )
    parent_struct = utils.get_sptr_by_name(class_name)
    flag = idaapi.FF_STRUCT
    mt = idaapi.opinfo_t()
    mt.tid = vtables_union_id
    struct_size = ida_struct.get_struc_size(vtables_union_id)
    vtables_union_ptr_type = utils.get_typeinf_ptr(vtables_union_name)
    if class_vtable_member:
        member_ptr = class_vtable_member
    else:
        member_id = ida_struct.add_struc_member(
            parent_struct,
            get_class_vtable_field_name(class_name),
            offset,
            flag,
            mt,
            struct_size,
        )
        member_ptr = ida_struct.get_member_by_id(member_id)
    ida_struct.set_member_tinfo(
        parent_struct, member_ptr, 0, vtables_union_ptr_type, idaapi.TINFO_DEFINITE
    )
    return vtables_union
Ejemplo n.º 30
0
 def typeid(self):
     opinfo = idaapi.opinfo_t()
     res = idaapi.retrieve_member_info(self.ptr, opinfo)
     return None if res is None else res.tid if res.tid != idaapi.BADADDR else None
Ejemplo n.º 31
0
 def type(self, type):
     flag, typeid, size = typemap.resolve(type)
     opinfo = idaapi.opinfo_t()
     opinfo.tid = typeid
     return idaapi.set_member_type(self.__owner.ptr, self.offset, flag,
                                   opinfo, size)
Ejemplo n.º 32
0
def install_vtables_union(class_name, class_vtable_member=None, vtable_member_tinfo=None, offset=0):
    # pylint: disable=too-many-locals
    # TODO: this function is too big and must be refactored
    log.debug(
        "install_vtables_union(%s, %s, %s)",
        class_name,
        class_vtable_member,
        str(vtable_member_tinfo),
    )
    if class_vtable_member and vtable_member_tinfo:
        old_vtable_sptr = utils.extract_struct_from_tinfo(vtable_member_tinfo)
        old_vtable_class_name = ida_struct.get_struc_name(old_vtable_sptr.id)
    else:
        old_vtable_class_name = get_class_vtable_struct_name(class_name, offset)
        old_vtable_sptr = utils.get_sptr_by_name(old_vtable_class_name)
    vtables_union_name = old_vtable_class_name
    if old_vtable_sptr and not ida_struct.set_struc_name(
        old_vtable_sptr.id, old_vtable_class_name + "_orig"
    ):
        # FIXME: why log exception?
        log.exception(
            "Failed changing %s->%s_orig",
            old_vtable_class_name,
            old_vtable_class_name,
        )
        # FIXME: why -1 and not None?
        return -1
    vtables_union_id = utils.get_or_create_struct_id(vtables_union_name, True)
    vtable_member_tinfo = utils.get_typeinf(old_vtable_class_name + "_orig")
    if vtables_union_id == BADADDR:
        log.exception(
            "Cannot create union vtable for %s()%s",
            class_name,
            vtables_union_name,
        )
        # FIXME: why -1 and not None?
        return -1

    vtables_union = ida_struct.get_struc(vtables_union_id)
    if not vtables_union:
        log.exception("Could retrieve vtables union for %s", class_name)
        # FIXME: return -1?
    if vtable_member_tinfo is not None:
        vtables_union_vtable_field_name = get_class_vtables_field_name(class_name)
    else:
        vtables_union_vtable_field_name = get_interface_empty_vtable_name()
    utils.add_to_struct(vtables_union, vtables_union_vtable_field_name, vtable_member_tinfo)
    parent_struct = utils.get_sptr_by_name(class_name)
    flag = idaapi.FF_STRUCT
    mt = idaapi.opinfo_t()
    mt.tid = vtables_union_id
    struct_size = ida_struct.get_struc_size(vtables_union_id)
    vtables_union_ptr_type = utils.get_typeinf_ptr(vtables_union_name)
    if class_vtable_member:
        member_ptr = class_vtable_member
    else:
        # FIXME: add_struc_member returns error code, not member id
        member_id = ida_struct.add_struc_member(
            parent_struct,
            get_class_vtable_field_name(class_name),
            offset,
            flag,
            mt,
            struct_size,
        )
        # FIXME: get_member_by_id returns tuple, not member ptr
        member_ptr = ida_struct.get_member_by_id(member_id)
    ida_struct.set_member_tinfo(
        parent_struct,
        member_ptr,
        0,
        vtables_union_ptr_type,
        idaapi.TINFO_DEFINITE,
    )
    # FIXME: might be None! Is this OK, considering we return -1 everywhere else?
    return vtables_union