def DumpExports():
    invalidFormatNames = []
    pe = peutils_t()
    baseaddr = pe.imagebase
    print "Listing module {} exports with base address {:x}".format(GetInputFile(),baseaddr)
    exportsList = list(idautils.Entries())
    print "Found %d exports(s)..." % len(exportsList)
    inputFileBase = os.path.splitext(GetInputFile())[0]
    
    outfileName = GetInputFile() + ".exports.h"
    print "Dumping ordinals to " + outfileName
    outfile = file(outfileName,"w")
    
    print >> outfile, "// List of {} exports (base address {:x})\n\n".format(GetInputFile(),baseaddr)
    for exp_index, exp_ordinal, exp_ea, exp_name in list(idautils.Entries()):
        if exp_name == "DllEntryPoint":
            continue
        print >> outfile, "/// @ordinal {}".format(exp_ordinal)
        name = GetTrueNameEx(BADADDR,exp_ea);
        expectedNameStart = inputFileBase + "_" + str(exp_ordinal)
        if not name.startswith(expectedNameStart):
            normalizedName = tryNormalizeName(name,expectedNameStart)
            if normalizedName:
                print "replacing " + name + " by " + normalizedName
                MakeName(exp_ea, normalizedName)
                name = normalizedName
            else:
                invalidFormatNames.append(name + "(expected " + expectedNameStart + ")")
        if name != expectedNameStart:
            name = RemovePrefix(name, expectedNameStart)
        print >> outfile, "/// @name {}".format(name)
        print >> outfile, "/// @address {:x}".format(exp_ea)
        tinfo = GetTinfo(exp_ea)
        # Note: One way to force types not to be guessed could be to call MakeName ?
        if tinfo is not None:
            (type, fields) = tinfo
            print >> outfile,idaapi.idc_print_type(type, fields, name, 0) +";"
        else:
            guessedType = GuessType(exp_ea)
            if guessedType is not None:
                print >> outfile,"/// @guessedtype {}".format(guessedType)
            else:
                print >> outfile,"/// Failed to extract type"
        print >> outfile,""
    print "All done..."
    
    if invalidFormatNames:
        print "Badly formated names:"
        for name in invalidFormatNames:
            print name
Exemple #2
0
    def isExport(self):
        entries = idautils.Entries()

        for entry in entries:
            if self.addr in entry: return True

        return False
Exemple #3
0
def find_exported_eas():
    """Find the address of all exported functions. Exported functions are
  entrypoints into this program that external code can execute."""
    exported_eas = set()
    for index, ordinal, ea, name in idautils.Entries():

        # Not sure how this happens, but IDA seemed to treat
        # `obstack_alloc_failed_handler` in `call cs:[obstack_alloc_failed_handler]`
        # as an entrypoint.
        num_data_refs = len(tuple(idautils.DataRefsTo(ea)))
        num_code_refs = len(tuple(idautils.CodeRefsTo(ea, True)))
        num_code_refs += len(tuple(idautils.CodeRefsTo(ea, True)))
        if num_data_refs and not num_code_refs:
            log.warning(
                "Ignoring entrypoint {:08x}, it's only referenced by data".
                format(ea))
            continue

        if not has_segment_type(ea, idc.SEG_CODE):
            log.warning(
                "Ignoring entrypoint {:08x}, it is not in a code segment".
                format(ea))
            continue

        if not idc.hasName(ea):
            old_name = name
            if name.startswith("."):
                name = idc.GetCommentEx(ea, 0)

            log.info("Renaming `{}` at {:08x} to `{}`".format(
                old_name, ea, name))
            idc.MakeName(ea, name)

    return exported_eas
Exemple #4
0
def main():
    ea = idaapi.get_screen_ea()

    # export entry = tuple(index, ordinal, address, name)
    exports = {export[2]: export for export in idautils.Entries()}

    # list of tuple(xref_address, export_name, xref_offset)
    exported_xrefs = []

    xrefs = [x.frm for x in idautils.XrefsTo(ea)]
    for xref in xrefs:
        func = idaapi.get_func(xref)
        if func and func.startEA in exports:
            exported_xrefs.append(
                (xref, exports[func.startEA][3], xref - func.startEA))

    if exported_xrefs:
        delim = "=" * 80
        print delim
        print "Dumping exported xrefs for:  %s  %s" % (idaapi.get_name(
            ea, ea), idahex(ea))
        print delim
        for exported_xref in exported_xrefs:
            print "%s  %s + 0x%X" % (idahex(
                exported_xref[0]), exported_xref[1], exported_xref[2])
    else:
        print "%s  %shas no exported xrefs." % (idahex(ea),
                                                idaapi.get_name(ea, ea) or "")
Exemple #5
0
def generateDefFile(defname, eps):
    deffile = open(defname, 'wb')
    deffile.write("EXPORTS\n")
    entrypoints = idautils.Entries()

    for ep_tuple in entrypoints:
        (index, ordinal, ea, name) = ep_tuple

        if name not in eps:
            continue

        fwdname = isFwdExport(name, ea)
        if fwdname is not None:
            deffile.write("{0}={1}\n".format(name, fwdname))
        else:
            args, conv, ret = getExportType(name, ea)

            if conv == cfg_pb2.ExternalFunction.CallerCleanup:
                decor_name = "_export_{0}".format(name)
            elif conv == cfg_pb2.ExternalFunction.CalleeCleanup:
                decor_name = "_export_{0}@{1}".format(name, args*4)
            elif conv == cfg_pb2.ExternalFunction.FastCall:
                decor_name = "@export_{0}@{1}".format(name, args*4)
            else:
                raise Exception("Unknown calling convention: " + str(conv))

            deffile.write("{0}={1}\n".format(name, decor_name))

    deffile.close()
Exemple #6
0
def generateExportStub(cname, eps):
    cfile = open(cname, 'wb')
    entrypoints = idautils.Entries()

    for ep_tuple in entrypoints:
        (index, ordinal, ea, name) = ep_tuple

        if name not in eps:
            continue

        fwdname = isFwdExport(name, ea)
        if fwdname is not None:
            continue
        else:
            args, conv, ret =  getExportType(name, ea)

            if conv == cfg_pb2.ExternalFunction.CallerCleanup:
                convstr = "__cdecl"
            elif conv == cfg_pb2.ExternalFunction.CalleeCleanup:
                convstr = "__stdcall"
            elif conv == cfg_pb2.ExternalFunction.FastCall:
                convstr = "__fastcall"
            else:
                raise Exception("Unknown calling convention")

            declargs = makeArgStr(name, declaration=True)
            callargs = makeArgStr(name, declaration=False)

            cfile.write("extern int {2} driver_{0}({1});\n".format(name, declargs, convstr))
            cfile.write("int {3} export_{0}({1}) {{ return driver_{0}({2}); }} \n".format(
                name, declargs, callargs, convstr))
            cfile.write("\n")

    cfile.close()
Exemple #7
0
    def exportsInner(self):
        """Create a collection / generator of all of the exported symbols (string names) in the program (will be called only once).

        Return Value:
            collection of all of the exported symbols in the program
        """
        return map(lambda x: self._logic.funcNameInner(x[-1]), idautils.Entries())
Exemple #8
0
def identify_program_entrypoints(func_eas):
    """Identify all entrypoints into the program. This is pretty much any
  externally visible function."""
    DEBUG("Looking for entrypoints")
    DEBUG_PUSH()

    exclude = set([
        "_start", "__libc_csu_fini", "__libc_csu_init", "main", "__data_start",
        "__dso_handle", "_IO_stdin_used"
    ])

    exported_funcs = set()
    exported_vars = set()

    for index, ordinal, ea, name in idautils.Entries():
        assert ea != idc.BADADDR
        if not is_external_segment(ea):
            sym_name = get_symbol_name(ea, allow_dummy=False)
            if not sym_name:
                DEBUG("WEIRD: Forcing entrypoint {:x} name to be {}".format(
                    ea, name))
                set_symbol_name(ea, name)

            if is_code(ea):
                func_eas.add(ea)
                if name not in exclude:
                    exported_funcs.add(ea)
            else:
                if name not in exclude and not is_runtime_external_data_reference(
                        ea):
                    exported_vars.add(ea)

    DEBUG_POP()
    return exported_funcs, exported_vars
Exemple #9
0
    def search(self):

        exports = set([info[3] for info in idautils.Entries()])
        comexports = set([
            'DllUnregisterServer', 'DllEntryPoint', 'DllGetClassObject',
            'DllCanUnloadNow', 'DllRegisterServer'
        ])
        dllpath = ida_nalt.get_input_file_path().decode('utf-8')
        if not comexports.issubset(exports):
            print('{} is not COM! exports mismatching'.format(dllpath))
            return
        try:
            tlb = pythoncom.LoadTypeLib(dllpath)
        except:
            print('{} is not COM! LoadTypeLib fail'.format(dllpath))
            return
        classes = {}
        values = []
        for i in range(tlb.GetTypeInfoCount()):
            if tlb.GetTypeInfoType(i) == pythoncom.TKIND_COCLASS:
                ctypeinfo = tlb.GetTypeInfo(i)
                clsid = str(ctypeinfo.GetTypeAttr().iid)
                for j in range(ctypeinfo.GetTypeAttr().cImplTypes):
                    typeinfo = ctypeinfo.GetRefTypeInfo(
                        ctypeinfo.GetRefTypeOfImplType(j))
                    attr = typeinfo.GetTypeAttr()
                    name = tlb.GetDocumentation(i)[0]
                    iid = str(attr.iid)
                    vas = self.get_com_vas(
                        dllpath.encode(locale.getdefaultlocale()[1]), clsid,
                        iid, str(attr.cFuncs))
                    if isinstance(vas, str):
                        print(vas)
                    else:
                        for findex in range(attr.cFuncs):
                            fundesc = typeinfo.GetFuncDesc(findex)
                            funnames = typeinfo.GetNames(fundesc.memid)
                            funname_ext = "{}_{}_{}".format(
                                name, funnames[0],
                                invokekinds[fundesc.invkind])
                            typ, flags, default = fundesc.rettype
                            desc = ''
                            if fundesc.invkind == pythoncom.INVOKE_FUNC:
                                desc += vartypes.get(typ, 'UNKNOWN') + ' ('
                                argi = 1
                                for argdesc in fundesc.args:
                                    typ, flags, default = argdesc
                                    desc += '{} {}'.format(
                                        vartypes.get(typ, 'UNKNOWN'),
                                        funnames[argi])
                                    if default is not None:
                                        desc += '={}'.format(default)
                                    desc += ' ,'
                                    argi += 1
                                desc += ')'
                            idaapi.set_name(vas[findex], funname_ext)
                            values.append(
                                [vas[findex], funname_ext, name, desc])
        ComHelperResultChooser("Comhelper", values).show()
Exemple #10
0
def get_export_list():
    """Returns a set of the exported function addresses"""
    exports = set()

    for i, ordn, ea, name in idautils.Entries():
        exports.add(ea)

    return exports
Exemple #11
0
def getAllExports() :
    entrypoints = idautils.Entries()
    to_recover = set()
    # recover every entry point
    for ep_tuple in entrypoints:
        (index, ordinal, ea, name) = ep_tuple
        to_recover.add(name)

    return to_recover
Exemple #12
0
def setBpOnEntries():
	#List of tuples (index, ordinal, ea, name)
	entries = list(idautils.Entries())
	
	if (len(entries) == 0):
		print "No entry points!"
	else:
		for entry in entries:
			ea = entry[2]
			idc.AddBpt(ea)
			print "Bp on %s(0x%08x) set " % (entry[3], ea) 
Exemple #13
0
def obtain_export_by_name(export_name):
    """
    Iterate the entry points to identify the location of an export by name

    :param export_name: Target export

    :return: Location of target export or idc.BADADDR
    """
    for (i, ordinal, ea, name) in idautils.Entries():
        if name == export_name:
            return ea
    return idc.BADADDR
Exemple #14
0
def get_exports():
    '''
    enumerate the exports of the currently loaded module.

    Yields:
      Tuple[int, int, str]:
        - address of exported function
        - export ordinal
        - name of exported function
    '''
    for index, ordinal, ea, name in idautils.Entries():
        yield ea, ordinal, name
Exemple #15
0
    def entries_iter(cls):
        """
            Get an generator on the functions which are entry points of the
            binary. This should be faster than :meth:`~BipFunction.entries` .

            :return: A generator on :class:`BipFunction` which are entry
                points of the binary currently analyzed.
        """
        for elt in idautils.Entries():
            try:
                yield cls(elt[2])
            except ValueError:  # case where we are not in a function, but data
                continue  # we just ignore that case
Exemple #16
0
 def __init__(self):
     self.exports_by_addr = collections.defaultdict(list)
     self.exports_by_name = {}
     self.export_by_ordinal = {}
     for index, ordinal, addr, name in idautils.Entries():
         x = IDAExport(addr, ordinal, name)
         self.exports_by_addr[addr].append(x)
         self.exports_by_name[name] = x
         self.export_by_ordinal[ordinal] = x
         #Entry point : doesnt works for ELF..
         # TODO: find real entry point method
         if addr == ordinal:
             self.entry_point = x
     # disable default dict at this point to prevent error
     self.exports_by_addr.default_factory = None
