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
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()
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
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
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()
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()
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
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()
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
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()
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()
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
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
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
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
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
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()
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)
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
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
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)
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
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()}
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
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
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