Exemple #1
0
    def load_crash_report(self, log_file):
        with open(log_file, 'r') as f:
            log = f.read()

        traceback = process_stack_trace(log)

        self.log_txt.setText(log)

        self.stack_trace_table.clear()
        self.stack_trace_table.setHorizontalHeaderLabels(
            ["Address", "Function"])
        self.stack_trace_table.setRowCount(len(traceback))
        for i, addr in enumerate(traceback):
            func_name = idc.GetFunctionName(addr)
            func_name_demangled = idc.Demangle(
                func_name, idc.GetLongPrm(idc.INF_SHORT_DN))
            if func_name_demangled is not None:
                func_name = func_name_demangled
            self.stack_trace_table.setRowHeight(i, 20)
            self.stack_trace_table.setItem(
                i, 0, QtWidgets.QTableWidgetItem("0x{:016x}".format(addr)))
            self.stack_trace_table.setItem(
                i, 1, QtWidgets.QTableWidgetItem(func_name))

        self.log_txt.setEnabled(True)
        self.stack_trace_table.setEnabled(True)
Exemple #2
0
def kernelcache_find_virtual_method_overrides(classname=None, method=None):
    import idc
    import idaapi
    import ida_kernelcache as kc

    # Define the form to ask for the arguments.
    class MyForm(idaapi.Form):
        def __init__(self):
            swidth = 40
            idaapi.Form.__init__(
                self, r"""STARTITEM 0
Find virtual method overrides

<#The class#Class :{classname}>
<#The virtual method#Method:{method}>""", {
                    'classname':
                    idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT,
                                            swidth=swidth),
                    'method':
                    idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT,
                                            swidth=swidth),
                })

        def OnFormChange(self, fid):
            return 1

    kc.collect_class_info()

    if any(arg is None for arg in (classname, method)):
        f = MyForm()
        f.Compile()
        f.classname.value = classname or ''
        f.method.value = method or ''
        ok = f.Execute()
        if ok != 1:
            print 'Cancelled'
            return False
        classname = f.classname.value
        method = f.method.value
        f.Free()

    if classname not in kc.class_info:
        print 'Not a valid class: {}'.format(classname)
        return False

    print 'Subclasses of {} that override {}:'.format(classname, method)
    baseinfo = kc.class_info[classname]
    found = False
    for classinfo in baseinfo.descendants():
        for _, override, _ in kc.vtable.class_vtable_overrides(
                classinfo, superinfo=baseinfo, methods=True):
            name = idc.NameEx(idc.BADADDR, override)
            demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
            name = demangled if demangled else name
            if method in name:
                print '{:#x}  {}'.format(override, classinfo.classname)
                found = True
    if not found:
        print 'No subclass of {} overrides {}'.format(classname, method)
    return found
def kernelcache_find_virtual_method_overrides(classname=None, method=None):
    import idc
    import ida_kernelcache as kc

    kc.collect_class_info()

    if not classname:
        classname = idc.AskStr('IOUserClient', 'Enter class name')
    if classname not in kc.class_info:
        print 'Not a valid class: {}'.format(classname)
        return False

    if not method:
        method = idc.AskStr('externalMethod', 'Enter method name')

    print 'Subclasses of {} that override {}:'.format(classname, method)
    baseinfo = kc.class_info[classname]
    found = False
    for classinfo in baseinfo.descendants():
        for _, override, _ in kc.vtable.class_vtable_overrides(
                classinfo, superinfo=baseinfo, methods=True):
            name = idc.NameEx(idc.BADADDR, override)
            demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
            name = demangled if demangled else name
            if method in name:
                print '{:#x}  {}'.format(override, classinfo.classname)
                found = True
    if not found:
        print 'No subclass of {} overrides {}'.format(classname, method)
    return found