Exemple #17
0
    def run(self):
        """Run."""
        exports = list(idautils.Entries())

        new_exports = []
        for exp_i, exp_ord, exp_ea, exp_name in exports:
            orig_exp_name = exp_name
            if not exp_name:
                exp_name = idc.GetFunctionName(exp_ea)
                if not exp_name:
                    exp_name = '(error: unable to resolve)'
            if exp_ea == exp_ord:
                exp_ord = '[main entry]'
            new_exports.append([self.demangle(exp_name), "%08X" % exp_ea, "%s" % exp_ord, orig_exp_name])

        ExportChooser("Exports+", new_exports).Show()
        return
Exemple #18
0
def getAllExports() :
    entrypoints = idautils.Entries()
    to_recover = set()
    # recover every entry point
    for ep_tuple in entrypoints:
        (index, ordinal, ea, name) = ep_tuple
        to_recover.add(name)

    ### add it by wmh on 2015.3.30 
    #funcs = Functions();
    #for f in funcs:
    #    ea = idc.LocByName(Name(f).strip())
   #     if ea == idc.BADADDR:
    #        continue
   # 	to_recover.add(Name(f).strip());

    ### end add it by wmh 

    return to_recover 
Exemple #19
0
def Auto_Name_Function_Wrapper():
    ea = idc.ScreenEA()
    segStartEA = idc.SegStart(ea)
    segEndEA = idc.SegEnd(ea)

    print '=' * 100
    print 'aan_Auto_Name_Function Starting'

    excludeList = [entry[3] for entry in idautils.Entries()]
    excludeList.extend([
        'WinMain', 'WinMain@12', 'WinMain@16', 'wWinMain', 'wWinMain@12',
        'wWinMain@16', '_wWinMain@12', '_wWinMain@16', 'main', '_main',
        'StartAddress'
    ])

    funcList = []
    for funcEa in idautils.Functions(segStartEA, segEndEA):
        flags = idc.GetFunctionFlags(funcEa)
        if ((flags & idc.FUNC_LIB) != idc.FUNC_LIB) and (
            (flags & idc.FUNC_THUNK) != idc.FUNC_THUNK) and (
                idc.GetFunctionName(funcEa) not in excludeList):
            funcList.append(funcEa)

    parentNodes = set()
    for funcEa in funcList:
        for refEA in idautils.CodeRefsTo(funcEa, 0):
            if idc.GetFunctionAttr(refEA, idc.FUNCATTR_START) != funcEa:
                parentNodes.add(idc.GetFunctionAttr(refEA, idc.FUNCATTR_START))

    leafNodes = []
    for funcEa in funcList:
        if funcEa not in parentNodes:
            leafNodes.append(funcEa)

    threadRootsList = Get_Thread_Roots()
    threadRootsList = [
        threadEa for threadEa in threadRootsList[:]
        if idc.GetFunctionName(threadEa) not in excludeList
    ]

    for funcEa in threadRootsList:
        if idc.GetFunctionFlags(funcEa) == -1:
            pass
        else:
            Rename(funcEa, CUSTOM_MANUAL_FUNC_PREFIX + 'TS')

    while True:
        funcRenamedCount = 0
        nodesTraversed = set()
        curNodes = leafNodes[:]

        while True:
            for funcEa in curNodes:
                if idc.GetFunctionName(funcEa).startsWith(
                        CUSTOM_MANUAL_FUNC_PREFIX):
                    continue
                oldFuncName = idc.GetFunctionName(funcEa)
                newFuncNameProposed = Build_New_Func_Name(funcEa)
                Rename(funcEa, newFuncNameProposed)
                newFuncNameActual = idc.GetFunctionName(funcEa)

                if oldFuncName != newFuncNameActual:
                    funcRenamedCount += 1

            nodesTraversed.update(curNodes)
            parentNodes = set()

            for funcEa in curNodes:
                for refEA in idautils.CodeRefsTo(funcEa, 0):
                    flags = idc.GetFunctionFlags(refEA)
                    if ((flags & idc.FUNC_LIB) != idc.FUNC_LIB) and (
                            idc.GetFunctionName(refEA) not in excludeList):
                        if idc.GetFunctionAttr(
                                refEA,
                                idc.FUNCATTR_START) not in nodesTraversed:
                            parentNodes.add(
                                idc.GetFunctionAttr(refEA, idc.FUNCATTR_START))

            if len(parentNodes) == 0:
                break

            curNodes = parentNodes.copy()

        if funcRenamedCount == 0:
            break

    print 'aan_Auto_Name_Function completed'
    print '=' * 100
    Refresh()
