Beispiel #1
0
 def makeInterface(self, offset):
     idc.SetType(offset, "interfaceType")
     ifaceid = ida_struct.get_struc_id("interfaceType")
     meth_offs = idc.get_member_offset(ifaceid, "methods")
     slice_id = ida_struct.get_struc_id("slice")
     size_off = idc.get_member_offset(slice_id, "len")
     size = self.stepper.ptr(offset + meth_offs + size_off)
     if size != 0:
         addr = self.getPtr(slice_id, offset + meth_offs, "data")
         idc.SetType(addr, "imethod")
         sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod"))
         self.make_arr(addr, size, sz, "imethod")
         names = self.processIMethods(addr, size)
         # For now only for go1.7
         if names is None:
             return
         name = self.getName(offset)
         while name[0] == "*":
             name = name[1:]
         name = Utils.relaxName(name)
         name = "user_interface_" + name
         # TODO: this is for go1.7 need additional check for other versions
         fields = [("inter", "void *"), ("type", "void *"), ("link", "void *"), ("bad", "__int32"),
                   ("unused", "__int32")]
         for i in names:
             fields.append((i, "void *"))
         itype = [(name, fields)]
         self.settings.structCreator.createTypes(itype)
Beispiel #2
0
 def make_arr(self, addr, arr_size, struc_size, type):
     res = idc.make_array(addr, arr_size)
     if res == False:
         ida_bytes.del_items(addr, arr_size * struc_size,
                             ida_bytes.DELIT_SIMPLE)
         idc.SetType(addr, type)
         idc.make_array(addr, arr_size)
Beispiel #3
0
def _get_function_tif_with_hex_rays(offset):
    """
    Attempt to get the tinfo_t object of a function using the Hex-Rays decompiler plugin.

    :param offset: Offset of function.
    :raises: RuntimeError on failure.
    :returns: tinfo_t object on success.
    """
    tif = ida_typeinf.tinfo_t()

    # This requires Hexrays decompiler, load it and make sure it's available before continuing.
    if not idaapi.init_hexrays_plugin():
        idc.load_and_run_plugin("hexrays", 0) or idc.load_and_run_plugin("hexx64", 0)
    if not idaapi.init_hexrays_plugin():
        raise RuntimeError("Unable to load Hexrays decompiler.")

    # Pull type from decompiled C code.
    try:
        decompiled = idaapi.decompile(offset)
    except idaapi.DecompilationFailure:
        decompiled = None
    if decompiled is None:
        raise RuntimeError("Cannot decompile function at 0x{:X}".format(offset))
    decompiled.get_func_type(tif)

    # Save type for next time.
    fmt = decompiled.print_dcl()
    fmt = "".join(c for c in fmt if c in string.printable and c not in ("\t", "!"))
    set_type_result = idc.SetType(offset, "{};".format(fmt))
    if not set_type_result:
        logger.warning("Failed to SetType for function at 0x{:X} with decompiler type {!r}".format(offset, fmt))

    return tif
