Example #1
0
def erase_contents():
    res = db.functions()
    total, tag = len(res), internal.comment.contents.btag
    yield total

    for idx, ea in enumerate(db.functions()):
        internal.netnode.blob.remove(ea, tag)
        yield idx, ea
    return
Example #2
0
def all():
    '''Iterate through everything in the database and update the tagcache with any found tags.'''
    total = len(list(db.functions()))
    addr, tags = {}, {}
    for i, ea in enumerate(db.functions()):
        print "{:x} : updating references for contents : {:d} of {:d}".format(
            ea, i, total)
        _, _ = function(ea)
    print 'updating references for globals'
    _, _ = globals()
Example #3
0
def erase_contents():
    '''Erase the contents cache defined for each function in the database.'''
    res = db.functions()
    total, tag = len(res), internal.comment.contents.btag
    yield total

    for idx, ea in enumerate(db.functions()):
        internal.netnode.blob.remove(ea, tag)
        yield idx, ea
    return
Example #4
0
def erase_contents():
    '''Erase the contents cache defined for each function in the database.'''
    res = db.functions()
    total, tag = len(res), internal.comment.contents.btag
    yield total

    for idx, ea in enumerate(db.functions()):
        internal.netnode.blob.remove(ea, tag)
        yield idx, ea
    return
Example #5
0
def do_functions():
    addr, tags = {}, {}
    t = len(list(db.functions()))
    for i, ea in enumerate(db.functions()):
        print "{:x} : fetching function {:d} of {:d}".format(ea, i, t)
        res = fn.tag(ea)
        #res.pop('name', None)
        for k, v in res.iteritems():
            addr[ea] = addr.get(ea, 0) + 1
            tags[k] = tags.get(k, 0) + 1
        continue
    return addr, tags
Example #6
0
def all():
    '''Re-build the cache for all the globals and contents in the database.'''
    total = len(list(db.functions()))

    # process all function contents tags
    for i, ea in enumerate(db.functions()):
        six.print_(u"updating references for contents ({:#x}) : {:d} of {:d}".format(ea, i, total), file=output)
        _, _ = contents(ea)

    # process all global tags
    six.print_(u'updating references for globals', file=output)
    _, _ = globals()
Example #7
0
def all():
    '''Re-build the cache for all the globals and contents in the database.'''
    total = len(list(db.functions()))

    # process all function contents tags
    for i, ea in enumerate(db.functions()):
        print >> output, "updating references for contents ({:#x}) : {:d} of {:d}".format(
            ea, i, total)
        _, _ = contents(ea)

    # process all global tags
    print >> output, 'updating references for globals'
    _, _ = globals()
Example #8
0
def map(F, **kwargs):
    """Execute the callback `F` on all functions in the database. Synonymous to `map(F, database.functions())` but with some extra logging to display the current progress.

    The `F` parameter is defined as a function taking either an
    `(address, **kwargs)` or a `(index, address, **kwargs)`. Any
    keyword arguments are passed to `F` unmodified.
    """
    f1 = lambda idx, ea, **kwargs: F(ea, **kwargs)
    f2 = lambda idx, ea, **kwargs: F(idx, ea, **kwargs)
    Ff = internal.utils.pycompat.method.function(F) if isinstance(F, types.MethodType) else F
    Fc = internal.utils.pycompat.function.code(Ff)
    f = f1 if internal.utils.pycompat.code.argcount(Fc) == 1 else f2

    result, all = [], database.functions()
    total = len(all)
    if len(all):
        ea = next(item for item in all)
        try:
            for i, ea in enumerate(all):
                ui.navigation.set(ea)
                six.print_("{:#x}: processing # {:d} of {:d} : {:s}".format(ea, 1 + i, total, func.name(ea)))
                result.append( f(i, ea, **kwargs) )
        except KeyboardInterrupt:
            six.print_("{:#x}: terminated at # {:d} of {:d} : {:s}".format(ea, 1 + i, total, func.name(ea)))
    return result
