Esempio n. 1
0
def set_ida_struct(struct: Struct, controller) -> bool:
    # first, delete any struct by the same name if it exists
    sid = ida_struct.get_struc_id(struct.name)
    if sid != 0xffffffffffffffff:
        sptr = ida_struct.get_struc(sid)
        ida_struct.del_struc(sptr)

    # now make a struct header
    ida_struct.add_struc(ida_idaapi.BADADDR, struct.name, False)
    sid = ida_struct.get_struc_id(struct.name)
    sptr = ida_struct.get_struc(sid)

    # expand the struct to the desired size
    # XXX: do not increment API here, why? Not sure, but you cant do it here.
    ida_struct.expand_struc(sptr, 0, struct.size)

    # add every member of the struct
    for off, member in struct.struct_members.items():
        # convert to ida's flag system
        mflag = convert_size_to_flag(member.size)

        # create the new member
        ida_struct.add_struc_member(
            sptr,
            member.member_name,
            member.offset,
            mflag,
            None,
            member.size,
        )

    return True
Esempio n. 2
0
def add_struc_retry(name, max_attempts=100):
    i = 0
    suggested_name = name
    sid = ida_struct.add_struc(BADADDR, suggested_name)
    while sid == BADADDR:
        suggested_name = name + "_" + str(i)
        sid = ida_struct.add_struc(BADADDR, suggested_name)
        i += 1
        if i == max_attempts:
            return None, sid
    return suggested_name, sid
Esempio n. 3
0
def create_vtable_struct(sptr, name, vtable_offset, parent_name=None):
    logging.debug("create_vtable_struct(%s, %d)", name, vtable_offset)
    vtable_details = find_vtable_at_offset(sptr, vtable_offset)
    parent_vtable_member = None
    parent_vtable_struct = None
    parent_name = None
    parents_chain = None
    if vtable_details is not None:
        logging.debug("Found parent vtable %s %d", name, vtable_offset)
        parent_vtable_member, parent_vtable_struct, parents_chain = vtable_details
    else:
        logging.debug("Couldn't found parent vtable %s %d", name, vtable_offset)
    if parent_vtable_member is not None:
        parent_name = ida_struct.get_struc_name(parent_vtable_struct.id)
    vtable_name = get_class_vtable_struct_name(name, vtable_offset)
    if vtable_offset == 0:
        this_type = utils.get_typeinf_ptr(name)
    else:
        this_type = utils.get_typeinf_ptr(parent_name)
    if vtable_name is None:
        logging.exception(
            "create_vtable_struct(%s, %d): vtable_name is" " None", name, vtable_offset
        )
    vtable_id = ida_struct.add_struc(BADADDR, vtable_name, False)
    if vtable_id == BADADDR:
        logging.exception("Couldn't create struct %s", vtable_name)
    vtable_struct = ida_struct.get_struc(vtable_id)
    if parents_chain:
        for parent_name, offset in parents_chain:
            add_child_vtable(parent_name, name, vtable_id, offset)
    else:
        add_class_vtable(sptr, vtable_name, vtable_offset)

    return vtable_struct, this_type
Esempio n. 4
0
def create_cmdref():
    sid = ida_struct.add_struc(0, "cmd_ref",0)
    idc.add_struc_member(sid, "name", -1, ida_bytes.off_flag()|ida_bytes.FF_DATA|ida_bytes.FF_DWORD, -1, 4)
    idc.add_struc_member(sid, "reserve1", -1, ida_bytes.FF_DWORD, -1, 4)
    idc.add_struc_member(sid, "param", -1, ida_bytes.FF_WORD, -1, 4)
    idc.add_struc_member(sid, "id", -1, ida_bytes.FF_WORD, -1, 4)
    idc.add_struc_member(sid, "reserve2", -1, ida_bytes.FF_DWORD, -1, 4)
    return sid
