// GhidraScript: decompile one function and print matching lines with context. // Usage: DecompileSearch.java 0x005ed4c0 0x104 8 import ghidra.app.decompiler.DecompInterface; import ghidra.app.decompiler.DecompileResults; import ghidra.app.script.GhidraScript; import ghidra.program.model.listing.Function; public class DecompileSearch extends GhidraScript { @Override public void run() throws Exception { String[] args = getScriptArgs(); if (args == null || args.length < 2) { printerr("DecompileSearch: needs address, text, and optional context-line count"); return; } Function function = getFunctionContaining(toAddr(Long.decode(args[0]))); if (function == null) { printerr("function not found"); return; } int context = args.length > 2 ? Integer.decode(args[2]) : 5; DecompInterface decomp = new DecompInterface(); decomp.openProgram(currentProgram); DecompileResults result = decomp.decompileFunction(function, 120, monitor); if (!result.decompileCompleted()) { printerr("decompile failed"); return; } String[] lines = result.getDecompiledFunction().getC().split("\\R"); boolean[] selected = new boolean[lines.length]; for (int i = 0; i < lines.length; ++i) { if (!lines[i].contains(args[1])) continue; for (int j = Math.max(0, i - context); j <= Math.min(lines.length - 1, i + context); ++j) { selected[j] = true; } } println("function: " + function.getName() + " @ " + function.getEntryPoint()); boolean gap = false; for (int i = 0; i < lines.length; ++i) { if (selected[i]) { if (gap) println("..."); println(String.format("%5d %s", i + 1, lines[i])); gap = false; } else if (i > 0 && selected[i - 1]) { gap = true; } } } }