Beispiel #4
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.add_struc_member(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.add_struc_member(sid, use_name, -1, i1, i2, i3)
         if new_type is not None:
             offset = idc.get_member_offset(sid, use_name)
             # print "Setting %s as %s" % (i[0], new_type)
             idc.SetType(idc.get_member_id(sid, offset), new_type)
Beispiel #5
0
    def handle_offset(self, offset):
        #Check if we already parse this
        if offset in self.type_addr:
            return
        print ("Processing: %x" % offset)
        self.type_addr.append(offset)

        #Set type and get name
        idc.SetType(offset, "type")
        name = self.getName(offset)
        idc.set_cmt(offset, name, 0)

        #get kind name
        kind_name = self.getKindEnumName(offset)
        print (kind_name)
        if name[0] == "*" and kind_name != "PTR":
            name = name[1:]
        name = Utils.relaxName(name)
        Utils.rename(offset, name)
        self.betterTypePlease(offset)
        sid = ida_struct.get_struc_id("type")
        addr = self.getPtrToThis(sid, offset)
        if addr != 0:
            addr = self.getOffset(addr)
            self.handle_offset(addr)
        return
        if kind_name != "FUNC":
            self.processUncommon(sid, offset)
Beispiel #6
0
 def yatest_create_struct_in_stack_vars_with_renaming(self):
     """
     test creation of struct from stack vars
     used to find a bug (structure is correctly applied on var if renamed)
     """
     # create structure
     ident, sida = self.get_function_sid_without_del(
         True, local_size=complex_struc3_size, count_from_first_var=True)
     self.assertNotEqual(sida, -1)
     sidb = idc.AddStrucEx(0, 'create_struct_in_stack_vars_with_renaming',
                           0)
     self.assertNotEqual(sidb, -1)
     size = self.create_complex2(sidb, complex_struc3)
     self.assertEqual(complex_struc3_size, size)
     # set first var prototype
     offset = idc.GetFirstMember(sida)
     member_id = idc.GetMemberId(sida, offset)
     self.assertNotEqual(member_id, -1)
     self.assertTrue(
         idc.SetType(member_id,
                     "create_struct_in_stack_vars_with_renaming* x;"))
     self.assertEqual("create_struct_in_stack_vars_with_renaming *",
                      idc.GetType(idc.GetMemberId(sida, offset)))
     idc.SetMemberName(sida, offset, "var1")
     yaunit.save("create_struct_in_stack_vars_with_renaming", sida)
     yaunit.save("create_struct_in_stack_vars_with_renaming_offset", offset)
Beispiel #7
0
 def makeArrType(self, offset):
     idc.SetType(offset, "arrayType")
     sid = ida_struct.get_struc_id("arrayType")
     addr = self.getPtr(sid, offset, "elem")
     self.handle_offset(addr)
     addr = self.getPtr(sid, offset, "slice")
     self.handle_offset(addr)
Beispiel #8
0
 def load(infos):
     idc.set_inf_attr(idc.INF_COMPILER, 6)
     for info in infos:
         type = info.get('type', None)
         ida_name.set_name(info['start'], info['name'])
         if type:
             idc.SetType(info['start'], type)
Beispiel #9
0
 def make_names(self):
     '''
     make names in idb
     '''
     EFI_GUID = 'EFI_GUID *'
     EFI_GUID_ID = idc.get_struc_id('EFI_GUID')
     self.get_boot_services()
     self.get_protocols()
     self.get_prot_names()
     data = self.Protocols['all']
     empty = True
     for element in data:
         try:
             idc.SetType(element['address'], EFI_GUID)
             self.apply_struct(element['address'], 16, EFI_GUID_ID)
             name = element['protocol_name'] + '_' + \
                 '{addr:#x}'.format(addr=element['address'])
             idc.set_name(element['address'], name)
             empty = False
             print('[ {ea} ] {name}'.format(
                 ea='{addr:#010x}'.format(addr=element['address']),
                 name=name))
         except:
             continue
     if empty:
         print(' * list is empty')
Beispiel #10
0
 def makeArrType(self, offset):
     idc.SetType(offset, "arrayType")
     sid = idc.GetStrucIdByName("arrayType")
     addr = self.getPtr(sid, offset, "elem")
     self.handle_offset(addr)
     addr = self.getPtr(sid, offset, "slice")
     self.handle_offset(addr)
Beispiel #11
0
 def apply(self, data):
     # TODO: deserialize type info and apply it
     prototype = data['type_info']
     if idc.SetType(self.offset, prototype) is None:
         log('annotation_prototype').warn(
             "Setting prototype failed at %s with "
             "%s", self.offset, data)
Beispiel #12
0
def _get_function_tif_with_guess_type(offset):
    """
    Attempt to get the tinfo_t object of a function using the "guess_type" function.

    :param offset: Offset of function.
    :raises: RuntimeError on failure.
    :returns: tinfo_t object on success.
    """
    tif = ida_typeinf.tinfo_t()

    guessed_type = idc.guess_type(offset)
    if guessed_type is None:
        raise RuntimeError(
            "Failed to guess function type for offset 0x{:X}".format(offset))

    func_name = idc.get_func_name(offset)
    if func_name is None:
        raise RuntimeError(
            "Failed to get function name for offset 0x{:X}".format(offset))

    # Documentation states the type must be ';' terminated, also the function name must be inserted
    guessed_type = re.sub(r"\(", " {}(".format(func_name),
                          "{};".format(guessed_type))
    set_type_result = idc.SetType(offset, guessed_type)
    if not set_type_result:
        logger.warning(
            "Failed to SetType for function at 0x{:X} with guessed type {!r}".
            format(offset, guessed_type))
    # Try one more time to get the tinfo_t object
    if not ida_nalt.get_tinfo(tif, offset):
        raise RuntimeError(
            "Failed to obtain tinfo_t object for offset 0x{:X}".format(offset))

    return tif
Beispiel #13
0
 def getName(self, offset):
     sid = idc.GetStrucIdByName("type")
     string_addr = offset + idc.GetMemberOffset(sid, "string")
     ptr = self.stepper.ptr(string_addr)
     idc.SetType(ptr, "string")
     name = self.stepper.ptr(ptr)
     return idc.GetString(name)
Beispiel #14
0
 def getName(self, offset):
     sid = ida_struct.get_struc_id("type")
     string_addr = offset + idc.get_member_offset(sid, "string")
     ptr = self.stepper.ptr(string_addr)
     idc.SetType(ptr, "string")
     name = self.stepper.ptr(ptr)
     return idc.GetString(name)
Beispiel #15
0
def _get_tif_with_guess_type(address: int) -> Optional[ida_typeinf.tinfo_t]:
    """
    Attempt to get the tinfo_t object for the function using the "guess_type" function.

    :raises: RuntimeError on failure.
    :returns: tinfo_t object on success.
    """
    guessed_type = idc.guess_type(address)
    if guessed_type is None:
        return None

    func_name = idc.get_func_name(address)
    if func_name is None:
        return None

    # Documentation states the type must be ';' terminated, also the function name must be inserted
    guessed_type = re.sub(r"\(", f" {func_name}(", f"{guessed_type};")
    set_type_result = idc.SetType(address, guessed_type)
    if not set_type_result:
        logger.warning(
            f"Failed to SetType for function at 0x{address:X} with guessed type {guessed_type!r}"
        )

    tif = ida_typeinf.tinfo_t()
    if not ida_nalt.get_tinfo(tif, address):
        return None
    return tif
Beispiel #16
0
 def parseFuncType(self, offset):
     return
     sid = ida_struct.get_struc_id("funcType")
     in_size = idc.Word(offset + idc.get_member_offset(sid, "incount"))
     out_size = idc.Word(offset + idc.get_member_offset(sid, "outcount"))
     sz = ida_struct.get_struc_size(sid)
     for i in xrange(in_size + out_size):
         idc.SetType(offset + sz + i * self.stepper.size, "type *")
Beispiel #17
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)
Beispiel #18
0
 def parseFuncType(self, offset):
     return
     sid = idc.GetStrucIdByName("funcType")
     in_size = idc.Word(offset + idc.GetMemberOffset(sid, "incount"))
     out_size = idc.Word(offset + idc.GetMemberOffset(sid, "outcount"))
     sz = idc.GetStrucSize(sid)
     for i in xrange(in_size + out_size):
         idc.SetType(offset + sz + i * self.stepper.size, "type *")
