// SPDX-License-Identifier: BSD-3-Clause // // ConfigureAnalysis.java - Ghidra pre-script used by the Open-IOV CUDA // tooling to make headless auto-analysis of a large stripped vendor library // tractable and reproducible. // // The CUDA userspace driver is a ~70 MB, fully stripped x86-64 shared object // with roughly a hundred thousand functions. The default analyzer set spends // the majority of its time in the two optional "identifier" analyzers, which // are not needed to obtain readable decompilation: // // * Decompiler Parameter ID - decompiles every function to recover // parameter types (very expensive, no value // for a stripped binary where we have no // type definitions for internal structs) // * Function ID (FID) - matches function bodies against .fidb // signature databases (liberal, and we have // no curated database for this toolchain) // // Everything else (disassembly, function start search, aggressive instruction // finder, exception handling, stack analysis, reference analyzers, ...) is // kept, because function discovery quality on a stripped binary depends on // them. // // Usage (analyzeHeadless): // -preScript ConfigureAnalysis.java [verbose] // // Re-runnable: the same settings are applied on every analysis of a program. import ghidra.app.script.GhidraScript; import ghidra.framework.options.Options; public class ConfigureAnalysis extends GhidraScript { private static final String[] DISABLE = { "Decompiler Parameter ID", "Function ID", }; private static final String[] ENABLE = { "Aggressive Instruction Finder", "GCC Exception Handlers", "Function Start Search", "Shared Return Calls", "Non-Returning Functions - Known", "Non-Returning Functions - Discovered", }; @Override public void run() throws Exception { boolean verbose = getScriptArgs().length > 0; Options opts = currentProgram.getOptions("Analyzers"); if (verbose) { println("[ConfigureAnalysis] analyzer options before:"); for (String name : opts.getOptionNames()) { println(" " + name + " = " + opts.getObject(name, null)); } } for (String name : DISABLE) { if (opts.contains(name)) { opts.setBoolean(name, false); println("[ConfigureAnalysis] disabled: " + name); } else { println("[ConfigureAnalysis] WARN not found: " + name); } } for (String name : ENABLE) { if (opts.contains(name)) { opts.setBoolean(name, true); println("[ConfigureAnalysis] enabled: " + name); } } if (verbose) { println("[ConfigureAnalysis] analyzer options after:"); for (String name : opts.getOptionNames()) { println(" " + name + " = " + opts.getObject(name, null)); } } } }