예제 #1
0
def create_cmdref():
    sid = ida_struct.add_struc(0, "cmd_ref")
    idc.AddStrucMember(sid, "name", -1, offflag() | FF_DATA | FF_DWRD, -1, 4)
    idc.AddStrucMember(sid, "id", -1, idc.FF_DWRD, -1, 4)
    idc.AddStrucMember(sid, "id2", -1, idc.FF_DWRD, -1, 4)
    idc.AddStrucMember(sid, "id3", -1, idc.FF_DWRD, -1, 4)
    return sid
예제 #2
0
 def fillStruct(self, sid, data):
     for i in data:
         new_type = None
         #(i1, i2, i3) = self.stepper.parseField(i[1])
         name = i[1]
         if name[0] == "*":
             name = name[1:]
         if i[1] != "uintptr":
             i1, i2, i3 = (idc.FF_BYTE | idc.FF_DATA, -1, 1)
         else:
             i1, i2, i3 = self.uintptr
         if name == i[1]:
             new_type = i[1]
         else:
             new_type = name + " *"
         res = idc.AddStrucMember(sid, i[0], -1, i1, i2, i3)
         use_name = i[0]
         if res == -1:  #Bad name
             #print "Bad name %s for struct member" % i[0]
             use_name = i[0] + "_autogen_" + id_generator()
             idc.AddStrucMember(sid, use_name, -1, i1, i2, i3)
         if new_type is not None:
             offset = idc.GetMemberOffset(sid, use_name)
             #print "Setting %s as %s" % (i[0], new_type)
             idc.SetType(idc.GetMemberId(sid, offset), new_type)
예제 #3
0
def create_struc_from_skeleton(name, skeleton, default_type=idaapi.FF_DWRD):
    sorted_data_types = sorted(data_types.items(),
                               key=lambda x: x[1],
                               reverse=True)
    sid = idc.GetStrucIdByName(name)
    if sid != idaapi.BADADDR:
        idc.DelStruc(sid)
    idx = idc.AddStrucEx(idaapi.BADADDR, name, False)
    i = 0
    size = skeleton[-1][SKELETON_OFFSET] + data_types[skeleton[-1]
                                                      [SKELETON_TYPE]]
    while i < size:
        if i < skeleton[0][SKELETON_OFFSET]:
            if i + data_types[default_type] <= skeleton[0][SKELETON_OFFSET]:
                idc.AddStrucMember(idx, 'field_{0}'.format(hex(i)), i,
                                   default_type | idaapi.FF_DATA, -1,
                                   data_types[default_type])
                i += data_types[default_type]
            else:
                for data_type in sorted_data_types:
                    if skeleton[0][SKELETON_OFFSET] - i >= data_type[1]:
                        idc.AddStrucMember(idx, 'field_{0}'.format(hex(i)), i,
                                           data_type[0] | idaapi.FF_DATA, -1,
                                           data_type[1])
                        i += data_type[1]
                        break
        elif i == skeleton[0][SKELETON_OFFSET]:
            idc.AddStrucMember(idx, skeleton[0][SKELETON_NAME],
                               skeleton[0][SKELETON_OFFSET],
                               skeleton[0][SKELETON_TYPE] | idaapi.FF_DATA, -1,
                               data_types[skeleton[0][SKELETON_TYPE]])
            i += data_types[skeleton[0][SKELETON_TYPE]]
            skeleton.pop(0)
        else:
            skeleton.pop(0)
예제 #4
0
파일: snippet.py 프로젝트: szabo92/gistable
def create_CFLString_struct():
    sid = find_or_create_struct("CFLString")
    print idc.AddStrucMember(sid, "magic", -1, idc.FF_DWRD, -1, 4)
    print idc.AddStrucMember(sid, "unk4", -1, idc.FF_DWRD, -1, 4)
    print idc.AddStrucMember(sid, "cstr", -1, idc.FF_BYTE, -1, 0)

    return sid
