Skip to content

Don't let a filename Ghidra dislikes kill the server - #229

Open
subwire wants to merge 1 commit into
mainfrom
ghidra-sanitize-program-name
Open

Don't let a filename Ghidra dislikes kill the server#229
subwire wants to merge 1 commit into
mainfrom
ghidra-sanitize-program-name

Conversation

@subwire

@subwire subwire commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Problem

Ghidra validates project and program names and rejects certain characters. Both names are derived from the binary's file name, so a crackme called timo#3 throws from inside the import:

java.lang.IllegalArgumentException: name contains invalid character: '#'

The caller sees only:

Decompiler server c3b08ec63d exited with status 1 before registering.

The real reason is buried in the server log, and the only workaround available to an analyst is to rename the file.

Seen in the wild

Caught on a 40-binary benchmark run. An agent hit this, diagnosed it, and worked around it by copying timo#3 to timo3_working_copy and loading that instead. It recovered — after several minutes and a backend switch.

Worth noting how it got there: it had preferred IDA (as SKILL.md says to), IDA crashed on this binary, it fell back to Ghidra, and then hit this. Two failures compounding.

Change

Sanitize the derived project/program names; leave the path on disk alone. The binary is still opened by its real path — only the names handed to Ghidra change. An explicitly-passed project_name/program_name is sanitized too, since it lands in the same validator.

Verified against the binary that failed — it now loads and lists functions normally:

BEFORE: Failed to start server: java.lang.IllegalArgumentException: ... '#'
AFTER:  { "status": "started", ... }   →  list_functions returns 392 bytes at 0x1000

Tests

Three: rejected characters are replaced; ordinary names (including spaces, dots, dashes) are untouched; degenerate input never yields an empty name, which Ghidra also rejects.

🤖 Generated with Claude Code

Ghidra validates project and program names and rejects a set of
characters outright. Both names are derived from the binary's file name,
so a crackme called `timo#3` throws

    java.lang.IllegalArgumentException: name contains invalid character: '#'

from inside the import. That reaches the caller only as "server exited
with status 1 before registering", with the real reason buried in the
server log -- and the sole workaround available to an analyst is to
rename the file.

Caught on a benchmark run, where an agent did exactly that: it hit the
error, then copied `timo#3` to `timo3_working_copy` and loaded that
instead. It recovered, but spent several minutes and a backend
switch to do it.

Filenames are not ours to choose -- CTF and crackme corpora are full of
them -- so sanitize the derived names and leave the path on disk alone.
The binary is still opened by its real path; only the names handed to
Ghidra change.

Verified against the binary that failed: it now loads and its functions
list normally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant