Ejemplo n.º 1
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.º 2
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.º 3
0
    def yatest_apply_struct(self):
        addrs = []
        # -1: struct, n: union
        for k in range(-1, 4):
            # find an integer operand in any function
            addr = self.find_operand_addr()
            addrs.append(addr)

            # create struct
            sid = idc.AddStrucEx(-1, 'apply_struct_%x' % (k + 1), 0)
            self.assertNotEqual(sid, -1)
            ftype = idaapi.FF_BYTE | idaapi.FF_DATA

            # apply struct only
            if k == -1:
                # add struct fields
                for x in xrange(0, 0x60):
                    self.assertEqual(
                        idc.AddStrucMember(sid, 'field_%x' % x, -1, ftype, -1,
                                           1), 0)
                path = idaapi.tid_array(1)
                path[0] = sid
                self.assertNotEqual(
                    self.custom_op_stroff(addr, path.cast(), 1),
                    idaapi.BADADDR)
                continue

            # create union
            uid = idc.AddStrucEx(-1, 'apply_union_%x' % (k + 1), 1)
            self.assertNotEqual(uid, -1)
            for x in xrange(1, 0x10):
                self.assertEqual(
                    idc.AddStrucMember(uid, 'union_%x' % x, -1, ftype, -1, 1),
                    0)

            # add struct fields
            for x in xrange(0, 0x60):
                self.assertEqual(
                    idc.AddStrucMember(sid, 'field_%x' % x, -1,
                                       idaapi.struflag(), uid, 1), 0)

            # apply selected union field
            fid = idc.GetMemberId(uid, k)
            self.assertNotEqual(fid, -1)
            path = idaapi.tid_array(2)
            path[0] = sid
            path[1] = fid
            self.assertNotEqual(self.custom_op_stroff(addr, path.cast(), 2),
                                idaapi.BADADDR)
        yaunit.save('apply_struct', addrs)
Ejemplo n.º 4
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.º 5
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