Esempio n. 5
0
def get_guid_tid():
    tid = ida_struct.get_struc_id('GUID')
    if tid == idaapi.BADADDR:
        print("[*] create GUID struct")
        tid = ida_struct.add_struc(0xffffffff, 'GUID', 0)
        sptr = ida_struct.get_struc(tid)
        ida_struct.add_struc_member(sptr, 'Data1', 0x0, 0x20000000, None, 4)
        ida_struct.add_struc_member(sptr, 'Data2', 0x4, 0x10000000, None, 2)
        ida_struct.add_struc_member(sptr, 'Data3', 0x6, 0x10000000, None, 2)
        ida_struct.add_struc_member(sptr, 'Data4', 0x8, 0x00000000, None, 8)
    return tid
Esempio n. 6
0
def defENTENT():
    sid = ida_struct.get_struc_id("ENTENT")
    if sid != ida_idaapi.BADADDR:
        struc = ida_struct.get_struc(sid)
        ida_struct.del_struc(struc)
    sid = ida_struct.add_struc(ida_idaapi.BADADDR, "ENTENT", 0)
    struc = ida_struct.get_struc(sid)

    ida_struct.add_struc_member(struc, "flags", ida_idaapi.BADADDR, FF_BYTE,
                                None, 1)
    ida_struct.add_struc_member(struc, "addr", ida_idaapi.BADADDR, FF_WORD,
                                None, 2)
    return sid
Esempio n. 7
0
    def apply(cls, data):
        struct_id = ida_struct.add_struc(idaapi.BADADDR, data['name'],
                                         data['union'])
        if 'comment' in data and data['comment']:
            ida_struct.set_struc_cmt(struct_id, data['comment'], False)
        if 'repeatable_comment' in data and data['comment']:
            ida_struct.set_struc_cmt(struct_id, data['repeatable_comment'],
                                     True)

        if 'members' in data and data['members']:
            struct = ida_struct.get_struc(struct_id)
            for member_idx, member_data in data['members']:
                cls.apply_member(struct, member_data)