Example #9
0
def __process_functions():
    p = ui.progress()
    globals = internal.comment.globals.address()

    funcs = list(database.functions())
    p.update(current=0, max=len(funcs), title="Pre-building tagcache...")
    p.open()
    for i, fn in enumerate(funcs):
        chunks = list(function.chunks(fn))

        text = functools.partial("{:x} : Processing function {:d} of {:d} : ({:d} chunk{:s})".format, fn, i, len(funcs))
        p.update(current=i)

        contents = set(internal.comment.contents.address(fn))
        for ci, (l, r) in enumerate(chunks):
            p.update(text=text(len(chunks), 's' if len(chunks) != 1 else ''), tooltip="Chunk #{:d} : {:x} - {:x}".format(ci, l, r))
            for ea in database.iterate(l, r):
                # FIXME: no need to iterate really since we should have
                #        all of the addresses
                for k, v in database.tag(ea).iteritems():
                    if ea in globals: internal.comment.globals.dec(ea, k)
                    if ea not in contents: internal.comment.contents.inc(ea, k, target=fn)
                continue
            continue
        continue
    p.close()
Example #10
0
def rebase(info):
    functions, globals = map(utils.fcompose(sorted, list), (database.functions(), internal.netnode.alt.fiter(internal.comment.tagging.node())))

    p = ui.Progress()
    p.update(current=0, title=u"Rebasing tagcache...", min=0, max=len(functions)+len(globals))
    fcount = gcount = 0

    scount = info.size() + 1
    six.print_(u"{:s}.rebase({!s}) : Rebasing tagcache for {:d} segments.".format(__name__, utils.string.repr(info), scount))

    # for each segment
    p.open()
    for si in six.moves.range(scount):
        msg = u"Rebasing tagcache for segment {:d} of {:d} : {:#x} ({:+#x}) -> {:#x}".format(si, scount, info[si]._from, info[si].size, info[si].to)
        p.update(title=msg), six.print_(msg)

        # for each function (using target address because ida moved the netnodes for us)
        res = [n for n in functions if info[si].to <= n < info[si].to + info[si].size]
        for i, fn in __rebase_function(info[si]._from, info[si].to, info[si].size, iter(res)):
            text = u"Function {:d} of {:d} : {:#x}".format(i + fcount, len(functions), fn)
            p.update(value=sum((fcount, gcount, i)), text=text)
            ui.navigation.procedure(fn)
        fcount += len(res)

        # for each global
        res = [(ea, count) for ea, count in globals if info[si]._from <= ea < info[si]._from + info[si].size]
        for i, ea in __rebase_globals(info[si]._from, info[si].to, info[si].size, iter(res)):
            text = u"Global {:d} of {:d} : {:#x}".format(i + gcount, len(globals), ea)
            p.update(value=sum((fcount, gcount, i)), text=text)
            ui.navigation.analyze(ea)
        gcount += len(res)
    p.close()
def fetch_globals_functions():
    """Fetch the reference count for the global tags (function) in the database.

    Returns the tuple `(address, tags)` where the `address` and `tags`
    fields are both dictionaries containing the reference count for
    the addresses and tag names.
    """
    addr, tags = {}, {}
    functions = [item for item in db.functions()]
    for i, ea in enumerate(functions):
        ui.navigation.auto(ea)
        six.print_(
            u"globals: fetching tag from function {:#x} : {:d} of {:d}".format(
                ea, i, len(functions)),
            file=output)

        # grab both comment types from the current function and then decode
        # them. once decoded then we can just iterate through their keys and
        # tally everything up.
        repeatable, nonrepeatable = (func.comment(ea, repeatable=item)
                                     for item in [True, False])
        for items in map(internal.comment.decode, [repeatable, nonrepeatable]):
            #items.pop('name', None)
            for name in items:
                addr[ea] = addr.get(ea, 0) + 1
                tags[name] = tags.get(name, 0) + 1
            continue
        continue
    return addr, tags