예제 #5
0
 def yatest_create_sub(self):
     for offset, count in create_sub:
         name = 'substruct_' + hhex(offset) + '_' + hhex(count)
         sida = idc.AddStrucEx(-1, name + '_sub1', 0)
         self.assertNotEqual(sida, -1)
         sidb = idc.AddStrucEx(-1, name + '_sub2', 0)
         self.assertNotEqual(sidb, -1)
         for i in xrange(0, 16):
             self.assertEqual(idc.AddStrucMember(sidb, 'sub_' + hhex(i), i, idaapi.FF_BYTE | idaapi.FF_DATA, -1, 1), 0)
         self.assertEqual(idc.AddStrucMember(sida, 'sub_struc', offset, idaapi.FF_STRU | idaapi.FF_DATA, sidb, count * 16), 0)
예제 #6
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)
예제 #7
0
def register_struct(objname, s):
    """Registers a ctypes.Structure structure and returns Structure Type ID"""
    tid = idc.AddStruc(-1, objname)
    if tid < 0:
        raise Exception('ida_add_structure error %d' % tid)

    for name, typ in s._fields_:
        # normal type
        if typ in _ctypes_table:
            typ, size = _ctypes_table[typ]
            typeid = -1
        # embedded struct type
        elif typ in _registered_structures:
            _, typeid, size = _registered_structures[typ]
            typ = idc.FF_STRU
        # pointer to a predefined structure
        else:
            typ = idc.FF_0OFF | idc.FF_DWRD
            typeid, size = 0, 4

        ret = idc.AddStrucMember(tid, name, -1, typ, typeid, size)
        if ret < 0:
            raise Exception('ida_add_structure_member %s: %d' % (name, ret))

    # add this structure identifier to the global list
    _registered_structures[s] = objname, tid, ctypes.sizeof(s)
    return tid
예제 #8
0
def _create_class_structs__slices(classinfo, endmarkers=True):
    """Create the IDA structs for a C++ class."""
    classname = classinfo.classname
    # Open or create the structs.
    sidf = idau.struct_open(classname + '::fields', create=True)
    sid = idau.struct_open(classname, create=True)
    if sid is None or sidf is None:
        _log(0, 'Could not create class structs for {}', classname)
        return None
    assert all(not idc.IsUnion(s) for s in (sidf, sid))
    # Calculate the size of the ::fields struct.
    if classinfo.superclass:
        # If we have a superclass, our fields start after our superclass's fields end.
        fields_start = classinfo.superclass.class_size
    else:
        # If we don't have a superclass, our fields start after our vtable.
        fields_start = idau.WORD_SIZE
    fields_size = classinfo.class_size - fields_start
    # Add an ::end member to the fields struct if requested.
    if endmarkers:
        ret = idc.AddStrucMember(sidf, classname + '::end', fields_size,
                                 idc.FF_UNK, -1, 0)
        if ret not in (0, idc.STRUC_ERROR_MEMBER_NAME,
                       idc.STRUC_ERROR_MEMBER_OFFSET):
            # If that didn't work that's too bad, but continue anyway.
            _log(0, 'Could not create {}::end', classname)
    return sid, sidf, fields_start
예제 #9
0
def struct_add_word(sid, name, offset, size, count=1):
    """Add a word (integer) to a structure.

    If sid is a union, offset must be -1.
    """
    return idc.AddStrucMember(sid, name, offset, idc.FF_DATA | word_flag(size),
                              -1, size * count)