Exemple #4
0
def _split_basic_block(start_ea, end_ea):
    """
    IDA Pro's ``idaapi.Flowchart`` does not consider function calls as basic
    block boundaries. This function takes an address range and splits the
    basic blocks found within that range so that function calls are considered
    basic block boundaries.
    """
    split_bbs = []
    func_name = idc.GetFunctionName(start_ea)
    demangled_name = idc.Demangle(func_name, idc.GetLongPrm(idc.INF_SHORT_DN))
    if demangled_name:
        func_name = demangled_name

    bb_start_addr = start_ea
    block = idautils.Heads(start_ea, end_ea)

    for inst in block:
        mnem = idc.GetMnem(inst)
        if mnem == 'call' and inst != end_ea:
            split_bbs.append(
                dict(start_addr=bb_start_addr,
                     end_addr=idc.NextHead(inst, end_ea + 1) - 1,
                     function=func_name))
            bb_start_addr = idc.NextHead(inst, end_ea + 1)

    if bb_start_addr < end_ea:
        split_bbs.append(
            dict(start_addr=bb_start_addr,
                 end_addr=end_ea - 1,
                 function=func_name))

    return split_bbs
Exemple #5
0
    def __get_functions(self):
        functions = list(idautils.Functions())
        for start_function in functions:
            tinfo = idc.GetTinfo(start_function)
            if tinfo is None:
                continue

            mangled_name = idc.GetFunctionName(start_function)

            demangled = {idc.INF_SHORT_DN: '', idc.INF_LONG_DN: ''}
            for record in demangled.iteritems():
                (type, value) = record
                demangled[type] = idc.Demangle(mangled_name,
                                               idc.GetLongPrm(type))

                ida_type, ida_fields = tinfo

            yield models_ida.IdaRawFunctions(
                start=start_function,
                end=idc.GetFunctionAttr(start_function, idc.FUNCATTR_END),
                ida_type=ida_type,
                ida_fields=ida_fields,
                mangled_name=mangled_name,
                short_name=demangled[idc.INF_SHORT_DN],
                long_name=demangled[idc.INF_LONG_DN])
Exemple #6
0
 def demangle(self, name):
     mask = idc.GetLongPrm(idc.INF_SHORT_DN)
     demangled = idc.Demangle(name, mask)
     if demangled is None:
         return name
     else:
         return demangled
Exemple #7
0
 def getFunctionName(self, ea):
     """Returns the name of the function to which ea belongs"""
     demangled_name = idc.Demangle(idc.GetFunctionName(ea),
                                   idc.GetLongPrm(idc.INF_SHORT_DN))
     if not demangled_name:
         return idc.GetFunctionName(ea)
     else:
         return demangled_name
Exemple #8
0
    def GetFuncName(self, ea, demangle=True):
        name = get_func_name(ea)
        demangled_name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))

        if demangled_name == None:
            return name
        else:
            return demangled_name
Exemple #9
0
def _demangle(name, short=True):
    dtype = idc.INF_LONG_DN
    if short:
        dtype = idc.INF_SHORT_DN
    tmp = idc.Demangle(name, idc.GetLongPrm(dtype))
    if tmp:
        name = tmp
    name = name.replace('__', '::')
    return name
Exemple #10
0
def vtable_symbol_get_class(symbol):
    """Get the class name for a vtable symbol."""
    try:
        demangled = idc.Demangle(symbol, idc.GetLongPrm(idc.INF_SHORT_DN))
        pre, post = demangled.split("`vtable for'", 1)
        assert pre == ''
        return post
    except:
        return None
Exemple #11
0
def demangle(name, strip_arg_types=False):
    def strip_args(name):
        if strip_arg_types is True:
            return name.split("(", 1)[0]
        else:
            return name

    demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_LONG_DN))
    if demangled is not None:
        return strip_args(demangled)

    # The names in RTTI are not mangled normally, so try prepending
    # the '_Z'
    demangled = idc.Demangle("_Z" + name, idc.GetLongPrm(idc.INF_LONG_DN))
    if demangled is not None:
        return strip_args(demangled)

    return strip_args(name)
Exemple #12
0
 def demangle_name(cls, name):
     '''Demangle name.'''
     tmp = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
     if tmp:
         name = tmp
     matches = re.match(r'^(.*?)\(.*?\)', name)
     if matches:
         name = matches.group(1)
     return name