Example #12
0
def rebase(info):
    functions, globals = map(utils.compose(sorted, list), (database.functions(), internal.netnode.alt.fiter(internal.comment.tagging.node())))

    p = ui.progress()
    p.update(current=0, title="Rebasing tagcache...", min=0, max=len(functions)+len(globals))
    fcount = gcount = 0

    # for each segment
    p.open()
    for si in xrange(info.size()):
        p.update(title="Rebasing segment {:d} of {:d} (+{:x}) : {:x} -> {:x}".format(si, info.size(), info[si].size, info[si]._from, info[si].to))

        # for each function (using target address because ida moved the netnodes for us)
        res = [n for n in functions if info[si].to <= n < info[si].to + info[si].size]
        for i, fn in __rebase_function(info[si]._from, info[si].to, info[si].size, res):
            text = "Function {:d} of {:d} : {:x}".format(i + fcount, len(functions), fn)
            p.update(value=sum((fcount,gcount,i)), text=text)
        fcount += len(res)

        # for each global
        res = [(ea,count) for ea,count in globals if info[si]._from <= ea < info[si]._from + info[si].size]
        for i, ea in __rebase_globals(info[si]._from, info[si].to, info[si].size, res):
            time.sleep(0.001)
            text = "Global {:d} of {:d} : {:x}".format(i + gcount, len(globals), ea)
            p.update(value=sum((fcount,gcount,i)), text=text)
        gcount += len(res)
    p.close()
Example #13
0
def __process_functions(percentage=0.10):
    p = ui.Progress()
    globals = set(internal.comment.globals.address())

    total = 0

    funcs = list(database.functions())
    p.update(current=0, max=len(funcs), title=u"Pre-building tagcache...")
    p.open()
    six.print_(u"Pre-building tagcache for {:d} functions.".format(len(funcs)))
    for i, fn in enumerate(funcs):
        chunks = list(function.chunks(fn))

        text = functools.partial(u"Processing function {:#x} ({chunks:d} chunk{plural:s}) -> {:d} of {:d}".format, fn, i + 1, len(funcs))
        p.update(current=i)
        ui.navigation.procedure(fn)
        if i % (int(len(funcs) * percentage) or 1) == 0:
            six.print_(u"Processing function {:#x} -> {:d} of {:d} ({:.02f}%)".format(fn, i+1, len(funcs), i / float(len(funcs)) * 100.0))

        contents = set(internal.comment.contents.address(fn))
        for ci, (l, r) in enumerate(chunks):
            p.update(text=text(chunks=len(chunks), plural='' if len(chunks) == 1 else 's'), tooltip="Chunk #{:d} : {:#x} - {:#x}".format(ci, l, r))
            ui.navigation.analyze(l)
            for ea in database.address.iterate(l, r):
                # FIXME: no need to iterate really since we should have
                #        all of the addresses
                for k, v in six.iteritems(database.tag(ea)):
                    if ea in globals: internal.comment.globals.dec(ea, k)
                    if ea not in contents: internal.comment.contents.inc(ea, k, target=fn)
                    total += 1
                continue
            continue
        continue
    six.print_(u"Successfully built tag-cache composed of {:d} tag{:s}.".format(total, '' if total == 1 else 's'))
    p.close()
Example #14
0
def map(F, **kwargs):
    """Execute the callback `F` on all functions in the database. Synonymous to `map(F, database.functions())` but with some extra logging to display the current progress.

    The `F` parameter is defined as a function taking either an
    `(address, **kwargs)` or a `(index, address, **kwargs)`. Any
    keyword arguments are passed to `F` unmodified.
    """
    f1 = lambda (idx, ea), **kwargs: F(ea, **kwargs)
    f2 = lambda (idx, ea), **kwargs: F(idx, ea, **kwargs)
    f = f1 if F.func_code.co_argcount == 1 else f2

    result, all = [], database.functions()
    total = len(all)
    if len(all):
        ea = next(iter(all))
        try:
            for i, ea in enumerate(all):
                ui.navigation.set(ea)
                print("{:#x}: processing # {:d} of {:d} : {:s}".format(
                    ea, i + 1, total, func.name(ea)))
                result.append(f((i, ea), **kwargs))
        except KeyboardInterrupt:
            print("{:#x}: terminated at # {:d} of {:d} : {:s}".format(
                ea, i + 1, total, func.name(ea)))
    return result