Exemple #20
0
def recover_rtti():
  for index, ordinal, ea, name in idautils.Entries():
    if get_stripped_name(name) in typeinfo_names:
      get_typeinfo_refs(name, ea)
Exemple #21
0
def save_export_renames(dest):
        exports = {}
        for i, ord, addr, name in idautils.Entries():
                exports[name] = idc.GetFunctionName(addr)
        with open(path.expanduser(dest), 'w') as f:
                json.dump(exports, f)
Exemple #22
0
def recoverCfg(to_recover, outf, exports_are_apis=False):
    M = cfg_pb2.Module()
    M.module_name = idc.GetInputFile()
    DEBUG("PROCESSING: {0}\n".format(M.module_name))

    our_entries = []
    entrypoints = idautils.Entries()
    exports = {}
    for index,ordinal,exp_ea, exp_name in entrypoints:
        exports[exp_name] = exp_ea

    new_eas = set()
    add_result_from_IDA(new_eas)
    processDataSegments(M, new_eas)

    for name in to_recover:

        if name in exports:
            ea = exports[name]
        else:
            ea = idc.LocByName(name)
            if ea == idc.BADADDR:
                raise Exception("Could not locate entry symbol: {0}".format(name))

        fwdname = isFwdExport(name, ea)

        if fwdname is not None:
            sys.stdout.write("Skipping fwd export {0} : {1}\n".format(name, fwdname))
            continue

        if not isInternalCode(ea):
            sys.stdout.write("Export {0} does not point to code; skipping\n".format(name))
            continue

        our_entries.append( (name, ea) )

    recovered_fns = 0

    # process main entry points
    for fname, fea in our_entries:

        sys.stdout.write("Recovering: {0}\n".format(fname))

        F = entryPointHandler(M, fea, fname, exports_are_apis)

        RECOVERED_EAS.add(fea)
        recoverFunction(M, F, fea, new_eas)

        recovered_fns += 1

    # process subfunctions
    new_eas.difference_update(RECOVERED_EAS)

    while len(new_eas) > 0:
        cur_ea = new_eas.pop()
        if cur_ea in RECOVERED_EAS:
            continue

        if not isInternalCode(cur_ea):
            raise Exception("Function EA not code: {0:x}".format(cur_ea))

        F = addFunction(M, cur_ea)
        sys.stdout.write("Recovering: {0}\n".format(hex(cur_ea)))
        RECOVERED_EAS.add(cur_ea)

        recoverFunction(M, F, cur_ea, new_eas)

        recovered_fns += 1

    if recovered_fns == 0:
        sys.stderr.write("COULD NOT RECOVER ANY FUNCTIONS\n")
        return

    probably_fn_pointers = set()
    map(lambda (s,e): scanDataForCodePointers(s,e,probably_fn_pointers), DATA_SEGMENTS);

    # add functions found by scanning data section
    while len(probably_fn_pointers) > 0:
        cur_ea = probably_fn_pointers.pop()
        if not isInternalCode(cur_ea):
            raise Exception("Function EA not code: {0:x}".format(cur_ea))

        F = addFunction(M, cur_ea)
        sys.stdout.write("Recovering: {0}\n".format(hex(cur_ea)))
        RECOVERED_EAS.add(cur_ea)

        recoverFunction(M, F, cur_ea, probably_fn_pointers)

        recovered_fns += 1

    # if FUNCTIONS_NEED_TRAMPOLINE is true it means
    # there is some indirect calls and we need to set
    # trampolines for those functions we think may be
    # targets
    # XXX: for the moment every function is a target
    if FUNCTIONS_NEED_TRAMPOLINE:
        for f in M.internal_funcs:
            f.need_trampoline = True

    mypath = path.dirname(__file__)
    processExternals(M)

    outf.write(M.SerializeToString())
    outf.close()

    sys.stdout.write("Recovered {0} functions.\n".format(recovered_fns))
    sys.stdout.write("Saving to: {0}\n".format(outf.name))
Exemple #23
0
if info.is_be():
    data['info']['endian'] = "big"

#get program_class
data['info']['program_class'] = class_map[info.filetype]

#get imports and dlls
nimps = idaapi.get_import_module_qty()
for i in xrange(0, nimps):
    dllname = idaapi.get_import_module_name(i)
    if dllname != None:
        data['libs'].append({"name": dllname})
    idaapi.enum_import_names(i, imp_cb)

