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
python类decompile()的实例源码
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: 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: 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 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 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 decompile(cls):
'''(UNSTABLE) Returns the decompiled code of the basic-block at the current address.'''
return cls.decompile(ui.current.address())
def decompile(cls):
'''(UNSTABLE) Returns the decompiled code of the basic-block at the current address.'''
return cls.decompile(ui.current.address())
def decompile(cls):
'''(UNSTABLE) Returns the decompiled code of the basic-block at the current address.'''
return cls.decompile(ui.current.address())
def decompile(cls):
'''(UNSTABLE) Returns the decompiled code of the basic-block at the current address.'''
return cls.decompile(ui.current.address())
def decompile(cls):
'''(UNSTABLE) Returns the decompiled code of the basic-block at the current address.'''
return cls.decompile(ui.current.address())
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