Example #15
0
    def frames():
        '''Iterate through the fields of each frame for all the functions defined within the database.'''
        global read

        for ea in db.functions():
            ui.navigation.procedure(ea)
            res = dict(read.frame(ea))
            if res: yield ea, res
        return
Example #16
0
    def frames():
        '''Iterate through the fields of each frame for all the functions defined within the database.'''
        global read

        for ea in db.functions():
            ui.navigation.procedure(ea)
            res = dict(read.frame(ea))
            if res: yield ea, res
        return
Example #17
0
    def frames(*tags):
        '''Iterate through the fields in each function's frame containing the specified `tags`.'''
        global export
        tags_ = {x for x in tags}

        for ea in db.functions():
            ui.navigation.procedure(ea)
            res = dict(export.frame(ea, *tags))
            if res: yield ea, res
        return
Example #18
0
def fetch_globals_functions():
    """Fetch the reference count for the global tags (function) in the database.

    Returns the tuple `(address, tags)` where the `address` and `tags`
    fields are both dictionaries containing the reference count for
    the addresses and tag names.
    """
    addr, tags = {}, {}
    t = len(list(db.functions()))
    for i, ea in enumerate(db.functions()):
        ui.navigation.auto(ea)
        six.print_(u"globals: fetching tag from function {:#x} : {:d} of {:d}".format(ea, i, t), file=output)
        res = func.tag(ea)
        #res.pop('name', None)
        for k, v in six.iteritems(res):
            addr[ea] = addr.get(ea, 0) + 1
            tags[k] = tags.get(k, 0) + 1
        continue
    return addr, tags
Example #19
0
    def frames(*tags):
        '''Iterate through the fields in each function's frame containing the specified `tags`.'''
        global export
        tags_ = {x for x in tags}

        for ea in db.functions():
            ui.navigation.procedure(ea)
            res = dict(export.frame(ea, *tags))
            if res: yield ea, res
        return
Example #20
0
def fetch_globals_functions():
    """Fetch the reference count for the global tags (function) in the database.

    Returns the tuple `(address, tags)` where the `address` and `tags`
    fields are both dictionaries containing the reference count for
    the addresses and tag names.
    """
    addr, tags = {}, {}
    t = len(list(db.functions()))
    for i, ea in enumerate(db.functions()):
        ui.navigation.auto(ea)
        print >> output, "globals: fetching tag from function {:#x} : {:d} of {:d}".format(
            ea, i, t)
        res = func.tag(ea)
        #res.pop('name', None)
        for k, v in six.iteritems(res):
            addr[ea] = addr.get(ea, 0) + 1
            tags[k] = tags.get(k, 0) + 1
        continue
    return addr, tags
Example #21
0
def all():
    '''Re-build the cache for all the globals and contents in the database.'''
    functions = [item for item in db.functions()]

    # process all function contents tags
    for i, ea in enumerate(functions):
        six.print_(u"updating references for contents ({:#x}) : {:d} of {:d}".format(ea, i, len(functions)), file=output)
        _, _ = contents(ea)

    # process all global tags
    six.print_(u'updating references for globals', file=output)
    _, _ = globals()
Example #22
0
def everything(use_cache=False):
    '''Return all the tags within the database as (globals, contents, frames).'''
    if use_cache:
        g, f = cached()

    else:
        print >> output, '--> Grabbing globals...'
        g = {ea: d for ea, d in globals()}

        print >> output, '--> Grabbing contents from all functions...'
        res = (function(ea) for ea in db.functions())
        f = {}
        map(f.update, itertools.imap(dict, itertools.ifilter(None, res)))

    print >> output, '--> Grabbing frames from all functions...'
    h = {ea: d for ea, d in frames()}
    return (g, f, h)