Beispiel #19
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))
Beispiel #20
0
def set_type_single(address, type_):
    if isinstance(type_, fa_types.FaStruct) or \
            isinstance(type_, fa_types.FaEnum):
        type_str = type_.get_name()
    else:
        type_str = type_

    idc.SetType(address, type_str)
    ida_auto.auto_wait()
Beispiel #21
0
 def makeMap(self, offset):
     idc.SetType(offset, "mapType")
     sid = ida_struct.get_struc_id("mapType")
     addr = self.getPtr(sid, offset, "key")
     self.handle_offset(addr)
     addr = self.getPtr(sid, offset, "elem")
     self.handle_offset(addr)
     addr = self.getPtr(sid, offset, "bucket")
     self.handle_offset(addr)
Beispiel #22
0
    def makeStructType(self, offset):
        idc.SetType(offset, "structType")
        sid = idc.GetStrucIdByName("structType")
        slice_id = idc.GetStrucIdByName("slice")
        offset_elem = idc.GetMemberOffset(sid, "fields")
        inner_offset = idc.GetMemberOffset(slice_id, "data")
        addr = self.stepper.ptr(offset_elem + offset + inner_offset)

        inner_offset = idc.GetMemberOffset(slice_id, "len")
        size = self.stepper.ptr(offset + offset_elem + inner_offset)
        if size == 0:
            return
        idc.SetType(addr, "structField")
        sz = idc.GetStrucSize(idc.GetStrucIdByName("structField"))
        self.make_arr(addr, size, sz, "structField")
        sid_type = idc.GetStrucIdByName("type")
        size_new_struct = self.getPtr(sid_type, offset, "size")
        for i in xrange(size):
            self.processStructField(addr, i * sz)
