Ejemplo n.º 1
0
def struct_add_ptr(sid, name, offset, count=1, type=None):
    """Add a pointer to a structure.

    If sid is a union, offset must be -1.
    """
    ptr_flag = idc.FF_DATA | word_flag(WORD_SIZE) | idaapi.offflag()
    ret = idc.AddStrucMember(sid, name, offset, ptr_flag, 0, WORD_SIZE)
    if ret == 0 and type is not None:
        if offset == -1:
            offset = struct_member_offset(sid, name)
            assert offset is not None
        mid = idc.GetMemberId(sid, offset)
        idc.SetType(mid, type)
    return ret
Ejemplo n.º 2
0
class QMetaObject__d:
    """
struct QMetaObject::d { // private data
    const QMetaObject *superdata;
    const QByteArrayData *stringdata;
    const uint *data;
    StaticMetacallFunction static_metacall;
    const QMetaObject * const *relatedMetaObjects;
    void *extradata; //reserved for future use
} d;
"""
    c_struct = [("superdata", offflag() | FF_DATA | ARCH_F),
                ("stringdata", offflag() | FF_DATA | ARCH_F),
                ("data", offflag() | FF_DATA | ARCH_F),
                ("metacall", offflag() | FF_DATA | ARCH_F),
                ("relatedMetaObjects", offflag() | FF_DATA | ARCH_F),
                ("extradata", offflag() | FF_DATA | ARCH_F)]

    def __init__(self, offset):
        struct_map(self, self.c_struct, offset)
        struct_maker(self, offset)