Example #23
0
    def contents(location=False):
        """Iterate through the contents tags for all the functions within the database.

        Each iteration yields a tuple of the format `(location, tags)` where
        `location` can be either an address or a chunk identifier and offset
        depending on whether `location` was specified as true or not.
        """
        global read

        # Iterate through each function in the database
        for ea in db.functions():

            # it's faster to precalculate the chunks here
            F, chunks = func.by(ea), [ch for ch in func.chunks(ea)]

            # Iterate through the function's contents yielding each tag
            for ea, res in read.content(ea):
                loc = addressToLocation(ea, chunks=chunks) if location else ea
                yield loc, res
            continue
        return
Example #24
0
    def contents(location=False):
        """Iterate through the contents tags for all the functions within the database.

        Each iteration yields a tuple of the format `(location, tags)` where
        `location` can be either an address or a chunk identifier and offset
        depending on whether `location` was specified as true or not.
        """
        global read

        # Iterate through each function in the database
        for ea in db.functions():

            # it's faster to precalculate the chunks here
            F, chunks = func.by(ea), [ch for ch in func.chunks(ea)]

            # Iterate through the function's contents yielding each tag
            for ea, res in read.content(ea):
                loc = addressToLocation(ea, chunks=chunks) if location else ea
                yield loc, res
            continue
        return
Example #25
0
def map(F, **kwargs):
    """Execute the callback `F` on all functions in the database. Synonymous to `map(F, database.functions())` but with some extra logging to display the current progress.

    The `F` parameter is defined as a function taking either an
    `(address, **kwargs)` or a `(index, address, **kwargs)`. Any
    keyword arguments are passed to `F` unmodified.
    """
    f1 = lambda (idx, ea), **kwargs: F(ea, **kwargs)
    f2 = lambda (idx, ea), **kwargs: F(idx, ea, **kwargs)
    f = f1 if F.func_code.co_argcount == 1 else f2

    result, all = [], database.functions()
    total = len(all)
    if len(all):
        ea = next(iter(all))
        try:
            for i, ea in enumerate(all):
                ui.navigation.set(ea)
                print("{:#x}: processing # {:d} of {:d} : {:s}".format(ea, i+1, total, func.name(ea)))
                result.append( f((i, ea), **kwargs) )
        except KeyboardInterrupt:
            print("{:#x}: terminated at # {:d} of {:d} : {:s}".format(ea, i+1, total, func.name(ea)))
    return result
Example #26
0
    if False:
        import re, pyml, database,function

        SetDelayed = pyml.function("SetDelayed")
        Set = pyml.function("Set")
        List = pyml.function("List")
        Hold = pyml.function("Hold")
        RuleDelayed = pyml.function("RuleDelayed")
        Rule = pyml.function("Rule")

        call = pyml.function("call")
        symcall = pyml.function("symcall")
        
        rules = []
        max = len(database.functions())
        for i,ea in enumerate(database.functions()):
            result = []
            for l,r in function.chunks(ea):
                for x in database.iterate(l,r):
                    address,size,insn = x,idc.ItemSize(x),idc.GetDisasm(x)
                    insn = re.sub(" +", " ", insn)
                    insn = insn.replace("short", "")
                    insn = insn.replace("dword", "")
                    insn = insn.replace("offset", "")
                    insn = insn.replace("large", "")
                    insn = insn.replace("ptr", "")
                    insn = insn.replace("[", "")
                    insn = insn.replace("]", "")
                    if " " in insn:
                        insn = insn.replace(" ", "|", 1)
