Initial public source release

Split reusable rendering and format support into vectorail-core and vectorail-gc.
This commit is contained in:
2026-08-02 17:05:27 +02:00
commit 831d96e562
109 changed files with 20558 additions and 0 deletions
+96
View File
@@ -0,0 +1,96 @@
// GhidraScript: FindStringXrefs.java
// Usage (headless):
// analyzeHeadless <projDir> <projName> -process <progName> \
// -scriptPath <path> -postScript FindStringXrefs.java "<needle1>" ["<needle2>" ...]
//
// 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<String> 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;
}
}
}