Beispiel #23
0
def make_strings_const():
    s = idautils.Strings(False)
    s.setup(strtypes=idautils.Strings.STR_UNICODE | idautils.Strings.STR_C)

    for v in s:
        gt = idc.GetType(v.ea)
        if not gt:
            gt = idc.GuessType(v.ea)
        if gt and not gt.startswith("const "):
            idc.SetType(v.ea, "const " + gt)
Beispiel #24
0
 def processStructField(self, addr, index):
     offset = addr + index
     sid = ida_struct.get_struc_id("structField")
     ptr = self.getPtr(sid, offset, "Name")
     if ptr != 0:
         idc.SetType(ptr, "string")
         fieldName = idc.GetString(self.stepper.ptr(ptr))
         Utils.rename(ptr, fieldName)
     ptr = self.getPtr(sid, offset, "typ")
     self.handle_offset(ptr)    
Beispiel #25
0
    def set_function_type(name, TypeString, print_ERROR=False):
        ea = idaapi.get_name_ea(-1, str(name))
        if ea == idaapi.BADADDR:
            return

        ok = idc.SetType(ea, str(TypeString))
        if not ok and print_ERROR:
            print(
                "Could not add function type {name} at {ea:#x} : {TypeString}".
                format(name=name, ea=ea, TypeString=TypeString))
Beispiel #26
0
    def set_global_data(name, TypeString):
        ea = idaapi.get_name_ea(-1, str(name))

        if ea == idaapi.BADADDR:
            return

        ok = idc.SetType(ea, str(TypeString))
        if not ok:
            print("Could not add global type {name} at {ea:#x} : {TypeString}".
                  format(name=name, ea=ea, TypeString=TypeString))
Beispiel #27
0
 def set_types(self):
     '''
     handle (EFI_BOOT_SERVICES *) type
     and (EFI_SYSTEM_TABLE *) for x64 images
     '''
     RAX = 0
     O_REG = 1
     O_MEM = 2
     EFI_BOOT_SERVICES = 'EFI_BOOT_SERVICES *'
     EFI_SYSTEM_TABLE = 'EFI_SYSTEM_TABLE *'
     empty = True
     for service in self.gBServices:
         for address in self.gBServices[service]:
             ea = address
             num_of_attempts = 10
             for _ in range(num_of_attempts):
                 ea = idc.prev_head(ea)
                 if (idc.print_insn_mnem(ea) == 'mov'
                         and idc.get_operand_type(ea, 1) == O_MEM):
                     if (idc.get_operand_type(ea, 0) == O_REG
                             and idc.get_operand_value(ea, 0) == RAX):
                         gvar = idc.get_operand_value(ea, 1)
                         gvar_type = idc.get_type(gvar)
                         '''
                         if (EFI_SYSTEM_TABLE *)
                         '''
                         if ((gvar_type != 'EFI_SYSTEM_TABLE *') and \
                             (idc.print_operand(address, 0).find('rax') == 1)
                         ):
                             if self._find_est(gvar, ea, address):
                                 print(
                                     '[ {0} ] Type ({type}) successfully applied'
                                     .format(
                                         '{addr:#010x}'.format(addr=gvar),
                                         type=EFI_SYSTEM_TABLE))
                                 empty = False
                                 break
                         '''
                         otherwise it (EFI_BOOT_SERVICES *)
                         '''
                         if (gvar_type != 'EFI_BOOT_SERVICES *'
                                 and gvar_type != 'EFI_SYSTEM_TABLE *'):
                             if idc.SetType(gvar, EFI_BOOT_SERVICES):
                                 empty = False
                                 idc.set_name(
                                     gvar,
                                     'gBs_{addr:#x}'.format(addr=gvar))
                                 print(
                                     '[ {0} ] Type ({type}) successfully applied'
                                     .format(
                                         '{addr:#010x}'.format(addr=gvar),
                                         type=EFI_BOOT_SERVICES))
                         break
     if empty:
         print(' * list is empty')