예제 #10
0
    def build_struct(self):
        ''' Creates an IDA structure for this Type.
        '''
        if self.struct is not None:
            return

        for p in self.parents:
            p.build_struct()

        self.struct = idc.AddStrucEx(-1, self.name, 0)

        if as_signed(self.struct, TARGET_ADDRESS_SIZE) == -1:
            raise RuntimeError("Unable to make struct `{}`".format(self.name))
        else:
            #TODO: either come up with another way of showing this, or
            #      sync it with the actual function names
            cmt = "constructors: "
            for c in self.constructors():
                cmt += "{}(0x{:02x}), ".format(idc.Name(c), c)
            cmt = cmt.strip(", ")
            idaapi.set_struc_cmt(self.struct, cmt, False)

        if TARGET_ADDRESS_SIZE == 8:
            mask = idc.FF_QWRD
        else:
            mask = idc.FF_DWRD

        # Only bases get the magic _vptr member
        if len(self.parents) == 0:
            idc.AddStrucMember(self.struct, "_vptr", 0, idc.FF_DATA | mask, -1,
                               TARGET_ADDRESS_SIZE)
            idc.SetType(idc.GetMemberId(self.struct, 0), "_vfunc**")

        for i, parent in enumerate(self.parents):
            try:
                #TODO: for non-itanium ABI, this may not be available
                #      when RTTI is disabled
                offset = self.tablegroup.tables[i].offset_to_top
            except:
                break

            idc.AddStrucMember(self.struct, "parent_{}".format(i),
                               -offset, idc.FF_DATA, -1,
                               idc.GetStrucSize(parent.struct))

            idc.SetType(idc.GetMemberId(self.struct, -offset), parent.name)
예제 #11
0
 def yatest_set_field_prototype(self):
     for field_type, name, prototype in set_field_prototype:
         sid = idc.AddStrucEx(-1, name, 0)
         self.assertNotEqual(sid, -1)
         self.assertEqual(idc.AddStrucMember(sid, 'field', 0, field_type | idaapi.FF_DATA, -1, get_size(field_type, -1)), 0)
         mid = idc.GetMemberId(sid, 0)
         self.assertNotEqual(mid, -1)
         self.assertTrue(idc.SetType(mid, prototype))
예제 #12
0
def struct_add_struct(sid, name, offset, msid, count=1):
    """Add a structure member to a structure.

    If sid is a union, offset must be -1.
    """
    size = idc.GetStrucSize(msid)
    return idc.AddStrucMember(sid, name, offset, idc.FF_DATA | idc.FF_STRU,
                              msid, size * count)
예제 #13
0
 def create_field(self, sid, offset, name, ftype, strid, count):
     if ftype is None or name is None:
         return
     name = 'field_%.04X_%s' % (offset, name)
     size = get_size(ftype, strid) if ftype is not None else 1
     self.assertEqual(
         idc.AddStrucMember(sid, name, offset, ftype | idaapi.FF_DATA,
                            strid, size * count), 0)
예제 #14
0
def find_WdfDriverCreate():
    function_offset = OFFSET_WdfDriverCreate

    # If the XREF to wdfFunctions + function_offset exists.. then we're in case 1!
    try:
        call_pfnWdfDriverCreate = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset).next().frm
    except StopIteration:
        # this is case 2!
        call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("mov", 1,function_offset)
        if call_pfnWdfDriverCreate != None:
            idc.OpStroffEx(call_pfnWdfDriverCreate,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)
        else:
            call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("call", 0, function_offset)
            idc.OpStroffEx(call_pfnWdfDriverCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)

    if call_pfnWdfDriverCreate != None:
        # First identify the RealDriverEntry :)
        current_func = idaapi.get_func(call_pfnWdfDriverCreate)
        idc.MakeName(current_func.startEA, "_DriverEntry_")

        argument_DriverConfig_addr = find_function_arg_with_operand_value(call_pfnWdfDriverCreate, "mov", "rsp", 0x20, 0)
        register_DriverConfig = idc.GetOpnd(argument_DriverConfig_addr, 1)
        lea_DriverConfig_addr = find_function_arg(argument_DriverConfig_addr, "lea", register_DriverConfig, 0)

        # Get stack and the stack operand offset
        current_func = idaapi.get_func(lea_DriverConfig_addr)
        stack_id = idc.GetFrame(current_func)
        opnd = idc.GetOpnd(lea_DriverConfig_addr, 1)
        if "rsp" in opnd:
            stack_member_offset = idc.GetOperandValue(lea_DriverConfig_addr, 1)
        elif "rbp" in opnd:
            var_x = opnd.split("+")[-1][:-1] # [rbp+57h+var_80] -> var_80
            members, _ = retrieve_stack_members(current_func)
            inverted_members = {v:k for k, v in members.items()}
            try:
                stack_member_offset = inverted_members[var_x]
            except KeyError as msg:
                print msg
                return

        else:
            print("+] WdfDriverCreate() Unidentified register stack layout")
            return

        #idc.SetMemberName(stack_id, stack_member_offset, "_DriverConfig")
        struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG")
        struct_size = idc.GetStrucSize(struct_id)

        # First check if we have already touch this function stack before
        #if function_stack_erased(current_func):
            # need to take care of the already defined structs
        #    pass
        #else:
        delete_all_function_stack_members(current_func, force=True)
        idc.AddStrucMember(stack_id, "driver_config",
                           stack_member_offset, idc.FF_BYTE|idc.FF_DATA,
                           -1, struct_size)
        idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, struct_id, 1)
