# Ghidra headless script: decompile a target list of IL2CPP functions to C. # @category il2cpp # Reads ghidra/targets.txt (rvaname), creates+names+decompiles each, # dumps all C to ghidra/decomp.c for offline grepping. import time from ghidra.app.decompiler import DecompInterface from ghidra.util.task import ConsoleTaskMonitor from ghidra.program.model.symbol import SourceType ROOT = "/home/downloadpizza/sand_tools/ghidra" base = currentProgram.getImageBase() decomp = DecompInterface() decomp.openProgram(currentProgram) monitor = ConsoleTaskMonitor() out = open(ROOT + "/decomp.c", "w") n = 0 ok = 0 t0 = time.time() fp = open(ROOT + "/targets.txt") for line in fp: line = line.rstrip("\n") if not line: continue rva, name = line.split("\t", 1) # ascii-sanitize: obfuscated names use Cyrillic look-alikes -> replace name = "".join((ch if ord(ch) < 128 else "_") for ch in name) addr = base.add(int(rva)) fn = getFunctionAt(addr) if fn is None: disassemble(addr) createFunction(addr, name) fn = getFunctionAt(addr) n += 1 if fn is None: continue try: fn.setName(name, SourceType.USER_DEFINED) except: pass try: res = decomp.decompileFunction(fn, 25, monitor) if res is not None and res.decompileCompleted(): c = res.getDecompiledFunction().getC() c = "".join((ch if ord(ch) < 128 else "_") for ch in c) out.write("\n// ==== %s @ +0x%x ====\n" % (name, int(rva))) out.write(c) ok += 1 except Exception, e: pass if n % 1000 == 0: out.flush() print("processed %d ok %d (%.0fs)" % (n, ok, time.time() - t0)) fp.close() out.close() print("DONE processed %d ok %d in %.0fs" % (n, ok, time.time() - t0))