Exemple #13
0
    def architecture(self):
        """Return the IDA guessed processor
        Ripped from Miasm2 / examples / ida / utils
        """

        processor_name = idc.GetLongPrm(idc.INF_PROCNAME)

        if processor_name in self.IDAarch2MiasmArch:
            name = self.IDAarch2MiasmArch[processor_name]

        elif processor_name == "metapc":

            # HACK: check 32/64 using INF_START_SP
            inf = idaapi.get_inf_structure()
            if inf.is_32bit():
                name = "x86_32"
            elif inf.is_64bit():
                name = "x86_64"
            elif idc.GetLongPrm(idc.INF_START_SP) == 0x80:
                name = "x86_16"
            else:
                raise ValueError('cannot guess 32/64 bit! (%x)' % max_size)
        elif processor_name == "ARM":
            # TODO ARM/thumb
            # hack for thumb: set armt = True in globals :/
            # set bigendiant = True is bigendian
            is_armt = globals().get('armt', False)
            is_bigendian = globals().get('bigendian', False)
            if is_armt:
                if is_bigendian:
                    name = "armtb"
                else:
                    name = "armtl"
            else:
                if is_bigendian:
                    name = "armb"
                else:
                    name = "arml"

        else:
            print repr(processor_name)
            raise ValueError("Unknown corresponding architecture")

        return name
Exemple #14
0
 def get_func_name(self, address):
     name = idc.Demangle(idaapi.get_func_name(address),
                         idc.GetLongPrm(idc.INF_LONG_DN))
     if name != None:
         name = re.sub(r'[A-Za-z0-9_]+::', r'', name)
         name = re.sub(r'^public: ', r'', name)
         name = re.sub(r'unsigned short const \*', r'const wchar_t *', name)
         name = re.sub(r'unsigned short \*', r'wchar_t *', name)
         return name
     else:
         return idaapi.get_func_name(address)
Exemple #15
0
    def _get_imported_names(self):
        '''Create and return a list of imported function names.'''

        tmp = []
        for _, imp_entries in self._build_imports().items():
            for imp_name in imp_entries:
                tmp_name = idc.Demangle(imp_name, idc.GetLongPrm(idc.INF_SHORT_DN))
                if tmp_name:
                    imp_name = tmp_name
                tmp.append(imp_name)
        return tmp
Exemple #16
0
def init_demangled_names(*args):
    """
    Creates dictionary of demangled names => address, that will be used further at double click on methods got from
    symbols.
    """
    demangled_names.clear()
    for address, name in idautils.Names():
        short_name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
        if short_name:
            demangled_names[short_name.split('(')
                            [0]] = address - idaapi.get_imagebase()
    print "[DEBUG] Demangled names have been initialized"
Exemple #17
0
def method_name(symbol):
    """Get the name of the C++ method from its symbol.

    If the symbol demangles to 'Class::method(args)', this function returns 'method'.
    """
    try:
        demangled = idc.Demangle(symbol, idc.GetLongPrm(idc.INF_SHORT_DN))
        func = demangled.split('::', 1)[1]
        base = func.split('(', 1)[0]
        return base or None
    except:
        return None
Exemple #18
0
def class_from_vtable_method_symbol(method_symbol):
    """Get the base class in a vtable method symbol.

    Extract the name of the base class from a canonical method symbol.
    """
    demangled = idc.Demangle(method_symbol, idc.GetLongPrm(idc.INF_SHORT_DN))
    if not demangled:
        return None
    classname = demangled.split('::', 1)[0]
    if classname == demangled:
        return None
    return classname
Exemple #19
0
def block_split(output_file, startEA, endEA):
    curName = GetFunctionName(startEA);
    dem = idc.Demangle(curName, idc.GetLongPrm(INF_SHORT_DN));
    if dem != None:
        curName = dem;
    
    first=startEA
    h = idautils.Heads(startEA, endEA)
    for i in h:
        mnem = idc.GetMnem(i)
        if mnem == "call" and i != endEA:
            first=idc.NextHead(i, endEA+1)