예제 #15
0
def create_DISPFUNC_struct(name):
    sid = find_or_create_struct(name)
    idc.AddStrucMember(sid, "FuncName", 0, idc.FF_DWRD | FF_0OFF, -1, 4)
    idc.AddStrucMember(sid, "DISPID", 4, idc.FF_DWRD, -1, 4)
    idc.AddStrucMember(sid, "vtsParam", 8, idc.FF_DWRD, -1, 4)
    idc.AddStrucMember(sid, "vtRetVal", 0xC, idc.FF_DWRD, -1, 4)
    idc.AddStrucMember(sid, "pfnMember", 0x10, idc.FF_DWRD | FF_0OFF, -1, 4)
    idc.AddStrucMember(sid, "pfn", 0x14, idc.FF_DWRD | FF_0OFF, -1, 4)
    idc.AddStrucMember(sid, "filed18", 0x18, idc.FF_DWRD, -1, 4)
    idc.AddStrucMember(sid, "afxDispCustom", 0x1C, idc.FF_DWRD, -1, 4)

    return sid
예제 #16
0
 def checkVtblStruct(self, descr):
     if not descr.get('vtblid'):
         descr['vtblnm'] = descr['name'] + 'Vtbl'
         descr['vtblid'] = idc.AddStrucEx(-1, descr['vtblnm'], 0)
         idc.AddStrucMember(descr['vtblid'], "queryi", 0, idc.FF_QWRD, -1,
                            8)
     if not descr.get('id'):
         descr['id'] = idc.AddStrucEx(-1, descr['name'], 0)
     self.setStrucPntr(descr['id'], 0, 'vtbl', descr['vtblnm'] + '*')
     return descr
예제 #17
0
 def yatest_create_struct_field(self):
     for offset, count, field_type, string_type, comment, repeatable in create_field:
         size = count * get_size(field_type, string_type)
         name = get_name(field_type, string_type, offset, size)
         sid = idc.AddStrucEx(0, 'struct_' + name, 0)
         self.assertNotEqual(sid, -1)
         err = idc.AddStrucMember(sid, 'field_' + name, offset, field_type | idaapi.FF_DATA, string_type, size)
         self.assertEqual(err, 0)
         if comment is not None:
             self.assertNotEqual(idc.SetMemberComment(sid, offset, comment, repeatable), 0)
예제 #18
0
 def yatest_reference_loop(self):
     mids = []
     for k in range(0, 2):
         sid = idc.AddStrucEx(-1, 'refloop' + str(k), 0)
         self.assertNotEqual(sid, -1)
         self.assertEqual(idc.AddStrucMember(sid, 'refloop_field' + str(k), 0, idaapi.FF_DWRD, -1, 4), 0)
         mid = idc.GetMemberId(sid, 0)
         self.assertNotEqual(mid, -1)
         mids.append(mid)
     for k in range(0, 2):
         self.assertTrue(idc.SetType(mids[k], 'refloop' + str(1 - k) + ' *'))
예제 #19
0
def create_struc(name, size, default_type=idaapi.FF_DWRD):
    sid = idc.GetStrucIdByName(name)
    if sid != idaapi.BADADDR:
        idc.DelStruc(sid)
    idx = idc.AddStrucEx(idaapi.BADADDR, name, False)
    i = 0
    while i < size:
        idc.AddStrucMember(idx, 'field_{0}'.format(hex(i)), i,
                           default_type | idaapi.FF_DATA, -1,
                           data_types[default_type])
        i += data_types[default_type]