Example #27
0
    def __init__(self, options, create=True, existing=None):

        self.provider = ida.IDA()

        if create:
            # create the DB
            print "[*] db.py: Creating a new DB file"

            db = store.sqlite3.connect(options['full_file_name'])
            #db.isolation_level =
            self.db_obj = db

            store.driver.sqlite.Deploy(db).create()

            # mutes the pesky sqlite messages
            tmp = sys.stderr 
            sys.stderr = StringIO()
            session = store.driver.sqlite.Session(db,0)
            my_store = store.Store(session)
            sys.stderr = tmp

            all_funcs = database.functions()
            opt = {}
            opt['database'] = my_store

            self.store = my_store

            proc = self.provider.getArch()

            if proc == "pc":
                # XXX: hackish way to fix a crap ton of stuff...
                start = self.provider.segByBase(self.provider.segByName(".text"))
                end = self.provider.segEnd(self.provider.segByBase(self.provider.segByName(".text")))

                succeeded = 0
                for instr in self.provider.iterInstructions(start, end):
                    disasm = self.provider.getDisasm(instr)
                    tokens = disasm.split(" ")

                    res = []
                    for t in tokens:
                        if len(t) != 0:
                            res.append(t)

                    prologues = [['mov', 'edi,', 'edi'], ['push', 'ebp'], ['push', 'rbp']]

                    if res in prologues and instr not in all_funcs:
                        try:
                            prev_ea = self.provider.prevItem(instr, instr-0x20)
                            if prev_ea not in all_funcs:
                                if options['verbosity'] > 2:
                                    print "[!] Attempting to create a function at 0x%08x" % instr
                                ret = self.provider.makeFunc(instr)
                            else:
                                continue

                            if ret:
                                if options['verbosity'] > 2:
                                    print "[*] Successfully made new function at 0x%08x" % instr
                                succeeded += 1

                        except Exception as detail:
                            print detail
                            pass

                    elif "dup(90h)" in disasm:
                        if options['verbosity'] > 2:
                            print "Found dup at 0x%08x" % instr
                        try:
                            next_ea = self.provider.nextItem(instr, instr+0x20)

                            if next_ea not in all_funcs:
                                ret = self.provider.nextItem(next_ea, 0xFFFFFFFF)
                            else:
                                continue

                            if not ret and (next_ea in database.functions()) :
                                if options['verbosity'] > 2:
                                    print "[*] Successfully made new function at 0x%08x" % next_ea
                                succeeded += 1
                        except:
                            pass
                   
                if succeeded != 0:
                    print "[*] Successfully created %d new functions" % succeeded

            print "[*] There are %d funtions to process" % len(all_funcs)

            failed = 0
            succeeded = 0

            for i in xrange(0, len(all_funcs)):
    
                i_actual = i+1
                ea = all_funcs[i]
                if ((i_actual % 250 == 0) or (i == len(all_funcs)-1)):
                    print "[*] db.py: Processing 0x%08x (%d of %d)" % (ea, i_actual, len(all_funcs))

                analyza = analyze_xrefs(opt)
                collecta = collector(analyza, opt)

                try:
                    collecta.go(ea)
                    succeeded += 1
                
                except ValueError as detail:
                    failed += 1
                    if options['verbosity'] > 2:
                        print "0x%08x - failed to process node, %s" % (ea, detail)
                    
                opt['database'].commit()
            
            print "[*] Failed to process %d functions" % failed
            print "[*] Successfully processed %d functions" % succeeded

            # now loop imports
            segs = list(self.provider.getSegments())

            if proc in ["arm", "ppc", "mips"]:
                idata = "extern"
            elif proc == "pc":
                idata = ".idata"

            for s in segs:
                if self.provider.segName(s) == idata:
                    start = s
                    end = self.provider.segEnd(s)

                    for head in self.provider.iterData(start, end):
                        opt['database'].address(head)['name'] = self.provider.getName(head)

                        xrefs_to = database.cxup(head)

                        for x in xrefs_to:
                            try:
                                xref_top = function.top(x)
                            except ValueError: 
                                continue
                            context = opt['database'].c(xref_top)
                            context.address(x).edge((head, head))
            self.commit()


        else:
            db = store.sqlite3.connect(options['full_file_name'])
            self.db_obj = db

            # mutes the pesky sqlite messages
            tmp = sys.stderr
            sys.stderr = StringIO()
            session = store.driver.sqlite.Session(db,0)
            sys.stderr = tmp

            my_store = store.Store(session)
            self.store = my_store