Exemple #20
0
def method_arguments_string(symbol):
    """Get the arguments string of the C++ method from its symbol.

    If the symbol demangles to 'Class::method(arg1, arg2)', this function returns 'arg1, arg2'.
    """
    try:
        demangled = idc.Demangle(symbol, idc.GetLongPrm(idc.INF_LONG_DN))
        func = demangled.split('::', 1)[1]
        args = func.split('(', 1)[1]
        args = args.rsplit(')', 1)[0].strip()
        return args
    except:
        return None
Exemple #21
0
 def imp_cb(self, ea, name, ord1):
     """Callback passed to idaapi.enum_import_name in buildImportDictionary().
     Sets the name of the PE segment in which the import table resides, and
     inserts current import in dictionary of imported APIS"""
     if self.firstImport:
         self.imports_segment_name = idaapi.get_segm_name(ea)
         self.firstImport = False
     demangled_name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
     if not demangled_name:
         self.import_dict[ea] = (name, self.curr_mod_name)
     else:
         self.import_dict[ea] = (demangled_name, self.curr_mod_name)
     return True
Exemple #22
0
    def getText(self, addy):
        #print "Fetching text for %08x" % addy
        color = idaapi.SCOLOR_STRING

        if addy == function.top(addy):
            name = idc.NameEx(addy, addy)
            try:
                name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
            except:
                pass
        else:
            name = idc.NameEx(addy, addy)

        if name:
            return idaapi.COLSTR(" %s " % name, color)
        else:
            return idaapi.COLSTR(" 0x%08x " % addy, color)
Exemple #23
0
def cls_split_block(fp, startEA, endEA):
    curName = GetFunctionName(startEA)
    dem = idc.Demangle(curName, idc.GetLongPrm(INF_SHORT_DN))
    if dem != None:
        curName = dem

    first = startEA
    h = idautils.Heads(startEA, endEA)
    for i in h:
        mnem = idc.GetMnem(i)
        if mnem == "call" and i != endEA:
            print >> fp, "%#010x %#010x %s" % (
                first, idc.NextHead(i, endEA + 1) - 1, curName)
            first = idc.NextHead(i, endEA + 1)

    if first < endEA:
        print >> fp, "%#010x %#010x %s" % (first, endEA - 1, curName)
def decrypt(argv, funcName):
    myEH = flare_emu.EmuHelper()
    print("decrypting...")
    mu = myEH.emulateRange(idc.get_name_ea_simple(funcName),
                           stack=[0, argv[0], argv[1]],
                           memAccessHook=mem_hook)
    decrypted_data = myEH.getEmuBytes(argv[0], argv[1])
    print('decrypted: {}'.format(decrypted_data))
    # make string in idb file
    if funcName == "DecryptAsciiStr":
        # make ascii str
        idc.MakeStr(argv[0], argv[0] + argv[1])
    if funcName == "DecryptUnicodeStr":
        # make unicode str
        old_type = idc.GetLongPrm(INF_STRTYPE)
        idc.SetLongPrm(idc.INF_STRTYPE, idc.ASCSTR_UNICODE)
        idc.MakeStr(argv[0], argv[0] + (argv[1] * 2))
        idc.SetLongPrm(idc.INF_STRTYPE, old_type)
    return decrypted_data
Exemple #25
0
def get_function_name(ea):
    """
        Get the real function name
        """
    # Try to demangle
    funcName = idc.Demangle(idc.GetFunctionName(ea),
                            idc.GetLongPrm(idc.INF_SHORT_DN))
    if funcName:
        first_parens = funcName.find("(")
        if first_parens != -1:
            funcName = funcName[0:first_parens]

    # Function name is not mangled
    if not funcName:
        funcName = idc.GetFunctionName(ea)

    if funcName is None or funcName is "":
        funcName = idc.Name(ea)

    return funcName