예제 #20
0
    def makeStructFromHits(self, count, startHitIdx, endHitIdx):
        structName = 'sc%d' % count
        self.logger.debug("Making struct %d:", count)

        structId = idc.AddStrucEx(0xffffffff, structName, 0)
        if structId == 0xffffffff:
            raise ValueError("Struct %s already exists!" % structName)
        subRange = self.hits[startHitIdx:endHitIdx]
        for i in range(len(subRange)):
            hit = subRange[i]
            self.logger.debug("%02x: %08x: %08x %s" , i*self.PTR_SIZE, hit.ea, hit.symHash.hashVal, hit.symHash.symbolName)
            idc.AddStrucMember(structId, str(hit.symHash.symbolName), i*self.PTR_SIZE, idc.FF_DATA|idc.FF_DWRD, -1, 4)
예제 #21
0
def find_WdfIoQueueCreate():
    function_offset = OFFSET_WdfIoQueueCreate

    calls_to_pfn_list = []
    try:
        for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] +
                                     function_offset):
            call_pfnWdfIoQueueCreate = xref.frm
            calls_to_pfn_list.append(call_pfnWdfIoQueueCreate)
    except StopIteration:
        # this is case 2 or 3
        pass
    if len(calls_to_pfn_list) == 0:
        call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate(
            "call", 0, function_offset)
        if call_pfnWdfIoQueueCreate:
            calls_to_pfn_list.append(call_pfnWdfIoQueueCreate)
            idc.OpStroffEx(call_pfnWdfIoQueueCreate, 0,
                           (idaapi.get_struc_id("_WDFFUNCTIONS")), 0)

    if len(calls_to_pfn_list) == 0:
        call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate(
            "mov", 1, function_offset)
        if call_pfnWdfIoQueueCreate:
            calls_to_pfn_list.append(call_pfnWdfIoQueueCreate)
            idc.OpStroffEx(call_pfnWdfIoQueueCreate, 1,
                           (idaapi.get_struc_id("_WDFFUNCTIONS")), 0)

    for pfn_call in calls_to_pfn_list:
        lea_argument_addr = find_function_arg(pfn_call, "lea", "r8", 0)

        # Get stack and the stack operand offset
        current_func = idaapi.get_func(lea_argument_addr)
        stack_id = idc.GetFrame(current_func)
        stack_member_offset = idc.get_operand_value(lea_argument_addr, 1)

        struct_id = idaapi.get_struc_id("_WDF_IO_QUEUE_CONFIG")
        struct_size = idc.GetStrucSize(struct_id)

        # First check if we have already touch this function stack before
        if function_stack_erased(current_func):
            # need to take care of the already defined structs
            # If the arguments collide then this will fail
            pass
        else:
            delete_all_function_stack_members(current_func)
            print("Erased the stack members")

        idc.AddStrucMember(stack_id, "queue_config", stack_member_offset,
                           idc.FF_BYTE | idc.FF_DATA, -1, struct_size)
        idc.SetMemberType(stack_id, stack_member_offset,
                          idc.FF_STRU | idc.FF_DATA, struct_id, 1)
        print("IOQueue Creation at: " + hex(pfn_call))
예제 #22
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
예제 #23
0
 def setStrucPntr(self, sid, ofs, name, tp=None):
     vnm = idc.GetMemberName(sid, ofs)
     if not vnm or vnm in (idc.BADADDR, -1):
         idc.AddStrucMember(sid, name, ofs, idc.FF_QWRD, -1, 8)
         vnm = name
     if vnm != name:
         idc.SetMemberName(sid, ofs, name)
     sz = idc.GetMemberSize(sid, ofs)
     if sz != 8:
         idc.SetMemberType(sid, ofs, idc.FF_QWRD, -1, 1)
     mid = idc.GetMemberId(sid, ofs)
     t = idc.GetType(mid) or ''
     if tp and t.replace(' ', '') != tp.replace(' ', ''):
         idc.SetType(mid, tp + ';')