Example #28
0
def rip_stackframes():
    '''Return all function frame's stack variables in a dict of lists'''
    return {ea: rip_frame(func.frame(ea)) for ea in db.functions()}
Example #29
0
def frames():
    '''Yields all the frames for each function within the database.'''
    for ea in db.functions():
        res = dict(frame(ea))
        if res: yield ea, res
    return
Example #30
0
    def __init__(self, options):
        self.options       = options
        self.provider      = ida.IDA()
        self.function_data = {}

        self.proc = self.provider.getArch()

        self.jmp_mnem = ""

        if self.proc == "pc":
            self.call_mnem = "call"
            self.jmp_mnem = "jmp"
        elif self.proc == "arm" or self.proc == "ppc":
            self.call_mnem = "bl"
        elif self.proc == "mips":
            self.call_mnem = "jalr"

        all_funcs = database.functions()

        if self.proc == "pc":
            # XXX: hackish way to fix a crap ton of stuff...
            start = self.provider.segByBase(self.provider.segByName(".text"))
            end = self.provider.segEnd(self.provider.segByBase(self.provider.segByName(".text")))

            succeeded = 0
            for instr in self.provider.iterInstructions(start, end):
                disasm = self.provider.getDisasm(instr)
                tokens = disasm.split(" ")

                res = []
                for t in tokens:
                    if len(t) != 0:
                        res.append(t)

                prologues = [['mov', 'edi,', 'edi'], ['push', 'ebp'], ['push', 'rbp']]

                if res in prologues and instr not in all_funcs:
                    try:
                        prev_ea = self.provider.prevItem(instr, instr-0x20)
                        if prev_ea not in all_funcs:
                            if options['verbosity'] > 2:
                                print "[!] Attempting to create a function at 0x%08x" % instr
                            ret = self.provider.makeFunc(instr)
                        else:
                            continue

                        if ret:
                            if options['verbosity'] > 2:
                                print "[*] Successfully made new function at 0x%08x" % instr
                            succeeded += 1

                    except Exception as detail:
                        pass

                elif "dup(90h)" in disasm:
                    if options['verbosity'] > 2:
                        print "Found dup at 0x%08x" % instr
                    try:
                        next_ea = self.provider.nextItem(instr, instr+0x20)

                        if next_ea not in all_funcs:
                            ret = self.provider.nextItem(next_ea, 0xFFFFFFFF)
                        else:
                            continue

                        if not ret and (next_ea in database.functions()) :
                            if options['verbosity'] > 2:
                                print "[*] Successfully made new function at 0x%08x" % next_ea
                            succeeded += 1
                    except:
                        pass
               
            if succeeded != 0:
                print "[*] Successfully created %d new functions" % succeeded

        print "[*] There are %d functions to process" % len(all_funcs)

        failed = 0
        succeeded = 0

        for i in xrange(0, len(all_funcs)):

            i_actual = i+1
            ea = all_funcs[i]
            if ((i_actual % 250 == 0) or (i == len(all_funcs)-1)):
                print "[*] RefTree.py: Processing 0x%08x (%d of %d)" % (ea, i_actual, len(all_funcs))
            
            props = analysis.properties(ea)
            func_props = props.funcProps()

            try:
                self.add_func(ea, func_props)
                succeeded += 1
            except Exception as detail:
                raise
       
            except ValueError as detail:
                failed += 1
                if options['verbosity'] > 2:
                    print "0x%08x - failed to process node, %s" % (ea, detail)     
        
        print "[*] Failed to process %d functions" % failed
        print "[*] Successfully processed %d functions" % succeeded

        # now loop imports
        segs = list(self.provider.getSegments())

        if self.proc in ["arm", "ppc", "mips"]:
            idata = "extern"
        elif self.proc == "pc":
            idata = ".idata"

        for s in segs:
            if self.provider.segName(s) == idata:
                start = s
                end = self.provider.segEnd(s)

                for head in self.provider.iterData(start, end):
                    try:
                        self.add_func(head)
                    except Exception:
                        raise