#get exports
for exp in list(idautils.Entries()):
    e = {
        'name': exp[3],
        'offset': exp[1],
        'size':
        0  #Hardcoded to 0 until we figure out what the 'size' info actually means
    }
    data['exports'].append(e)

#iterate through functions
for func in idautils.Functions():
    #if func from library skip
    flags = idc.GetFunctionFlags(func)
    if flags & FUNC_LIB or flags & FUNC_THUNK or flags & FUNC_HIDDEN:
        continue
Exemple #24
0
def idenLib():
    global func_sigs
    global mainSigs
    # function sigs from the current binary
    func_bytes_addr = {}
    for addr, size in getFuncRanges():
        f_bytes = getOpcodes(addr, size)
        func_bytes_addr[f_bytes] = addr

    # load sigs
    if not os.path.isdir(symEx_dir):
        print("[idenLib - FAILED] There is no {} directory".format(symEx_dir))
        return

    if os.path.isfile(idenLibCache):
        func_sigs = pickle.load(open(idenLibCache, "rb"))
        if os.path.isfile(idenLibCacheMain):
            mainSigs = pickle.load(open(idenLibCacheMain, "rb"))
    else:
        idenLibProcessSignatures()
    # apply sigs
    counter = 0
    mainDetected = False
    for sig_opcodes, addr in func_bytes_addr.items():
        if func_sigs.has_key(sig_opcodes):
            func_name = func_sigs[sig_opcodes]
            current_name = ida_funcs.get_func_name(addr)
            if (current_name != func_name):
                digit = 1
                while func_name in getNames():
                    func_name = func_name + str(digit)
                    digit = digit + 1
                ida_name.set_name(addr, func_name, ida_name.SN_NOCHECK)
                print("{}: {}".format(hex(addr), func_name))
                counter = counter + 1
        if mainSigs.has_key(sig_opcodes):  # "main" sig
            callInstr = mainSigs[sig_opcodes][1] + addr
            if ida_ua.print_insn_mnem(callInstr) == "call":
                call_target = idc.get_operand_value(callInstr, 0)
                current_name = ida_funcs.get_func_name(call_target)
                func_name = mainSigs[sig_opcodes][0]
                if (current_name != func_name):
                    ida_name.set_name(call_target, func_name,
                                      ida_name.SN_NOCHECK)
                    print("{}: {}".format(hex(call_target), func_name))
                    counter = counter + 1
                    mainDetected = True
    if not mainDetected:
        for entry in idautils.Entries():
            for sig_opcodes, name_funcRva_EntryRva in mainSigs.items():
                callInstr = name_funcRva_EntryRva[2] + entry[2]  # from EP
                if ida_ua.print_insn_mnem(callInstr) == "call":
                    fromFunc = name_funcRva_EntryRva[1]
                    func_start = callInstr - fromFunc
                    func_opcodes = getOpcodes(func_start, MAX_FUNC_SIZE)
                    if func_opcodes.startswith(sig_opcodes):
                        call_target = idc.get_operand_value(callInstr, 0)
                        current_name = ida_funcs.get_func_name(call_target)
                        func_name = mainSigs[sig_opcodes][0]
                        if (current_name != func_name):
                            ida_name.set_name(call_target, func_name,
                                              ida_name.SN_NOCHECK)
                            print("{}: {}".format(hex(call_target), func_name))
                            counter = counter + 1
                            mainDetected = True
                            break

    print("[idenLib] Applied to {} function(s)".format(counter))
Exemple #25
0
def is_driver():
    exports = set(x[3] for x in idautils.Entries())
    return 'DriverEntry' in exports
