From a Good Investigation to a Repeatable One
Ghidra's automation surfaces answer a practical question: how can a validated analytical decision be repeated across files without turning an unexamined assumption into a large batch of results? This chapter focuses on the Headless Analyzer, PyGhidra, and GhidraDev's script and module paths. The reader will see what makes headless work a real pipeline, how to choose between Python, runtime scripts, and installable modules, and why logging, timeouts, read-only operation, and deletion controls are part of analytical quality.
Headless analysis is a controlled pipeline
Headless Ghidra is not simply the graphical interface with its windows hidden. The Headless Analyzer can create or populate projects, import or process files and directories, run scripts before and after analysis, enable or disable analysis, write logs, operate read-only, set an analysis timeout, and connect to a shared repository. Those controls turn an interactive sequence into a workflow with explicit inputs, stages, outputs, and failure conditions.
The first choice is whether the run is importing new inputs or processing programs that already exist in a project. Import mode establishes the program and can apply a loader, processor language, compiler context, and library search choices. Process mode works on existing programs and can run scripts or analysis over a selected file, folder, or recursive set. This distinction matters because the object being changed is different: one path creates or saves a new program, while the other modifies an existing analytical artifact.
Scripts can run before analysis, after analysis, or in both positions. A pre-script can prepare context or decide whether analysis should run. Analysis then adds the selected structures to the program. A post-script can inspect results, record findings, or decide how the program should be saved. Scripts execute in the order specified for their stage, so the pipeline has a causal sequence rather than a bag of independent hooks.
That ordering lets a workflow separate eligibility from interpretation. A pre-script might check whether an input belongs to the expected set, choose a project location, or establish a condition that must hold before expensive analysis begins. The analysis stage can then run under that declared context. A post-script can inspect whether the expected structure was produced and choose whether to preserve it, continue with another script, or stop. The important design question is not how many scripts a run contains, but which state each script expects and which later state it is allowed to change.
For a directory of related binaries, this separation also prevents a convenient batch loop from hiding per-file differences. One file may import successfully while another needs a different loader option or exceeds the analysis time budget. A post-script can record the difference, and a read-only diagnostic run can test the workflow before it writes results. The batch remains repeatable because the exception is represented as part of the pipeline rather than silently absorbed into a generic success message.