Esempio n. 8
0
class RTTICompleteObjectLocator(RTTIStruc):

    # Init class statics
    msid = get_struc_id("RTTICompleteObjectLocator")
    if msid != BADADDR:
        del_struc(get_struc(msid))
    msid = add_struc(0xFFFFFFFF, "RTTICompleteObjectLocator", False)
    add_struc_member(get_struc(msid), "signature", BADADDR, FF_DATA | FF_DWRD,
                     None, 4)
    add_struc_member(get_struc(msid), "offset", BADADDR, FF_DATA | FF_DWRD,
                     None, 4)
    add_struc_member(get_struc(msid), "cdOffset", BADADDR, FF_DATA | FF_DWRD,
                     None, 4)
    add_struc_member(get_struc(msid), "pTypeDescriptor", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    add_struc_member(get_struc(msid), "pClassDescriptor", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    if u.x64:
        add_struc_member(get_struc(msid), "pSelf", BADADDR,
                         FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    tid = msid
    struc = get_struc(tid)
    size = get_struc_size(tid)
    print "Completed Registering RTTICompleteObjectLocator"

    def __init__(self, ea, vtable):
        do_unknown_range(ea, self.size, DOUNK_DELNAMES)
        if doStruct(ea, self.size, self.tid):
            # Get adress of type descriptor from CompleteLocator
            print "Complete Object Locator at: 0x%x" % ea
            offset = get_member_by_name(self.struc, "pTypeDescriptor").soff
            typeDescriptor = get_32bit(ea + offset) + u.x64_imagebase()
            print "Looking for type Descriptor at: 0x%x" % typeDescriptor
            rtd = RTTITypeDescriptor(typeDescriptor)
            if rtd.class_name:
                print "Type Descriptor at: 0x%x" % typeDescriptor
                offset = get_member_by_name(self.struc,
                                            "pClassDescriptor").soff
                classHierarchyDes = get_32bit(ea + offset) + u.x64_imagebase()
                rchd = RTTIClassHierarchyDescriptor(classHierarchyDes)
                # filter out None entries
                rchd.bases = filter(lambda x: x, rchd.bases)
                className = strip(rtd.class_name)
                classes[className] = [strip(b) for b in rchd.bases]
                vtables[className] = vtable
                MakeNameEx(vtable, "vtable__" + className, SN_NOWARN)
            else:
                # if the RTTITypeDescriptor doesn't have a valid name for us to
                # read, then this wasn't a valid RTTICompleteObjectLocator
                MakeUnknown(ea, self.size, DOUNK_SIMPLE)
Esempio n. 9
0
    def _prepare_ida_type(self):
        if hasattr(self, "tid") and self.tid is not None:
            raise RuntimeError("May not call _prepare_ida_type twice")

        # Find existing structure
        self.tid = ida_struct.get_struc_id(self.name)

        if self.tid != BADADDR:
            # Grab structure pointer
            self._get_sptr()

            # Struct with given name already exists, validate it
            if self._validate_ida_type():
                self.log.info("Found struct '%s' with ID %d", self.name,
                              self.tid)
                return  # Successful

            # Existing struct not valid, ask user whether to overwrite
            query = ida_kernwin.ask_yn(
                ida_kernwin.ASKBTN_NO,
                "A structure named '{}' already exists but does not match the needed format. Do you wish to overwrite it?"
                .format(self.name))
            if query != ida_kernwin.ASKBTN_YES:
                raise RuntimeError("User cancelled operation")

            # Delete existing struct
            if not ida_struct.del_struc(self.sptr):
                raise RuntimeError(
                    "Could not delete existing structure '{}'".format(
                        self.name))
            self.log.info("Deleted struct '%s' (ID=%d)", self.name, self.tid)
            self.tid = None
            self.sptr = None

        # Create struct
        self.tid = ida_struct.add_struc(BADADDR, self.name)
        if self.tid is None or self.tid == BADADDR:
            raise RuntimeError("Could not create structure '{}'".format(
                self.name))

        # Grab structure pointer
        self._get_sptr()

        # Create members
        for f in self.members_array:
            f._prepare_ida_type()

        self.log.info("Created struct '%s' of size %d", self.name, self.size)
Esempio n. 10
0
class RTTIBaseClassDescriptor(RTTIStruc):
    msid = get_struc_id("RTTIBaseClassDescriptor")
    if msid != BADADDR:
        del_struc(get_struc(msid))
    msid = add_struc(0xFFFFFFFF, "RTTIBaseClassDescriptor", False)
    add_struc_member(get_struc(msid), "pTypeDescriptor", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    add_struc_member(get_struc(msid), "numContainerBases", BADADDR,
                     FF_DWRD | FF_DATA, None, 4)
    add_struc_member(get_struc(msid), "PMD", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    add_struc_member(get_struc(msid), "attributes", BADADDR, FF_DWRD | FF_DATA,
                     None, 4)
    tid = msid
    struc = get_struc(tid)
    size = get_struc_size(tid)
    print "Completed Registering RTTIBaseClassDescriptor"
Esempio n. 11
0
    def update_idb(self):
        sid = ida_struct.get_struc_id(self._name)
        if sid != -1:
            sptr = ida_struct.get_struc(sid)
            ida_struct.del_struc(sptr)

        sid = ida_struct.add_struc(idc.BADADDR, self._name, 0)
        sptr = ida_struct.get_struc(sid)

        for f in self._fields:
            ida_struct.add_struc_member(sptr, f.name, idc.BADADDR,
                                        (idc.FF_BYTE | idc.FF_DATA)
                                        & 0xFFFFFFFF, None, 1)
            member_name = "{}.{}".format(self._name, f.name)
            idc.SetType(
                idaapi.get_member_by_fullname(member_name)[0].id, f.type)

        ida_auto.auto_wait()
Esempio n. 12
0
    def create_structs(self):
        self.struct_id = ida_struct.add_struc(BADADDR, self.name)
        self.struct_ptr = ida_struct.get_struc(self.struct_id)
        if self.struct_ptr is None:
            logging.exception("self.struct_ptr is None at %s", self.name)
        previous_parent_offset = 0
        previous_parent_size = 0
        previous_parent_struct_id = BADADDR
        for _, parent_name, parent_offset in self.parents:
            if (
                parent_offset - previous_parent_offset > previous_parent_size
                and previous_parent_struct_id != BADADDR
            ):
                utils.expand_struct(
                    previous_parent_struct_id, parent_offset - previous_parent_offset
                )
            baseclass_id = ida_struct.get_struc_id(parent_name)
            baseclass_size = ida_struct.get_struc_size(baseclass_id)
            if baseclass_id == BADADDR or baseclass_size == 0:
                logging.warning(
                    "bad struct id or size: %s(0x%x:%s) - %s, %d",
                    self.name,
                    parent_offset,
                    parent_name,
                    baseclass_id,
                    baseclass_size,
                )
            member_name = cpp_utils.get_base_member_name(parent_name, parent_offset)
            idc.add_struc_member(
                self.struct_id,
                member_name,
                parent_offset,
                idaapi.FF_STRUCT,
                baseclass_id,
                baseclass_size,
            )
            previous_parent_offset = parent_offset
            previous_parent_size = baseclass_size
            previous_parent_struct_id = baseclass_id

        for _, parent_name, parent_offset in self.parents:
            ida_struct.get_member(
                self.struct_ptr, parent_offset
            ).props |= ida_struct.MF_BASECLASS
Esempio n. 13
0
    def load(infos):
        insn = ida_ua.insn_t()

        for info in infos:
            # Find or create struct.
            struct_id = ida_struct.get_struc_id(info['name'])
            if struct_id == BADADDR:
                print('[IDA-Sync] Creating new struct %s.' % info['name'])
                struct_id = ida_struct.add_struc(info['idx'], info['name'])
            struct = ida_struct.get_struc(struct_id)

            ida_struct.set_struc_idx(struct, info['idx'])

            # Create struct members.
            for member in info['members']:
                ida_struct.add_struc_member(
                    struct,
                    member['name'],
                    member['offset'],
                    # flag
                    0,
                    # opinfo_t instance... maybe it should sometimes be
                    # something?
                    None,
                    member['size'],
                )

            # Create xrefs to members of the struct as offsets.
            for xref in info['xrefs']:
                typ = xref['type']

                # Offset xref.
                if typ == 1:
                    # TODO figure out what second argument does.
                    idc.op_plain_offset(xref['from'], 1, xref['offset'])

                # Read/write xrefs.
                elif typ in [2, 3]:
                    ida_ua.create_insn(xref['from'], insn)
                    idc.op_stroff(insn, 1, struct.id, 0)

                # TODO do the other cases come up?
                else:
                    pass
Esempio n. 14
0
class RTTIClassHierarchyDescriptor(RTTIStruc):
    bases = None

    msid = get_struc_id("RTTIClassHierarchyDescriptor")
    if msid != BADADDR:
        del_struc(get_struc(msid))
    msid = add_struc(0xFFFFFFFF, "RTTIClassHierarchyDescriptor", False)
    add_struc_member(get_struc(msid), "signature", BADADDR, FF_DWRD | FF_DATA,
                     None, 4)
    add_struc_member(get_struc(msid), "attribute", BADADDR, FF_DWRD | FF_DATA,
                     None, 4)
    add_struc_member(get_struc(msid), "numBaseClasses", BADADDR,
                     FF_DWRD | FF_DATA, None, 4)
    add_struc_member(get_struc(msid), "pBaseClassArray", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    tid = msid
    struc = get_struc(tid)
    print "Completed Registering RTTIClassHierarchyDescriptor"

    def __init__(self, ea):
        print "Processing Class Hierarchy Descriptor at 0x%x" % ea
        do_unknown_range(ea, get_struc_size(self.tid), DOUNK_DELNAMES)
        if doStruct(ea, get_struc_size(self.tid), self.tid):
            baseClasses = get_32bit(
                ea + get_member_by_name(get_struc(
                    self.tid), "pBaseClassArray").soff) + u.x64_imagebase()
            nb_classes = get_32bit(
                ea +
                get_member_by_name(get_struc(self.tid), "numBaseClasses").soff)
            print "Baseclasses array at 0x%x" % baseClasses
            # Skip the first base class as it is itself (could check)
            self.bases = []
            for i in range(1, nb_classes):
                baseClass = get_32bit(baseClasses + i * 4) + u.x64_imagebase()
                print "base class 0x%x" % baseClass
                doDwrd(baseClasses + i * 4, 4)
                op_offset(baseClasses + i * 4, -1, u.REF_OFF | REFINFO_RVA, -1,
                          0, 0)
                doStruct(baseClass, RTTIBaseClassDescriptor.size,
                         RTTIBaseClassDescriptor.tid)
                typeDescriptor = get_32bit(baseClass) + u.x64_imagebase()
                self.bases.append(
                    RTTITypeDescriptor(typeDescriptor).class_name)
Esempio n. 15
0
    def update_idb(self, delete_existing_members=True):
        sid = ida_struct.get_struc_id(self._name)
        sptr = ida_struct.get_struc(sid)

        if sid == idc.BADADDR:
            sid = ida_struct.add_struc(idc.BADADDR, self._name, 0)
            sptr = ida_struct.get_struc(sid)
        else:
            if delete_existing_members:
                ida_struct.del_struc_members(sptr, 0, 0xffffffff)

        for f in self._fields:
            ida_struct.add_struc_member(sptr, f.name, f.offset,
                                        (idc.FF_BYTE | idc.FF_DATA)
                                        & 0xFFFFFFFF, None, 1)
            member_name = "{}.{}".format(self._name, f.name)
            idc.SetType(
                idaapi.get_member_by_fullname(member_name)[0].id, f.type)

        ida_auto.auto_wait()
Esempio n. 16
0
def defSEGENT():
    sid = ida_struct.get_struc_id("SEGENT")
    if sid != ida_idaapi.BADADDR:
        struc = ida_struct.get_struc(sid)
        ida_struct.del_struc(struc)
    sid = ida_struct.add_struc(ida_idaapi.BADADDR, "SEGENT", 0)
    struc = ida_struct.get_struc(sid)

    ida_struct.add_struc_member(struc, "flags", ida_idaapi.BADADDR,
                                ida_bytes.FF_WORD, None, 2)
    ida_struct.add_struc_member(struc, "oSegment", ida_idaapi.BADADDR,
                                ida_bytes.FF_WORD, None, 2)
    ida_struct.add_struc_member(struc, "nParagraphs", ida_idaapi.BADADDR,
                                ida_bytes.FF_WORD, None, 2)
    ida_struct.add_struc_member(struc, "nReloc", ida_idaapi.BADADDR,
                                ida_bytes.FF_WORD, None, 2)
    ida_struct.add_struc_member(struc, "minAlloc", ida_idaapi.BADADDR,
                                ida_bytes.FF_WORD, None, 2)
    ida_struct.add_struc_member(struc, "unused", ida_idaapi.BADADDR,
                                ida_bytes.FF_WORD, None, 2)
    return sid
Esempio n. 17
0
class RTTITypeDescriptor(RTTIStruc):
    class_name = None

    msid = get_struc_id("RTTITypeDescriptor")
    if msid != BADADDR:
        del_struc(get_struc(msid))
    msid = add_struc(0xFFFFFFFF, "RTTITypeDescriptor", False)
    add_struc_member(get_struc(msid),
                     "pVFTable", BADADDR, FF_DATA | u.PTR_TYPE | FF_0OFF,
                     u.mt_address(), u.PTR_SIZE)
    add_struc_member(get_struc(msid), "spare", BADADDR, FF_DATA | u.PTR_TYPE,
                     None, u.PTR_SIZE)
    add_struc_member(get_struc(msid), "name", BADADDR, FF_DATA | FF_ASCI,
                     u.mt_ascii(), 0)
    tid = msid
    struc = get_struc(tid)
    size = get_struc_size(tid)
    print "Completed Registering RTTITypeDescriptor"

    def __init__(self, ea):
        name = ea + get_member_by_name(get_struc(self.tid), "name").soff
        strlen = u.get_strlen(name)
        if strlen is None:
            # not a real vtable
            return
        self.size = self.size + strlen
        mangled = get_ascii_contents(name, strlen, 0)
        if mangled is None:
            # not a real function name
            return
        print "Mangled: " + mangled
        demangled = demangle_name('??_R0' + mangled[1:], 0)
        if demangled:
            do_unknown_range(ea, self.size, DOUNK_DELNAMES)
            if doStruct(ea, self.size, self.tid):
                print "  Made td at 0x%x: %s" % (ea, demangled)
                self.class_name = demangled
                return
        print "  FAIL :("
        return
Esempio n. 18
0
def import_structures(structures):
    """
    Import structures

    :param structures: Dict containing structure information
    """

    curr_idx = ida_struct.get_last_struc_idx() + 1
    for struct_name, struct_info in structures.items():
        # Create structure
        tid = ida_struct.add_struc(curr_idx, struct_name)

        # Get struct object and add members
        struct = ida_struct.get_struc(tid)
        for member_name, member_info in struct_info['members'].items():
            flag = get_flag_from_type(member_info['type'])
            ida_struct.add_struc_member(
                struct, member_name, member_info['offset'],
                flag, None, member_info['size']
            )

        curr_idx += 1
Esempio n. 19
0
def create_cmdptr():
    sid = ida_struct.add_struc(0, "cmd_ptr",0)
    idc.add_struc_member(sid, "id", -1, ida_bytes.FF_DWORD, -1, 4)
    idc.add_struc_member(sid, "ptr", -1, ida_bytes.off_flag()|ida_bytes.FF_DATA|ida_bytes.FF_DWORD, -1, 4)
    return sid
 def __call__(self):
     ida_struct.add_struc(self.struc, Event.encode(self.name),
                          self.is_union)
Esempio n. 21
0
 def implement(self):
     ida_struct.add_struc(long(self._id), self._name)
Esempio n. 22
0
 def __call__(self):
     ida_struct.add_struc(self.struc, self.name, self.is_union)
Esempio n. 23
0
"""
    This file is part of Polichombr
        (c) ANSSI-FR 2018

    Description:
        Semi automated test that add some data in the IDA database,
        that should be reflected in the second database
"""

import ida_name, ida_bytes, ida_struct
import idc

ida_name.set_name(0x401000, "TESTFUNCTION")
ida_bytes.set_cmt(0x40100A, "TEST COMMENT", 0)
ida_bytes.set_cmt(0x40100F, "TEST RPT COMMENT", 1)

struct_1 = ida_struct.add_struc(0, "TESTSTRUCT1")

struct_pointer = ida_struct.get_struc(struct_1)

ida_struct.add_struc_member(struct_pointer, "TESTMEMBER", 0, 0, None, 0)

idc.SetType(0x401000, "int __cdecl start(char *lpszTestArg);")
Esempio n. 24
0
 def implement(self):
     ida_struct.add_struc(self._id, self._name)
Esempio n. 25
0
def create_class(class_name, has_vtable, parent_class=None):
    class_id = ida_struct.add_struc(BADADDR, class_name)
    class_ptr = ida_struct.get_struc(class_id)
    # if parent class ->
    # if has_vtable-> if not parent- create vtable, if parent - install vtable
    return class_ptr
# with members of different types.
#
# Author: Gergely Erdelyi <*****@*****.**>
#---------------------------------------------------------------------

import ida_struct
import ida_idaapi
import ida_bytes
import ida_nalt

import idc

sid = ida_struct.get_struc_id("mystr1")
if sid != -1:
    idc.del_struc(sid)
sid = ida_struct.add_struc(ida_idaapi.BADADDR, "mystr1", 0)
print("%x" % sid)

# Test simple data types
simple_types_data = [
    (ida_bytes.FF_BYTE, 1),
    (ida_bytes.FF_WORD, 2),
    (ida_bytes.FF_DWORD, 4),
    (ida_bytes.FF_QWORD, 8),
    (ida_bytes.FF_TBYTE, 10),
    (ida_bytes.FF_OWORD, 16),
    (ida_bytes.FF_FLOAT, 4),
    (ida_bytes.FF_DOUBLE, 8),
    (ida_bytes.FF_PACKREAL, 10),
]
for i, tpl in enumerate(simple_types_data):
Esempio n. 27
0
def get_or_create_struct_id(struct_name, is_union=False):
    struct_id = ida_struct.get_struc_id(struct_name)
    if struct_id != BADADDR:
        return struct_id
    struct_id = ida_struct.add_struc(BADADDR, struct_name, is_union)
    return struct_id
Esempio n. 28
0
 def __call__(self):
     ida_struct.add_struc(ida_idaapi.BADADDR, self.name, self.is_union)