def idenLib():
    global g_func_sigs
    global g_main_sigs

    new_sigs = False
    cached = False
    if os.path.isfile(idenLibCache):
        try:
            with open(idenLibCache, "rb") as f:
                g_func_sigs = pickle.load(f)
            if os.path.isfile(idenLibCacheMain):
                with open(idenLibCacheMain, "rb") as f:
                    g_main_sigs = pickle.load(f)
                    cached = True
        except Exception as e:
            # continue with new sigs after excption
            print("[idenLib] load cache files error: %s" % str(e))

    if cached:
        ret = idaapi.ask_yn(idaapi.ASKBTN_YES, "Do you want to select another signatures than current cached ?")
        if ret == idaapi.ASKBTN_CANCEL:
            print("[idenLib] user cancelled")
            return

        new_sigs = ret == idaapi.ASKBTN_YES
    else:
        new_sigs = True

    idaapi.msg_clear()

    if new_sigs:
        if not idenLibProcessSignatures():
            return

    idaapi.show_wait_box("Please wait scan and apply signatures...")

    # function sigs from the current binary
    func_bytes_addr = {}
    for addr, size in getFuncRanges():
        f_bytes = getOpcodes(addr, size)
        func_bytes_addr[f_bytes] = addr

    # apply sigs
    counter = 0
    mainDetected = False
    for sig_opcodes, addr in func_bytes_addr.items():
        if g_func_sigs.has_key(sig_opcodes):
            set_func_library(addr)
            func_name = g_func_sigs[sig_opcodes][0]
            current_name = idc.get_func_name(addr)
            if current_name != func_name:
                idc.set_name(addr, func_name, idaapi.SN_FORCE)
                print("{}: {}".format(hex(addr).rstrip("L"), func_name))
                counter = counter + 1

        if g_main_sigs.has_key(sig_opcodes): # "main" sig
            callInstr = g_main_sigs[sig_opcodes][1] + addr
            if idaapi.print_insn_mnem(callInstr) == "call":
                call_target = idc.get_operand_value(callInstr, 0)
                set_func_library(call_target)
                func_name = g_main_sigs[sig_opcodes][0]
                current_name = idc.get_func_name(call_target)
                if current_name != func_name:
                    idaapi.set_name(call_target, func_name, idaapi.SN_FORCE)
                    print("{}: {}".format(hex(call_target).rstrip("L"), func_name))
                    counter = counter + 1
                    mainDetected = True

    if not mainDetected:
        for entry in idautils.Entries():
            for sig_opcodes, name_funcRva_EntryRva in g_main_sigs.items():
                callInstr = name_funcRva_EntryRva[2] + entry[2] # from EP
                if idaapi.print_insn_mnem(callInstr) == "call":
                    fromFunc = name_funcRva_EntryRva[1]
                    func_start = callInstr - fromFunc
                    func_opcodes = getOpcodes(func_start, MAX_FUNC_SIZE)
                    if func_opcodes.startswith(sig_opcodes):
                        call_target = idc.get_operand_value(callInstr, 0)
                        set_func_library(call_target)
                        current_name = idc.get_func_name(call_target)
                        func_name = g_main_sigs[sig_opcodes][0]
                        if current_name != func_name:
                            idaapi.set_name(call_target, func_name, idaapi.SN_FORCE)
                            print("{}: {}".format(hex(call_target).rstrip("L"), func_name))
                            counter = counter + 1
                            mainDetected = True
                            break

    idaapi.hide_wait_box()

    print("[idenLib] Applied to {} function(s)".format(counter))
Exemple #27
0
 def BuildExports(self):
     return list(idautils.Entries())