예제 #24
0
def new_struct(name, nb_field, field_size, is_union=False):
    type_by_size = {
        1: idc.FF_BYTE,
        2: idc.FF_WORD,
        4: idc.FF_DWRD,
        8: idc.FF_QWRD
    }
    if field_size not in type_by_size:
        raise ValueError("field size muste be {0}".format(list(type_by_size)))
    sid = idc.AddStrucEx(-1, name, is_union)
    if sid == -1:  # handle if name is already taken ?
        raise ValueError('bad name <{0}> for struct name'.format(name))
    for i in range(nb_field):
        idc.AddStrucMember(sid, 'field_{0}'.format(i), i * field_size,
                           idc.FF_DATA | type_by_size[field_size], -1,
                           field_size)
    return sid
예제 #25
0
    def makeStructFromHits(self, count, startHitIdx, endHitIdx):
        structName = 'sc%d' % count
        logger.debug("Making struct %d:", count)

        if using_ida7api:
            structId = idc.add_struc(0xffffffff, structName, 0)
        else:
            structId = idc.AddStrucEx(0xffffffff, structName, 0)
        if structId == 0xffffffff:
            raise ValueError("Struct %s already exists!" % structName)
        subRange = self.hits[startHitIdx:endHitIdx]
        for i in range(len(subRange)):
            hit = subRange[i]
            logger.debug("%02x: %08x: %08x %s" , i*self.ptrSize, hit.ea, hit.symHash.hashVal, hit.symHash.symbolName)
            if using_ida7api:
                idc.add_struc_member(structId, str(hit.symHash.symbolName), i*self.ptrSize, idc.FF_DATA|idc.FF_DWORD, -1, 4)
            else:
                idc.AddStrucMember(structId, str(hit.symHash.symbolName), i*self.ptrSize, idc.FF_DATA|idc.FF_DWRD, -1, 4)
예제 #26
0
    def make_struc(self, object_version, address):
        name = object_version.get_name()
        object_id = object_version.get_id()
        size = object_version.get_size()

        struc_id = idc.GetStrucIdByName(name)
        if struc_id == idc.BADADDR:
            try:
                is_union = object_version.get_object_flags()
            except KeyError:
                is_union = 0

            struc_id = idc.AddStrucEx(0, name, is_union)
            # add a dummy field.
            # This is necessary to avoid an error is idc.SetType(struc*) is used on another struc
            # member
            # TODO not for empty strucs
            if is_union:
                idc.AddStrucMember(struc_id, "yaco_filler", 0, idc.FF_BYTE, 0,
                                   1)

        else:

            is_union = idc.IsUnion(struc_id)
        #             if(is_union):
        #                 pass
        #             else:
        #                 self.clear_struc_fields(struc_id, object_version['xrefs'], is_union)

        if not is_union or is_union == 0:
            self.clear_struc_fields(
                struc_id, size,
                object_version.get_xrefed_id_map().iterkeys(), False)
        else:
            self.union_ids.add(struc_id)

        if DEBUG_EXPORTER:
            logger.debug(
                "adding struc id %s : '0x%.016X' (%s)" %
                (self.hash_provider.hash_to_string(object_id), struc_id, name))
        self.struc_ids[object_id] = struc_id
        _yatools_ida_exporter.set_struct_id(object_id, struc_id)

        self.hash_provider.put_hash_struc_or_enum(struc_id, object_id)