Example #31
0
    def __init__(self, options):
        self.options = options
        self.provider = ida.IDA()
        self.function_data = {}

        self.proc = self.provider.getArch()

        self.jmp_mnem = ""

        if self.proc == "pc":
            self.call_mnem = "call"
            self.jmp_mnem = "jmp"
        elif self.proc == "arm" or self.proc == "ppc":
            self.call_mnem = "bl"
        elif self.proc == "mips":
            self.call_mnem = "jalr"

        all_funcs = database.functions()

        if self.proc == "pc":
            # XXX: hackish way to fix a crap ton of stuff...
            start = self.provider.segByBase(self.provider.segByName(".text"))
            end = self.provider.segEnd(
                self.provider.segByBase(self.provider.segByName(".text")))

            succeeded = 0
            for instr in self.provider.iterInstructions(start, end):
                disasm = self.provider.getDisasm(instr)
                tokens = disasm.split(" ")

                res = []
                for t in tokens:
                    if len(t) != 0:
                        res.append(t)

                prologues = [['mov', 'edi,', 'edi'], ['push', 'ebp'],
                             ['push', 'rbp']]

                if res in prologues and instr not in all_funcs:
                    try:
                        prev_ea = self.provider.prevItem(instr, instr - 0x20)
                        if prev_ea not in all_funcs:
                            if options['verbosity'] > 2:
                                print "[!] Attempting to create a function at 0x%08x" % instr
                            ret = self.provider.makeFunc(instr)
                        else:
                            continue

                        if ret:
                            if options['verbosity'] > 2:
                                print "[*] Successfully made new function at 0x%08x" % instr
                            succeeded += 1

                    except Exception as detail:
                        pass

                elif "dup(90h)" in disasm:
                    if options['verbosity'] > 2:
                        print "Found dup at 0x%08x" % instr
                    try:
                        next_ea = self.provider.nextItem(instr, instr + 0x20)

                        if next_ea not in all_funcs:
                            ret = self.provider.nextItem(next_ea, 0xFFFFFFFF)
                        else:
                            continue

                        if not ret and (next_ea in database.functions()):
                            if options['verbosity'] > 2:
                                print "[*] Successfully made new function at 0x%08x" % next_ea
                            succeeded += 1
                    except:
                        pass

            if succeeded != 0:
                print "[*] Successfully created %d new functions" % succeeded

        print "[*] There are %d functions to process" % len(all_funcs)

        failed = 0
        succeeded = 0

        for i in xrange(0, len(all_funcs)):

            i_actual = i + 1
            ea = all_funcs[i]
            if ((i_actual % 250 == 0) or (i == len(all_funcs) - 1)):
                print "[*] RefTree.py: Processing 0x%08x (%d of %d)" % (
                    ea, i_actual, len(all_funcs))

            props = analysis.properties(ea)
            func_props = props.funcProps()

            try:
                self.add_func(ea, func_props)
                succeeded += 1
            except Exception as detail:
                raise

            except ValueError as detail:
                failed += 1
                if options['verbosity'] > 2:
                    print "0x%08x - failed to process node, %s" % (ea, detail)

        print "[*] Failed to process %d functions" % failed
        print "[*] Successfully processed %d functions" % succeeded

        # now loop imports
        segs = list(self.provider.getSegments())

        if self.proc in ["arm", "ppc", "mips"]:
            idata = "extern"
        elif self.proc == "pc":
            idata = ".idata"

        for s in segs:
            if self.provider.segName(s) == idata:
                start = s
                end = self.provider.segEnd(s)

                for head in self.provider.iterData(start, end):
                    try:
                        self.add_func(head)
                    except Exception:
                        raise