Beispiel #28
0
 def makeMap(self, offset):
     idc.SetType(offset, "mapType")
     sid = idc.GetStrucIdByName("mapType")
     addr = self.getPtr(sid, offset, "key")
     self.handle_offset(addr)
     addr = self.getPtr(sid, offset, "elem")
     self.handle_offset(addr)
     addr = self.getPtr(sid, offset, "bucket")
     self.handle_offset(addr)
     addr = self.getPtr(sid, offset, "hmap")
     self.handle_offset(addr)
Beispiel #29
0
 def get_data_guids(self):
     """rename GUIDs in idb"""
     EFI_GUID = "EFI_GUID"
     EFI_GUID_ID = idc.get_struc_id("EFI_GUID")
     segments = [".text", ".data"]
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.get_segm_name(seg) == segment:
                 seg_start = idc.get_segm_start(seg)
                 seg_end = idc.get_segm_end(seg)
                 break
         ea = seg_start
         while ea <= seg_end - 15:
             prot_name = str()
             if "unk" in idc.get_name(ea, ida_name.GN_VISIBLE):
                 find = False
                 cur_guid = list()
                 cur_guid.append(idc.get_wide_dword(ea))
                 cur_guid.append(idc.get_wide_word(ea + 4))
                 cur_guid.append(idc.get_wide_word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.get_wide_byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for guid_place in [
                     "ami_guids",
                     "asrock_guids",
                     "dell_guids",
                     "edk_guids",
                     "edk2_guids",
                     "lenovo_guids",
                 ]:
                     for name in self.Protocols[guid_place]:
                         if self.Protocols[guid_place][name] == cur_guid:
                             prot_name = f"{name}_{ea:016X}"
                             record = {
                                 "address": ea,
                                 "service": "unknown",
                                 "guid": cur_guid,
                                 "protocol_name": name,
                                 "protocol_place": guid_place,
                             }
                             find = True
                             break
                         if find:
                             break
                 if find and (idc.get_name(ea, ida_name.GN_VISIBLE) != prot_name):
                     idc.SetType(ea, EFI_GUID)
                     self.apply_struct(ea, 16, EFI_GUID_ID)
                     idc.set_name(ea, prot_name)
                     self.Protocols["data"].append(record)
             ea += 1
Beispiel #30
0
 def get_data_guids(self):
     '''
     rename GUIDs in idb
     '''
     EFI_GUID = 'EFI_GUID *'
     EFI_GUID_ID = idc.get_struc_id('EFI_GUID')
     segments = ['.text', '.data']
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.get_segm_name(seg) == segment:
                 seg_start = idc.get_segm_start(seg)
                 seg_end = idc.get_segm_end(seg)
                 break
         ea = seg_start
         while (ea <= seg_end - 15):
             prot_name = ''
             if idc.get_name(ea, ida_name.GN_VISIBLE).find('unk_') != -1:
                 find = False
                 cur_guid = []
                 cur_guid.append(idc.get_wide_dword(ea))
                 cur_guid.append(idc.get_wide_word(ea + 4))
                 cur_guid.append(idc.get_wide_word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.get_wide_byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for guid_place in [
                         'ami_guids', 'asrock_guids', 'dell_guids',
                         'edk_guids', 'edk2_guids', 'lenovo_guids'
                 ]:
                     for name in self.Protocols[guid_place]:
                         if self.Protocols[guid_place][name] == cur_guid:
                             prot_name = name + '_' + \
                                 '{addr:#x}'.format(addr=ea)
                             record = {
                                 'address': ea,
                                 'service': 'unknown',
                                 'guid': cur_guid,
                                 'protocol_name': name,
                                 'protocol_place': guid_place
                             }
                             find = True
                             break
                         if find:
                             break
                 if find and (idc.get_name(ea, ida_name.GN_VISIBLE) !=
                              prot_name):
                     idc.SetType(ea, EFI_GUID)
                     self.apply_struct(ea, 16, EFI_GUID_ID)
                     idc.set_name(ea, prot_name)
                     self.Protocols['data'].append(record)
             ea += 1