Ejemplo n.º 3
0
class typemap:
    """Convert bidirectionally from a pythonic type into an IDA type"""

    FF_MASK = 0xfff00000  # Mask that specifies the structure's type
    # FIXME: In some cases FF_nOFF (where n is 0 or 1) does not actually
    #        get auto-treated as an pointer by ida. Instead, it appears to
    #        only get marked as an "offset" and rendered as an integer.

    integermap = {
        1: (idaapi.byteflag(), -1),
        2: (idaapi.wordflag(), -1),
        3: (idaapi.tribyteflag(), -1),
        4: (idaapi.dwrdflag(), -1),
        8: (idaapi.qwrdflag(), -1),
        10: (idaapi.tbytflag(), -1),
        16: (idaapi.owrdflag(), -1),
    }
    if hasattr(idaapi, 'ywrdflag'):
        integermap[32] = getattr(idaapi, 'ywrdflag')(), -1

    decimalmap = {
        4: (idaapi.floatflag(), -1),
        8: (idaapi.doubleflag(), -1),
        10: (idaapi.packrealflag(), -1),
        12: (idaapi.packrealflag(), -1),
    }

    stringmap = {
        str: (idaapi.asciflag(), idaapi.ASCSTR_TERMCHR),
        unicode: (idaapi.asciflag(), idaapi.ASCSTR_UNICODE),
    }

    charmap = {
        chr: (idaapi.charflag(), -1),
    }
    ptrmap = {
        sz: (idaapi.offflag() | flg, tid)
        for sz, (flg, tid) in integermap.iteritems()
    }

    typemap = {
        int: integermap,
        long: integermap,
        float: decimalmap,
        str: stringmap,
        unicode: stringmap,
        chr: charmap,
        type: ptrmap,
    }

    # inverted lookup table
    inverted = {}
    for s, (f, _) in integermap.items():
        inverted[f & FF_MASK] = (int, s)
    for s, (f, _) in decimalmap.items():
        inverted[f & FF_MASK] = (float, s)
    for s, (f, _) in stringmap.items():
        inverted[f & FF_MASK] = (str, s)
    for s, (f, _) in ptrmap.items():
        inverted[f & FF_MASK] = (type, s)
    del f
    inverted[idaapi.FF_STRU] = (int, 1)  # FIXME: hack for dealing with
    #   structures that have the flag set
    #   but aren't actually structures..

    # defaults
    integermap[None] = integermap[(hasattr(database, 'config')
                                   and database.config.bits() or 32) / 8]
    decimalmap[None] = decimalmap[(hasattr(database, 'config')
                                   and database.config.bits() or 32) / 8]
    ptrmap[None] = ptrmap[(hasattr(database, 'config')
                           and database.config.bits() or 32) / 8]
    stringmap[None] = stringmap[str]
    charmap[None] = charmap[chr]

    @classmethod
    def dissolve(cls, flag, typeid, size):
        dt = flag & cls.FF_MASK
        sf = -1 if idaapi.is_signed_data(flag) else +1
        if dt == idaapi.FF_STRU and isinstance(typeid, (int, long)):
            t = instance(typeid)
            sz = t.size
            return t if sz == size else ([t], size // sz)
        if dt not in cls.inverted:
            logging.warn(
                'typemap.disolve(%r, %r, %r) : Unable to identify a pythonic type'
                % (dt, typeid, size))
        t, sz = cls.inverted[dt]
        res = t if sz == size else [t, sz * sf]
        return res if sz == size else (res, size)

    @classmethod
    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.º 4
0
i = 0
for t,nsize in zip(simple_types, simple_sizes):
    print "t%x:"% ((t|FF_DATA)&0xFFFFFFFF), AddStrucMember(sid, "t%02d"%i, BADADDR, (t|FF_DATA )&0xFFFFFFFF, -1, nsize)
    i+=1
 
# Test ASCII type
print "ASCII:", AddStrucMember(sid, "tascii", -1, FF_ASCI|FF_DATA, ASCSTR_C, 8)

# Test enum type - Add a defined enum name or load MACRO_WMI from a type library.
#eid = GetEnum("MACRO_WMI")
#print "Enum:", AddStrucMember(sid, "tenum", BADADDR, FF_0ENUM|FF_DATA|FF_DWRD, eid, 4)

# Test struc member type
msid = GetStrucIdByName("mystr2")
if msid != -1:
    DelStruc(msid)
msid = AddStrucEx(-1, "mystr2", 0)
print AddStrucMember(msid, "member1", -1, (FF_DWRD|FF_DATA )&0xFFFFFFFF, -1, 4)
print AddStrucMember(msid, "member2", -1, (FF_DWRD|FF_DATA )&0xFFFFFFFF, -1, 4)

msize = GetStrucSize(msid)
print "Struct:", AddStrucMember(sid, "tstruct", -1, FF_STRU|FF_DATA, msid, msize)
print "Stroff:", AddStrucMember(sid, "tstroff", -1, stroffflag()|FF_DWRD, msid, 4)

# Test offset types
print "Offset:", AddStrucMember(sid, "toffset", -1, offflag()|FF_DATA|FF_DWRD, 0, 4)
print "Offset:", SetMemberType(sid, 0, offflag()|FF_DATA|FF_DWRD, 0, 4)

print "Done"
Ejemplo n.º 5
0
i = 0
for t,nsize in zip(simple_types, simple_sizes):
    print "t%x:"% ((t|FF_DATA)&0xFFFFFFFF), add_struc_member(sid, "t%02d"%i, BADADDR, (t|FF_DATA )&0xFFFFFFFF, -1, nsize)
    i+=1

# Test ASCII type
print "ASCII:", add_struc_member(sid, "tascii", -1, FF_STRLIT|FF_DATA, STRTYPE_C, 8)

# Test enum type - Add a defined enum name or load MACRO_WMI from a type library.
#eid = get_enum("MACRO_WMI")
#print "Enum:", add_struc_member(sid, "tenum", BADADDR, FF_0ENUM|FF_DATA|FF_DWORD, eid, 4)

# Test struc member type
msid = get_struc_id("mystr2")
if msid != -1:
    del_struc(msid)
msid = add_struc(-1, "mystr2", 0)
print add_struc_member(msid, "member1", -1, (FF_DWORD|FF_DATA )&0xFFFFFFFF, -1, 4)
print add_struc_member(msid, "member2", -1, (FF_DWORD|FF_DATA )&0xFFFFFFFF, -1, 4)

msize = get_struc_size(msid)
print "Struct:", add_struc_member(sid, "tstruct", -1, FF_STRUCT|FF_DATA, msid, msize)
print "Stroff:", add_struc_member(sid, "tstroff", -1, stroffflag()|FF_DWORD, msid, 4)

# Test offset types
print "Offset:", add_struc_member(sid, "toffset", -1, offflag()|FF_DATA|FF_DWORD, 0, 4)
print "Offset:", set_member_type(sid, 0, offflag()|FF_DATA|FF_DWORD, 0, 4)

print "Done"
Ejemplo n.º 6
0
# Test ASCII type
print "ASCII:", AddStrucMember(sid, "tascii", -1, FF_ASCI | FF_DATA, ASCSTR_C,
                               8)

# Test enum type - Add a defined enum name or load MACRO_WMI from a type library.
#eid = GetEnum("MACRO_WMI")
#print "Enum:", AddStrucMember(sid, "tenum", BADADDR, FF_0ENUM|FF_DATA|FF_DWRD, eid, 4)

# Test struc member type
msid = GetStrucIdByName("mystr2")
if msid != -1:
    DelStruc(msid)
msid = AddStrucEx(-1, "mystr2", 0)
print AddStrucMember(msid, "member1", -1, (FF_DWRD | FF_DATA) & 0xFFFFFFFF, -1,
                     4)
print AddStrucMember(msid, "member2", -1, (FF_DWRD | FF_DATA) & 0xFFFFFFFF, -1,
                     4)

msize = GetStrucSize(msid)
print "Struct:", AddStrucMember(sid, "tstruct", -1, FF_STRU | FF_DATA, msid,
                                msize)
print "Stroff:", AddStrucMember(sid, "tstroff", -1,
                                stroffflag() | FF_DWRD, msid, 4)

# Test offset types
print "Offset:", AddStrucMember(sid, "toffset", -1,
                                offflag() | FF_DATA | FF_DWRD, 0, 4)
print "Offset:", SetMemberType(sid, 0, offflag() | FF_DATA | FF_DWRD, 0, 4)

print "Done"
Ejemplo n.º 7
0
#eid = get_enum("MACRO_WMI")
#print("Enum:", add_struc_member(sid, "tenum", BADADDR, FF_0ENUM|FF_DATA|FF_DWORD, eid, 4))

# Test struc member type
msid = get_struc_id("mystr2")
if msid != -1:
    del_struc(msid)
msid = add_struc(-1, "mystr2", 0)
print(
    add_struc_member(msid, "member1", -1, (FF_DWORD | FF_DATA) & 0xFFFFFFFF,
                     -1, 4))
print(
    add_struc_member(msid, "member2", -1, (FF_DWORD | FF_DATA) & 0xFFFFFFFF,
                     -1, 4))

msize = get_struc_size(msid)
print("Struct:",
      add_struc_member(sid, "tstruct", -1, FF_STRUCT | FF_DATA, msid, msize))
print("Stroff:",
      add_struc_member(sid, "tstroff", -1,
                       stroffflag() | FF_DWORD, msid, 4))

# Test offset types
print(
    "Offset:",
    add_struc_member(sid, "toffset", -1,
                     offflag() | FF_DATA | FF_DWORD, 0, 4))
print("Offset:", set_member_type(sid, 0, offflag() | FF_DATA | FF_DWORD, 0, 4))

print("Done")
Ejemplo n.º 8
0
i = 0
for t,nsize in zip(simple_types, simple_sizes):
    print("t%x:"% ((t|FF_DATA)&0xFFFFFFFF), add_struc_member(sid, "t%02d"%i, BADADDR, (t|FF_DATA )&0xFFFFFFFF, -1, nsize))
    i+=1

# Test ASCII type
print("ASCII:", add_struc_member(sid, "tascii", -1, FF_STRLIT|FF_DATA, STRTYPE_C, 8))

# Test enum type - Add a defined enum name or load MACRO_WMI from a type library.
#eid = get_enum("MACRO_WMI")
#print "Enum:", add_struc_member(sid, "tenum", BADADDR, FF_0ENUM|FF_DATA|FF_DWORD, eid, 4)

# Test struc member type
msid = get_struc_id("mystr2")
if msid != -1:
    del_struc(msid)
msid = add_struc(-1, "mystr2", 0)
print(add_struc_member(msid, "member1", -1, (FF_DWORD|FF_DATA )&0xFFFFFFFF, -1, 4))
print(add_struc_member(msid, "member2", -1, (FF_DWORD|FF_DATA )&0xFFFFFFFF, -1, 4))

msize = get_struc_size(msid)
print("Struct:", add_struc_member(sid, "tstruct", -1, FF_STRUCT|FF_DATA, msid, msize))
print("Stroff:", add_struc_member(sid, "tstroff", -1, stroffflag()|FF_DWORD, msid, 4))

# Test offset types
print("Offset:", add_struc_member(sid, "toffset", -1, offflag()|FF_DATA|FF_DWORD, 0, 4))
print("Offset:", set_member_type(sid, 0, offflag()|FF_DATA|FF_DWORD, 0, 4))

print("Done")
Ejemplo n.º 9
0
class typemap:
    """Convert bidirectionally from a pythonic type into an IDA type"""

    FF_MASKSIZE = 0xf0000000  # Mask that select's the flag's size
    FF_MASK = 0xfff00000  # Mask that select's the flag's repr
    # FIXME: In some cases FF_nOFF (where n is 0 or 1) does not actually
    #        get auto-treated as an pointer by ida. Instead, it appears to
    #        only get marked as an "offset" and rendered as an integer.

    integermap = {
        1: (idaapi.byteflag(), -1),
        2: (idaapi.wordflag(), -1),
        3: (idaapi.tribyteflag(), -1),
        4: (idaapi.dwrdflag(), -1),
        8: (idaapi.qwrdflag(), -1),
        10: (idaapi.tbytflag(), -1),
        16: (idaapi.owrdflag(), -1),
    }
    if idaapi.__version__ >= 7.0:
        del integermap[3]
    if hasattr(idaapi, 'ywrdflag'):
        integermap[32] = getattr(idaapi, 'ywrdflag')(), -1

    decimalmap = {
        4: (idaapi.floatflag(), -1),
        8: (idaapi.doubleflag(), -1),
        10: (idaapi.packrealflag(), -1),
        12: (idaapi.packrealflag(), -1),
    }

    stringmap = {
        chr: (idaapi.asciflag(), 0),
        str: (idaapi.asciflag(), idaapi.ASCSTR_TERMCHR),
        unicode: (idaapi.asciflag(), idaapi.ASCSTR_UNICODE),
    }

    ptrmap = {
        sz: (idaapi.offflag() | flg, tid)
        for sz, (flg, tid) in integermap.iteritems()
    }
    nonemap = {None: (idaapi.alignflag(), -1)}

    typemap = {
        int: integermap,
        long: integermap,
        float: decimalmap,
        str: stringmap,
        unicode: stringmap,
        chr: stringmap,
        type: ptrmap,
        None: nonemap,
    }

    # inverted lookup table
    inverted = {}
    for s, (f, _) in integermap.items():
        inverted[f & FF_MASKSIZE] = (int, s)
    for s, (f, _) in decimalmap.items():
        inverted[f & FF_MASKSIZE] = (float, s)
    for s, (f, _) in stringmap.items():
        inverted[f & FF_MASKSIZE] = (str, s)
    for s, (f, _) in ptrmap.items():
        inverted[f & FF_MASK] = (type, s)
    del f
    inverted[idaapi.FF_STRU] = (int, 1)  # FIXME: hack for dealing with
    #   structures that have the flag set
    #   but aren't actually structures..

    # defaults
    @classmethod
    def __newprc__(cls, pnum):
        info = idaapi.get_inf_structure()
        bits = 64 if info.is_64bit() else 32 if info.is_32bit() else None
        if bits is None: return

        typemap.integermap[None] = typemap.integermap[bits / 8]
        typemap.decimalmap[None] = typemap.decimalmap[bits / 8]
        typemap.ptrmap[None] = typemap.ptrmap[bits / 8]
        typemap.stringmap[None] = typemap.stringmap[str]

    @classmethod
    def __ev_newprc__(cls, pnum, keep_cfg):
        return cls.__newprc__(pnum)

    @classmethod
    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]

    @classmethod
    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