Exemple #28
0
        def activate(self, ctx):
            if self.menu_title == MenuAskEntryId:
                self.outer_self.mixto.entry_id = idaapi.ask_str(
                    "", 1000, "Mixto Entry Id")

            else:
                if self.outer_self.mixto.entry_id is None:
                    self.outer_self.mixto.entry_id = idaapi.ask_str(
                        "", 1000, "Mixto Entry Id")

            if self.menu_title == MenuAllFunc:
                all_func = ""
                # Get count of all functions in the binary
                count = idaapi.get_func_qty()

                for i in range(count):
                    fn = idaapi.getn_func(i)

                    # Function should not have dummy name such as sub_*
                    # and should not start with underscore (possible library functions)
                    if not idaapi.has_dummy_name(get_flags_at(
                            start_ea_of(fn))) and not idaapi.get_func_name(
                                start_ea_of(fn)).startswith("_"):
                        all_func += "{} @ 0x{:x}\n".format(
                            idaapi.get_func_name(start_ea_of(fn)),
                            start_ea_of(fn))
                self.outer_self.mixto.AddCommit(all_func,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Functions")

            elif self.menu_title == MenuImports:
                global AllImports
                AllImports = ""
                # Get count of all import modules in the binary
                count = idaapi.get_import_module_qty()

                for i in range(count):
                    module_name = idaapi.get_import_module_name(i)

                    AllImports += "{}:\n".format(module_name)
                    idaapi.enum_import_names(i, imports_cb)
                self.outer_self.mixto.AddCommit(AllImports,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Imports")

            elif self.menu_title == MenuDecFunc:
                addr_current = idc.get_screen_ea()
                addr_func = idaapi.get_func(addr_current)

                if not addr_func:
                    idaapi.msg("Place cursor inside a function!")
                    return False
                else:
                    err = None
                    out = str(idaapi.decompile(addr_func))
                    # print(out)
                    self.outer_self.mixto.AddCommit(
                        str(out),
                        self.outer_self.mixto.entry_id,
                        "(IDA) Function Decompilation {}".format(
                            idc.GetFunctionName(addr_func.startEA)),
                    )

            elif self.menu_title == MenuExports:
                all_exports = ""
                for entry in idautils.Entries():
                    _, ord, ea, name = entry
                    if not name:
                        all_exports += "0x{:x}: ord#{}\n".format(ea, ord)
                    else:
                        all_exports += "0x{:x}: {} ord#{}\n".format(
                            ea, name, ord)
                self.outer_self.mixto.AddCommit(all_exports,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Exports")

            elif self.menu_title == MenuAllComments:
                addr_current = idc.get_screen_ea()
                addr_func = idaapi.get_func(addr_current)

                uniq_comments = {}
                comments = []
                for ea in range(addr_func.startEA, addr_func.endEA):
                    comment = idaapi.get_cmt(ea, 0)
                    if comment is not None:
                        # hacky way to make sure only uniq comments are added
                        if uniq_comments.get(comment) == 1:
                            pass
                        else:
                            print(uniq_comments)
                            comments.append("{offset} {value}".format(
                                offset=hex(ea), value=comment))
                            print("here")
                            uniq_comments[comment] = 1
                if len(comments) > 0:
                    out = "\n".join(comments)
                    self.outer_self.mixto.AddCommit(
                        str(out),
                        self.outer_self.mixto.entry_id,
                        "(IDA) Function Comments {}".format(
                            idc.GetFunctionName(addr_func.startEA)),
                    )

                else:
                    raise TypeError("No comments found")

            return True
Exemple #29
0
def extract_file_export_names():
    """extract function exports"""
    for (_, _, ea, name) in idautils.Entries():
        yield Export(name), ea
Exemple #30
0
def recoverCfg(to_recover, outf, exports_are_apis=False):
    M = CFG_pb2.Module()
    M.module_name = idc.GetInputFile()
    DEBUG("PROCESSING: {0}\n".format(M.module_name))

    our_entries = []
    entrypoints = idautils.Entries()
    exports = {}
    for index, ordinal, exp_ea, exp_name in entrypoints:
        exports[exp_name] = exp_ea

    new_eas = set()
    processDataSegments(M, new_eas)

    for name in to_recover:

        if name in exports:
            ea = exports[name]
        else:
            ea = idc.LocByName(name)
            if ea == idc.BADADDR:
                raise Exception(
                    "Could not locate entry symbol: {0}".format(name))

        fwdname = isFwdExport(name, ea)

        if fwdname is not None:
            sys.stdout.write("Skipping fwd export {0} : {1}\n".format(
                name, fwdname))
            continue

        if not isInternalCode(ea):
            sys.stdout.write(
                "Export {0} does not point to code; skipping\n".format(name))
            continue

        our_entries.append((name, ea))

    recovered_fns = 0

    # process main entry points
    for fname, fea in our_entries:

        sys.stdout.write("Recovering: {0}\n".format(fname))

        F = entryPointHandler(M, fea, fname, exports_are_apis)

        RECOVERED_EAS.add(fea)
        recoverFunction(M, F, fea, new_eas)

        recovered_fns += 1

    # process subfunctions
    new_eas.difference_update(RECOVERED_EAS)

    while len(new_eas) > 0:
        cur_ea = new_eas.pop()
        if not isInternalCode(cur_ea):
            raise Exception("Function EA not code: {0:x}".format(cur_ea))

        F = addFunction(M, cur_ea)
        sys.stdout.write("Recovering: {0}\n".format(hex(cur_ea)))
        RECOVERED_EAS.add(cur_ea)

        recoverFunction(M, F, cur_ea, new_eas)

        recovered_fns += 1

    if recovered_fns == 0:
        sys.stderr.write("COULD NOT RECOVER ANY FUNCTIONS\n")
        return

    mypath = path.dirname(__file__)
    processExternals(M)

    outf.write(M.SerializeToString())
    outf.close()

    sys.stdout.write("Recovered {0} functions.\n".format(recovered_fns))
    sys.stdout.write("Saving to: {0}\n".format(outf.name))