我们从Python开源项目中,提取了以下32个代码示例,用于说明如何使用idaapi.decompile()。
def find_qmemcpy(): hex = '{:x}'.format for f in db.functions.iterate(): try: res = idaapi.decompile(f) qmemcpys = [x for x in re.findall('printf\(.*?;', str(res)) if 'sizeof' not in x] # heads = re.findall('::Next', str(res)) if not qmemcpys: continue print(hex(f), func.name(f)) for q in qmemcpys: print(q) except: pass # Natus
def decompile(cls, ea): '''(UNSTABLE) Returns the decompiled code of the basic-block at the address ``ea``.''' source = idaapi.decompile(ea) res = map(functools.partial(operator.__getitem__, source.eamap), cls.iterate(ea)) res = itertools.chain(*res) formatted = reduce(lambda t,c: t if t[-1].ea == c.ea else t+[c], res, [next(res)]) res = [] # FIXME: pretty damn unstable try: for fmt in formatted: res.append( fmt.print1(source.__deref__()) ) except TypeError: pass return '\n'.join(map(idaapi.tag_remove,res)) # function frame attributes # FIXME: put these in their own object and replace them with aliases
def decompile(cls, ea): '''(UNSTABLE) Returns the decompiled code of the basic-block at the address ``ea``.''' source = idaapi.decompile(ea) res = map(functools.partial(operator.__getitem__, source.eamap), cls.iterate(ea)) res = itertools.chain(*res) formatted = reduce(lambda t,c: t if t[-1].ea == c.ea else t+[c], res, [next(res)]) res = [] # FIXME: This is pretty damn unstable in my tests. try: for fmt in formatted: res.append( fmt.print1(source.__deref__()) ) except TypeError: pass return '\n'.join(map(idaapi.tag_remove,res)) # function frame attributes # FIXME: put these in their own object and replace them with aliases
def activate(self, ctx): for idx in ctx.chooser_selection: func_ea = idaapi.getn_func(idx - 1).startEA try: cfunc = idaapi.decompile(func_ea) if cfunc is None: continue FunctionTouchVisitor(cfunc).process() lvars = cfunc.get_lvars() if not (lvars and lvars[0].is_arg_var and Helper.is_legal_type(lvars[0].type())): continue scanner = DeepSearchVisitor(cfunc, 0, 0) scanner.process() for field in scanner.candidates: self.temporary_structure.add_row(field) except idaapi.DecompilationFailure: print "[Warning] Failed to decompile function at 0x{0:08X}".format(func_ea)
def scan_function(self, ea, offset, arg_index): # Function for recursive search structure's members if Helper.is_imported_ea(ea): return if (ea, arg_index, self.origin + offset) in scanned_functions: return try: scanned_functions.add((ea, arg_index, self.origin + offset)) new_function = idaapi.decompile(ea) if new_function: print "[Info] Scanning function {name} at 0x{ea:08X}, origin: 0x{origin:04X}".format( name=idaapi.get_short_name(ea), ea=ea, origin=self.origin + offset ) scanner = DeepSearchVisitor(new_function, self.origin + offset, arg_index) scanner.apply_to(new_function.body, None) self.candidates.extend(scanner.candidates) except idaapi.DecompilationFailure: print "[ERROR] Ida failed to decompile function at 0x{0:08X}".format(ea)
def decompile(self): """ decompile function """ try: return idaapi.decompile(self.at) except idaapi.DecompilationFailure, e: return repr(str(e)) text = str(idaapi.decompile(self.at)).strip() ''' sprintf: Python>for w in idaapi.decompile(0x00001578 ).lvars: print w.name s format result ''' # decompile.arguments # for w in idaapi.decompile(0x00001EF0 ).lvars: print w.name if not grep: return text.split('\n') # return all lines return [line.strip() for line in text.split('\n') if grep in line]
def exec_ida_batch_decompile(self, target, output, annotate_stackvar_size, annotate_xrefs, imports, recursive, experimental_decomile_cgraph): logger.debug("[+] batch decompile %r" % target) # todo: pass commandlines, # todo parse commandline script_args = ['--output=%s' % output] if annotate_stackvar_size: script_args.append("--annotate-stackvar-size") if annotate_xrefs: script_args.append("--annotate-xrefs") if imports: script_args.append("--imports") if recursive: script_args.append("--recursive") if experimental_decomile_cgraph: script_args.append("--experimental-decompile-cgraph") script_args = ['\\"%s\\"' % a for a in script_args] command = "%s %s" % (self.my_path, ' '.join(script_args)) self._exec_ida_batch(target, command)
def _refs_to_tablegroup(self): from itertools import chain if self.tablegroup is None: return [] candidates = [] # For now just use the first table array primary_table = self.tablegroup.primary_table() # When debug symbols are present, the decompile will usually # refer to the function table as an offset from the start # of the vtable, so also allow references to that. references = chain(idautils.XrefsTo(primary_table.address_point), idautils.XrefsTo(self.tablegroup.ea)) for ref in references: start = as_signed(idc.GetFunctionAttr(ref.frm, idc.FUNCATTR_START), TARGET_ADDRESS_SIZE) if start == -1: continue candidates.append(start) return candidates
def find_cfunc(ea): """Get cfuncptr_t from EA.""" func = idaapi.get_func(ea) if func: return idaapi.decompile(func)
def decompile_funcs(): data = open("G:\\targets\\blender\\done_decompile", 'r').read() for f in db.functions.iterate(): try: if str(f) in data: continue res = idaapi.decompile(f) with open("G:\\targets\\blender\\done_decompile", "a") as new_file: new_file.write(str(f) + '\n') filename = "G:\\targets\\blender\\decompiles\\{}".format(func.name(f)) with open(filename, "wb") as new_file: new_file.write(str(res)) except Exception as e: print("ERROR: {} - {}".format(func.name(f), e))
def decompile(cls): '''(UNSTABLE) Returns the decompiled code of the basic-block at the current address.''' return cls.decompile(ui.current.address())
def activate(self, ctx): hx_view = idaapi.get_tform_vdui(ctx.form) address = hx_view.cfunc.entry_ea xref_ea = idaapi.get_first_cref_to(address) xrefs = set() while xref_ea != idaapi.BADADDR: xref_func_ea = idc.GetFunctionAttr(xref_ea, idc.FUNCATTR_START) if xref_func_ea != idaapi.BADADDR: xrefs.add(xref_func_ea) else: print "[Warning] Function not found at 0x{0:08X}".format(xref_ea) xref_ea = idaapi.get_next_cref_to(address, xref_ea) for func_ea in xrefs: visitor = VariableLookupVisitor(address) try: cfunc = idaapi.decompile(func_ea) if cfunc: FunctionTouchVisitor(cfunc).process() visitor.apply_to(cfunc.body, None) for idx in visitor.result: scanner = DeepSearchVisitor(cfunc, 0, idx) scanner.process() for field in scanner.candidates: self.temporary_structure.add_row(field) except idaapi.DecompilationFailure: print "[Warning] Failed to decompile function at 0x{0:08X}".format(xref_ea) DeepSearchVisitor.clear()
def touch_all(self): for address in self.functions.difference(touched_functions): touched_functions.add(address) try: cfunc = idaapi.decompile(address) if cfunc: FunctionTouchVisitor(cfunc).process() except idaapi.DecompilationFailure: print "[ERROR] IDA failed to decompile function at 0x{address:08X}".format(address=address) idaapi.decompile(self.cfunc.entry_ea)
def tinfo(self): try: decompiled_function = idaapi.decompile(self.address) if decompiled_function: return idaapi.tinfo_t(decompiled_function.type) return Const.DUMMY_FUNC except idaapi.DecompilationFailure: pass print "[ERROR] Failed to decompile function at 0x{0:08X}".format(self.address) return Const.DUMMY_FUNC
def open_function(self): if self.address: if idaapi.decompile(self.address): idaapi.open_pseudocode(self.address, 0) else: idaapi.jumpto(self.address)
def run(self): files_decompiled = [] self._init_target() if self.chk_decompile_imports: self.init_tempdir() if self.chk_decompile_imports_recursive: pass for image_type, image_name, image_path in self.enumerate_import_images(): try: self.exec_ida_batch_decompile(target = image_path, output = self.output_path, annotate_stackvar_size = self.chk_annotate_stackvar_size, annotate_xrefs = self.chk_annotate_xrefs, imports = self.chk_decompile_imports, recursive = self.chk_decompile_imports_recursive, experimental_decomile_cgraph = self.chk_decompile_alternative) files_decompiled.append(image_path) except subprocess.CalledProcessError, cpe: logger.warning("[!] failed to decompile %r - %r" % (image_path, cpe)) self.remove_tempdir() if self.chk_annotate_stackvar_size: self.annotate_stack_variable_size() if self.chk_annotate_xrefs: self.annotate_xrefs() if self.chk_decompile_alternative: raise NotImplemented("Not yet implemented") pass else: self.decompile_all(self.output_path) files_decompiled.append(self.target_file) logger.info("[+] finished decompiling: %r" % files_decompiled) logger.info(" output dir: %s"%self.output_path if self.output_path else self.target_dir) return files_decompiled
def decompile_all(self, outfile=None): outfile = self._get_suggested_output_filename(outfile or self.target_path) logger.warning(outfile) logger.debug("[+] trying to decompile %r as %r" % (self.target_file, os.path.split(outfile)[1])) IdaHelper.decompile_full(outfile) logger.debug("[+] finished decompiling %r as %r" % (self.target_file, os.path.split(outfile)[1]))
def __init__(self, idbctrl, enumerate_imports=True, enumerate_other=False): self.idbctrl = idbctrl self.EChooser = TestEmbeddedChooserClass("Batch Decompile", flags=Choose2.CH_MULTI) self.propagateItems(enumerate_imports=enumerate_imports, enumerate_other=enumerate_other) Form.__init__(self, r"""Batch Decompile ... {FormChangeCb} <##Target :{target}> <##OutputPath:{outputPath}> <##Annotate StackVar Size:{chkAnnotateStackVars}> <##Annotate Func XRefs :{chkAnnotateXrefs}> <##Process Imports :{chkDecompileImports}> <##Cgraph (experimental) :{chkDecompileAlternative}>{cGroup1}> <##Scan Target Directory:{btnLoad}> <##Recursive:{chkDecompileImportsRecursive}>{cGroup2}> <##Decompile!:{btnProcessFiles}> <Please select items to decompile:{cEChooser}> """, { 'target': Form.FileInput(swidth=50, open=True, value=idbctrl.target_path), 'outputPath': Form.DirInput(swidth=50, value=idbctrl.output_path), 'cGroup1': Form.ChkGroupControl(("chkAnnotateStackVars", "chkAnnotateXrefs", "chkDecompileImports", "chkDecompileAlternative")), 'cGroup2': Form.ChkGroupControl(("chkDecompileImportsRecursive", )), 'FormChangeCb': Form.FormChangeCb(self.OnFormChange), 'btnLoad': Form.ButtonInput(self.OnButtonLoad), 'btnProcessFiles': Form.ButtonInput(self.OnButtonProcess), 'cEChooser': Form.EmbeddedChooserControl(self.EChooser), }) self.Compile()
def copy_function(addr): func_addr = idc.LocByName(idaapi.get_func_name(addr)) if func_addr == idaapi.BADADDR: idaapi.msg("0x%08X does not belong to a defined function\n" % addr) return callTypes = ["__cdecl", "__fastcall", "__stdcall", "__thiscall", "__usercall"] funcDef = str(idaapi.decompile(func_addr)).split('\n', 1)[0] hasCallType = any(call_type in funcDef for call_type in callTypes) parenthesesStart = funcDef.find('(') parenthesesEnd = funcDef.rfind(')') funcNameStart = funcDef[0 : parenthesesStart].rfind(' ') funcNameEnd = parenthesesStart returnTypeStart = 0 returnTypeEnd = funcNameStart callType = "" if hasCallType: callTypeStart = funcDef[0 : funcNameStart].rfind(' ') callType = funcDef[callTypeStart + 1 : funcNameStart] returnTypeEnd = callTypeStart if callType == "__cdecl": callType = "" returnType = funcDef[returnTypeStart : returnTypeEnd] funcName = funcDef[funcNameStart + 1 : parenthesesStart] args = funcDef[parenthesesStart + 1 : parenthesesEnd] finalString = "{0} ({1}* {2})({3}) = ({0}({1}*)({3}))({4});".format( returnType, callType, funcName, args, "0x%08X" % func_addr ) return finalString
def print_ast(ea): cfunc = idaapi.decompile(ea) printer = ast_printer_t() printer.apply_to_exprs(cfunc.body, None)
def export_pseudocomments_from_fun(f_ea): d = {} d[f_ea] = {} #f_ea = 0x040033EC print "Attempting to decompile %x" % f_ea try: ct = idaapi.decompile(f_ea) except idaapi.DecompilationFailure: print "error during decompilation (IDA API)" return d user_cmts = ct.user_cmts num_cmts = idaapi.user_cmts_size(user_cmts) #export_user_variables(ct, f_ea) print "Function 0x%08x has %d pseudocomments" % (f_ea, num_cmts) it = idaapi.user_cmts_begin(user_cmts) #while it != idaapi.user_cmts_end(user_cmts) i = 0 while (i < num_cmts): t = idaapi.user_cmts_first(it) #treeloc_t c = idaapi.user_cmts_second(it) #user_cmts_t print "Comment: %s at addr: 0x%08x itp: %d" % (c.c_str(), t.ea, t.itp) d[f_ea][i] = {"ea" : t.ea, "comment": c.c_str(), "itp": t.itp} i += 1 it = idaapi.user_cmts_next(it) return d
def import_pseudocomments_to_fun(f_ea, d): if d == {}: #print "skipping %x, empty" % f_ea return print "Attempting to decompile %x" % f_ea try: ct = idaapi.decompile(f_ea) except idaapi.DecompilationFailure: print "error during decompilation (IDA API)" return # i dont know when this happens, but for 404E1404, which is not really a function # this is triggered if not ct or ct.user_cmts == None: print "failed obtaining user cmts at %x" % f_ea return user_cmts = ct.user_cmts it = idaapi.user_cmts_begin(user_cmts) for i in d.iterkeys(): t = idaapi.treeloc_t() t.ea = d[i]["ea"] t.itp = d[i]["itp"] c = idaapi.citem_cmt_t(d[i]["comment"]) idaapi.user_cmts_insert(user_cmts, t, c)
def parents_from_destructors(type): ''' Finds the direct parents of the Type associated with ``tablegroup`` by examining function calls in its destructor. ''' def get_type_having_destructor(func_ea): for type in Types(): if func_ea in type.destructors(): return type return None class destructor_finder_t(idaapi.ctree_visitor_t): def __init__(self, ea): idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST) def visit_expr(self, e): if e.op == idaapi.cot_call: # Destructors only take 1 arg if len(e.a) != 1: return 0 elif e.a[0].v is None or e.a[0].v.idx != 0: return 0 addr = e.x.obj_ea type = get_type_having_destructor(addr) if type is None: return 0 parents.append(type) return 0 elif e.op == idaapi.cot_asg: pass return 0 def leave_expr(self, e): if e.op == idaapi.cot_call: self.destructor_candidate = None destructors = type.destructors() if len(destructors) == 0: return [] #TODO: consider other candidates destructor = destructors[0] parents = [] try: cfunc = idaapi.decompile(destructor); except idaapi.DecompilationFailure: return [] iff = destructor_finder_t(destructor) iff.apply_to(cfunc.body, None) return parents