// GhidraScript: FindStringXrefs.java // Usage (headless): // analyzeHeadless -process \ // -scriptPath -postScript FindStringXrefs.java "" ["" ...] // // Prints the addresses where the ASCII needle is found (optionally with NUL terminator) // and lists the functions that reference the string address. import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Function; import ghidra.program.model.mem.Memory; import ghidra.program.model.symbol.Reference; import ghidra.program.model.symbol.ReferenceIterator; import java.nio.charset.StandardCharsets; import java.util.LinkedHashSet; public class FindStringXrefs extends GhidraScript { @Override public void run() throws Exception { String[] args = getScriptArgs(); if (args == null || args.length == 0) { printerr("FindStringXrefs: needs at least one ASCII needle arg"); return; } Memory mem = currentProgram.getMemory(); Address min = mem.getMinAddress(); Address max = mem.getMaxAddress(); for (String needle : args) { if (needle == null) continue; if (needle.isEmpty()) continue; println("=== needle: " + needle + " ==="); byte[] pat0 = needle.getBytes(StandardCharsets.US_ASCII); byte[] pat1 = new byte[pat0.length + 1]; System.arraycopy(pat0, 0, pat1, 0, pat0.length); pat1[pat1.length - 1] = 0; // First try NUL-terminated. int hits = 0; Address at = min; while (true) { Address found = mem.findBytes(at, max, pat1, null, true, monitor); if (found == null) break; hits++; dumpHit(found); at = found.add(1); } // If no NUL-terminated matches, fall back to raw bytes search. if (hits == 0) { at = min; while (true) { Address found = mem.findBytes(at, max, pat0, null, true, monitor); if (found == null) break; hits++; dumpHit(found); at = found.add(1); } } if (hits == 0) { println("(no hits)"); } println(""); } } private void dumpHit(Address strAddr) { println("hit @ " + strAddr); LinkedHashSet funcs = new LinkedHashSet<>(); ReferenceIterator it = currentProgram.getReferenceManager().getReferencesTo(strAddr); int nref = 0; while (it.hasNext()) { Reference r = it.next(); nref++; Function f = getFunctionContaining(r.getFromAddress()); if (f != null) { funcs.add(f.getName() + " @ " + f.getEntryPoint()); } else { funcs.add("(no func) from " + r.getFromAddress()); } if (nref > 2000) break; // avoid pathological spam } println("refs: " + nref); for (String s : funcs) { println(" " + s); if (funcs.size() > 200) break; } } }