46 lines
1.6 KiB
Python
Executable file
46 lines
1.6 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""Find strings matching a regex and decompile their referencing functions.
|
|
|
|
Usage: dump-like launcher args: <elf> <proj_dir> <proj_name> <regex> [max_funcs]
|
|
"""
|
|
import re
|
|
import sys
|
|
|
|
import pyghidra
|
|
|
|
pyghidra.start()
|
|
|
|
from ghidra.app.decompiler import DecompInterface # noqa: E402
|
|
from ghidra.util.task import ConsoleTaskMonitor # noqa: E402
|
|
|
|
elf, proj_dir, proj_name, pat = sys.argv[1:5]
|
|
maxf = int(sys.argv[5]) if len(sys.argv) > 5 else 3
|
|
|
|
with pyghidra.program_context(pyghidra.open_project(
|
|
__import__('os').path.abspath(proj_dir), proj_name),
|
|
'/' + __import__('os').path.basename(elf)) as prog:
|
|
listing = prog.getListing()
|
|
fm = prog.getFunctionManager()
|
|
rm = prog.getReferenceManager()
|
|
rx = re.compile(pat)
|
|
dec = DecompInterface()
|
|
dec.openProgram(prog)
|
|
seen = set()
|
|
for d in listing.getDefinedData(True):
|
|
dt = d.getDataType().getName().lower()
|
|
if 'string' not in dt and 'char' not in dt:
|
|
continue
|
|
v = d.getValue()
|
|
if v is None or not rx.search(str(v)):
|
|
continue
|
|
print('STRING %s %r' % (d.getAddress(), str(v)[:100]))
|
|
for ref in rm.getReferencesTo(d.getAddress()):
|
|
f = fm.getFunctionContaining(ref.getFromAddress())
|
|
if f is None or f.getEntryPoint() in seen:
|
|
continue
|
|
seen.add(f.getEntryPoint())
|
|
print(' <- %s %s' % (f.getEntryPoint(), f.getName()))
|
|
if len(seen) <= maxf:
|
|
r = dec.decompileFunction(f, 90, ConsoleTaskMonitor())
|
|
if r.decompileCompleted():
|
|
print(r.getDecompiledFunction().getC()[:6000])
|