Skip to main content

Crate ghidra_worker_ctl

Crate ghidra_worker_ctl 

Source
Expand description

Worker lifecycle + boot orchestration. The pure state machine (state) plus the OS-facing boot path: config/argv (config), token handshake (token), spawn + pipe drain (launch), the Windows Job Object kill-guard (job_object), framed TCP transport (conn), and boot/handshake (boot). Health-driven RESPAWN wiring (re-boot a crashed worker mid-session) is still M1.

Modules§

boot
Boot orchestration (spec §4/§5). Host is the TCP server; the worker connects back and proves itself with a token+version init handshake. A racing local process without the token is rejected and the accept loop keeps going until the boot deadline (agy risk note A: a silent stall here is often an EDR/firewall intercept of the unsigned Java process, not a code bug — check that first).
config
Worker launch configuration + launcher argv (spec §3/§4). The argv build is a pure function so it is unit-tested without a Ghidra install. Attach-only (-process, not -import) because v1 attaches to already-analyzed projects (spec §8.1); writable (NOT -readOnly) since M2a’s rename write tool needs DomainFile.save(); the worker .java blocks in its socket loop so analyzeHeadless never returns and the JVM stays resident (spike D1).
conn
Framed JSON-RPC 2.0 request/response over the worker’s TCP stream (spec §5). One request in flight at a time (the worker services calls single-threaded on the Ghidra thread). Uses the existing ghidra-ipc frame codec (4-byte BE length prefix) and RpcRequest/RpcResponse types.
job_object
Re-export shim. The kill-guard moved to the proc-guard crate, but crate::job_object::JobObject stays a stable path for the worker lifecycle (launch.rs) — on Windows a Job Object with KILL_ON_JOB_CLOSE, on Unix a setsid process group, and a no-op stub everywhere else.
launch
Spawn the headless launcher and shield host stdout (spike D4). Both child pipes are drained on dedicated threads into the host’s STDERR so ~16 KB of Ghidra log spam per run never contaminates host stdout (reserved for MCP JSON-RPC, M1). The child is wrapped in a kill-guard (Windows Job Object or Unix process group) so the whole host->shell->java.exe tree dies with the host. On targets that are neither (e.g. WASM) the guard is a no-op and that guarantee does not hold: only the direct child is killed when WorkerProcess is dropped.
state
Pure worker-lifecycle state machine (spec §4). No I/O: models the states and the one-shot WORKER_RESTARTED notice so lifecycle decisions are unit-testable without spawning a JVM.
token
Connection token for the loopback-TCP transport (spec §5/§6). The host generates a 128-bit token, hands it to the worker out-of-band via a short-lived 0600 file, and verifies the worker echoes it in the init handshake — so another local process that races the ephemeral port is rejected. Not a long-term secret: it exists only for the boot window and the file is deleted right after the handshake (see boot.rs).