예제 #27
0
def create_vtable_struct(class_name, functions):
    struct_name = 'vtable_' + class_name
    sid = idc.GetStrucIdByName(struct_name)
    if sid != BADADDR:
        print("vtable already exists for " + class_name)
        return 0

    sid = idc.AddStrucEx(-1, struct_name, 0)
    idc.Til2Idb(-1, struct_name)

    offset = 0
    for fn in functions:
        func_name = fn[0]
        func_name = func_name.replace('~', 'destr_')
        func_type = fn[1]

        idc.AddStrucMember(sid, func_name, -1, idc.FF_QWRD, -1, 8)
        if func_type != '':
            if func_type.find("__cdecl(") > -1:
                func_type = func_type.replace("__cdecl",
                                              "(__cdecl *%s)" % func_name)
            elif func_type.find("__stdcall(") > -1:
                func_type = func_type.replace("__stdcall",
                                              "(__stdcall *%s)" % func_name)
            elif func_type.find("__fastcall(") > -1:
                func_type = func_type.replace("__fastcall",
                                              "(__fastcall *%s)" % func_name)
            elif func_type.find("__thiscall(") > -1:
                func_type = func_type.replace("__thiscall",
                                              "(__thiscall *%s)" % func_name)
            elif func_type.find("__usercall(") > -1:
                func_type = func_type.replace("__usercall",
                                              "(__usercall *%s)" % func_name)
            elif func_type.find("__userpurge(") > -1:
                func_type = func_type.replace("__userpurge",
                                              "(__userpurge *%s)" % func_name)

            SetType(GetMemberId(sid, offset), func_type)
            # MakeComm(GetMemberId(sid, offset), func_name)
            # "__int64 (__fastcall *)(ClassName *this)");
        offset += 8
        print(fn)

    return 1
예제 #28
0
def makeStruct(strname=""):
    '''
    Función para crear la estructura de Gustavo en IDA con idc.

    @param strname: nombre de la estructura

    @return: 0-todo bien, -1-caca
    '''
    sid = idc.GetStrucIdByName(strname)
    if sid == idc.BADADDR:
        sid = idc.AddStrucEx(-1, strname, 0)
    else:
        print "[-] Error. Structure %s already exists." % strname
        return -1
    print idc.AddStrucMember(sid, "instructionType", -1, idc.FF_BYTE, -1, 1)
    print idc.AddStrucMember(sid, "hashSha", -1, idc.FF_BYTE, -1, 20)
    print idc.AddStrucMember(sid, "instructionSize", -1, idc.FF_BYTE, -1, 1)
    print idc.AddStrucMember(sid, "branchHash", -1, idc.FF_BYTE, -1, 20)
    print idc.AddStrucMember(sid, "nextHash", -1, idc.FF_BYTE, -1, 20)
    print idc.AddStrucMember(sid, "salt", -1, idc.FF_DWRD, -1, 4)

    return 0
예제 #29
0
def add_struct_member(sid, name, offset, size):
    failure = idc.AddStrucMember(sid, name, offset, size_to_flags(size), -1,
                                 size)

    if failure:
        raise struct_member_error(failure, sid, name, offset, size)