def init_demangled_names(*args):
    """
    Creates dictionary of demangled names => address, that will be used further at double click on methods got from
    symbols.
    """
    demangled_names.clear()
    for address, name in idautils.Names():
        short_name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
        if short_name:
            demangled_names[short_name.split('(')[0]] = address - idaapi.get_imagebase()

            # Names can have templates and should be transformed before creating local type
            name = re.sub(r'[<>]', '_t_', name)

            # Thunk functions with name like "[thunk]:CWarmupHostProvider::Release`adjustor{8}'"
            result = re.search(r"(\[thunk\]:)?([^`]*)(.*\{(\d+)}.*)?", short_name)
            name, adjustor = result.group(2), result.group(4)
            if adjustor:
                demangled_names[name + "_adj_" + adjustor] = address - idaapi.get_imagebase()

    print "[DEBUG] Demangled names have been initialized"
def cls_split_block(fp, start_ea, end_ea):
    """
    ``idaapi.Flowchart`` does not consider function calls as basic block
    boundaries. This function takes a range of addresses and splits additional
    basic blocks.
    """
    cur_name = idc.GetFunctionName(start_ea)
    dem_name = idc.Demangle(cur_name, idc.GetLongPrm(idc.INF_SHORT_DN))
    if dem_name != None:
        cur_name = dem_name

    first = start_ea
    block = idautils.Heads(start_ea, end_ea)
    for inst in block:
        mnem = idc.GetMnem(inst)
        if mnem == 'call' and inst != end_ea:
            fp.write('%#010x %#010x %s\n' %
                     (first, idc.NextHead(inst, end_ea + 1) - 1, cur_name))
            first = idc.NextHead(inst, end_ea + 1)

    if first < end_ea:
        fp.write('%#010x %#010x %s\n' % (first, end_ea - 1, cur_name))
Exemple #28
0
def get_function_name(ea):
    """
        Get the real function name
        """
    # Try to demangle
    function_name = idc.Demangle(idc.GetFunctionName(ea),
                                 idc.GetLongPrm(idc.INF_SHORT_DN))

    if function_name:
        function_name = function_name.split("(")[0]

    # Function name is not mangled
    if not function_name:
        function_name = idc.GetFunctionName(ea)

    if not function_name:
        function_name = idc.Name(ea)

    # If we still have no function name, make one up. Format is - 'UNKN_FNC_4120000'
    if not function_name:
        function_name = "UNKN_FNC_%s" % hex(ea)

    return function_name
def main():
    #print('INF_VERSION:  %s' % (str(idc.GetLongPrm(idc.INF_VERSION))))
    #print('INF_PROCNAME: %s' % (str(idc.GetLongPrm(idc.INF_PROCNAME))))
    #print('INF_COMPILER: %s' % (str(idc.GetLongPrm(idc.INF_COMPILER))))
    #print('INF_FILETYPE: %s' % (str(idc.GetLongPrm(idc.INF_FILETYPE))))

    processor = str(idc.GetLongPrm(idc.INF_PROCNAME))

    is_x86 = processor == 'metapc'
    is_ARM = processor == 'ARM'

    if not is_x86:
        idc.Message('*** Sorry, currently only supported x86.\n')
        return

    def_struct()
    load_metadata()

    #return

    code_reg, meta_reg = analyze_reg()

    if code_reg != idc.BADADDR:
        analyze_code_reg(code_reg)

    if meta_reg != idc.BADADDR:
        analyze_meta_reg(meta_reg, code_reg)

    init_array = analyze_init_array()
    analyze_invoke_unityengine()
    analyze_invoke_library()

    print('%X: INIT_IL2CPP' % (idc.LocByName('INIT_IL2CPP')))
    print('%X: %s' % (code_reg, idc.Name(code_reg)))
    print('%X: %s' % (meta_reg, idc.Name(meta_reg)))
    print('%X: .init_array' % (init_array))
Exemple #30
0
def demangle(string):
    return idc.Demangle(string, idc.GetLongPrm(idc.INF_LONG_DN))