예제 #30
0
    def make_struc_member(self,
                          object_version,
                          address,
                          member_type=ya.OBJECT_TYPE_STRUCT_MEMBER):
        struc_object_id = object_version.get_parent_object_id()

        struc_id = 0
        try:
            struc_id = self.struc_ids[struc_object_id]
        except:
            return
        is_union = struc_id in self.union_ids

        offset = address

        if is_union:
            last_offset = idc.GetLastMember(struc_id)
            if last_offset == idc.BADADDR:
                last_offset = -1
            if last_offset < offset:
                for i in xrange(last_offset + 1, offset + 1):
                    idc.AddStrucMember(struc_id, "yaco_filler_%d" % i, 0,
                                       idc.FF_BYTE | idc.FF_DATA, -1, 1)
                    # ensure that 'offset' fields are present

        member_size = object_version.get_size()
        member_name = object_version.get_name()

        flags = object_version.get_object_flags()
        if idc.isStruct(flags):
            # if the sub field is a struct, it must have a single Xref field with the struct object id
            try:
                sub_struc_object_id = object_version.getXRefIdsAt(0, 0)[0]
                sub_struc_id = self.struc_ids[sub_struc_object_id]

                #                 logger.debug("%20s: adding sub member at offset 0x%08X,
                #                               size=0x%08X (sub=0x%.016X, size=0x%08X) with name %s" %
                #                             (
                #                                 idc.GetStrucName(struc_id), offset, member_size, sub_struc_id,
                #                                               idc.GetStrucSize(sub_struc_id), object_version.get_name()
                #                             ))

                sub_struc_size = idc.GetStrucSize(sub_struc_id)
                if sub_struc_size == 0:
                    logger.error(
                        "%20s: adding sub member at offset 0x%08X, size=0x%08X "
                        "(sub=0x%.016X, size=0x%08X) with name %s : sub struc size is ZERO"
                        % (idc.GetStrucName(struc_id), offset, member_size,
                           sub_struc_id, idc.GetStrucSize(sub_struc_id),
                           object_version.get_name()))

                else:
                    nitems = member_size / sub_struc_size

                    YaToolIDATools.SetStrucmember(struc_id, member_name,
                                                  offset, flags, sub_struc_id,
                                                  nitems)

            except KeyError:
                logger.error(
                    "Error while looking for sub struc in struc %s, offset 0x%08X (field name='%s')"
                    % (self.hash_provider.hash_to_string(struc_object_id),
                       offset, object_version.get_name()))
                traceback.print_exc()
        elif idc.isEnum0(flags):
            # an enum is applied here
            try:
                sub_enum_object_id = object_version.getXRefIdsAt(0, 0)[0]
                sub_enum_id = self.enum_ids[sub_enum_object_id]

                name_ok = idc.SetMemberName(struc_id, offset, member_name)
                if name_ok is not True:
                    logger.debug(
                        "Error while setting member name (enum) : "
                        "(struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d, tid=0x%016X"
                        % (name_ok, idc.GetStrucName(struc_id), member_name,
                           offset, flags, member_size, sub_struc_id))
                else:
                    sub_enum_size = idc.GetEnumWidth(sub_enum_id)
                    if sub_enum_size == 0:
                        sub_enum_size = member_size

                    nitems = member_size / sub_enum_size
                    ret = idc.SetMemberType(struc_id, offset, flags,
                                            sub_enum_id, nitems)
                    if ret == 0:
                        logger.debug(
                            "Error while setting member type (enum) : "
                            "(struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d, tid=0x%016X"
                            % (ret, idc.GetStrucName(struc_id), member_name,
                               offset, flags, member_size, sub_struc_id))

            except KeyError:
                logger.error(
                    "Error while looking for sub enum in struc %s, offset 0x%08X (field name='%s')"
                    % (struc_object_id, offset, member_name))
                traceback.print_exc()

        else:
            #             logger.debug("%20s: adding member at offset 0x%08X, size=0x%08X with name %s" %
            #                         (
            #                         idc.GetStrucName(struc_id), offset, member_size, object_version.get_name()
            #                         ))
            tid = -1
            if idc.isASCII(flags):
                logger.debug(
                    "object: %s : %s" % (self.hash_provider.hash_to_string(
                        object_version.get_id()), object_version.get_name()))
                try:
                    tid = object_version.get_string_type()
                except KeyError:
                    tid = idc.ASCSTR_C

            name_ok = idc.SetMemberName(struc_id, offset, member_name)
            if name_ok is not True:
                logger.debug(
                    "Error while setting member name :" +
                    " (struc_id=0x%08X, struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d)"
                    % (struc_id, idc.GetStrucName(struc_id), member_name,
                       offset, flags, member_size))
            else:
                item_size = YaToolIDATools.get_field_size(flags, tid)
                nitems = member_size / item_size
                # IDA BUG : 4-byte chars are stored as 2 double words, thus me must
                # multiply nitem by 2!
                ret = idc.SetMemberType(struc_id, offset, flags, tid, nitems)
                if ret == 0:
                    logger.debug(
                        "Error while setting member type :" +
                        " (struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d)"
                        % (idc.GetStrucName(struc_id), member_name, offset,
                           flags, member_size))

        try:
            repeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(True))
            idc.SetMemberComment(struc_id, offset, repeatable_headercomment, 1)
        except KeyError:
            pass

        try:
            nonrepeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(False))
            idc.SetMemberComment(struc_id, offset, nonrepeatable_headercomment,
                                 0)
        except KeyError:
            pass

        member_id = idc.GetMemberId(struc_id, offset)

        self.set_struct_member_type(object_version, member_id)
        if object_version.get_type() == ya.OBJECT_TYPE_STRUCT_MEMBER:
            self.strucmember_ids[object_version.get_id()] = member_id