Conversation
- Rename Docker container from ctf-re to toolbox in all configs and docs - Fix Ghidra headless MCP startup: build proper classpath with Ghidra runtime jars (Framework, Features, Processors, Debug), use com.xebyte.headless.GhidraMCPHeadlessServer entry point, bind to loopback only, add JVM flags (-Xmx4g -XX:+UseG1GC) - Robust headless JAR discovery: check target/archive-tmp first, then target/*Headless*.jar, fall back to largest jar in target/ - Simplify ghidra-headless bridge config: pass GHIDRA_MCP_URL via env var instead of --ghidra-server CLI arg; remove ghidra-gui entry (GUI bridge belongs in user's local config, not base config)
…for improved performance
…me split Split single-stage Dockerfile into 7 stages: - base: runtime OS packages only (no build toolchain), BinDiff - base-build: extends base with gcc/cmake/maven/autotools (~400MB, discarded after build) - python: angr, pwntools, frida, MCP stack (all pip packages pinned) - r2-ghidra: radare2 + r2pm plugins, Ghidra headless, ghidra-mcp - fuzzing: AFL++, honggfuzz (prefixed to /opt/tools/fuzzing) - android: platform-tools, apktool, jadx - final: FROM base, COPY --from each builder, scripts, configs All tools pinned to exact versions via ARGs — builds are reproducible. Bump a version, only that stage + final rebuilds. Final image ~400MB smaller: gcc, cmake, maven, llvm-dev, autotools never ship (they live only in base-build, discarded after build).
build.yml: triggers on push/PR to main, builds image with BuildKit + GHA cache, push: false. Fails fast if Dockerfile breaks. release.yml: triggers on tag push (v*.*.* / v*.*), builds + pushes to ghcr.io with semver tags (major, major.minor, version). Uses GITHUB_TOKEN for auth — no extra secrets needed.
Docker 23.0+ (BuildKit default), Compose 2.0+ (Compose V2). Fallback for Docker 18.09-22.x: export DOCKER_BUILDKIT=1.
angr 9.2.194 pins capstone==5.0.3, unicorn==2.1.1, etc. — installing capstone==5.0.5 alongside angr causes ResolutionImpossible. Let pip resolve capstone, unicorn, claripy, pyelftools, z3-solver (angr's transitive deps). Keep pins on top-level packages only. Also fix typo: PWNYOOLS_VERSION -> PWNTOOLS_VERSION.
All modified files had CRLF from Windows mount. Renormalized to LF. Added .gitattributes with '* text=auto eol=lf' + explicit rules for .sh, .py, .json, .yml, Dockerfile, .md to prevent recurrence.
2.5 may have build issues on Ubuntu 24.04's toolchain. Split RUN into build + install steps for clearer error attribution.
ghidra-mcp v5.13.1 dropped the --ghidra-server CLI flag. The bridge now reads GHIDRA_MCP_URL from the environment instead. Updated all 3 README examples to match configs/base.json.
Refactor removed the timeout wrapping — exec() ran unbounded. A blocking analysis or while True: pass would hang the server until killed. Run exec() via asyncio.to_thread wrapped in asyncio.wait_for(timeout). On timeout: returns error, server stays responsive. Thread keeps running (Python limitation) but MCP no longer hangs.
Binding to 127.0.0.1 inside the container rejects connections from host port forwarding (Docker connects to container's non-loopback interface). Bind to 0.0.0.0 so curl http://localhost:8089 works from the host as documented in README, while internal bridge at 127.0.0.1:8089 still works.
… angr MCP Drop custom angr-mcp, fuzz-mcp, python-mcp servers. angr ships its own MCP (python -m angr.mcp). Shell MCP covers everything else. Remove fuzz-init.sh and angr-solve.py CLI wrappers — direct CLI invocation preferred. Cap shell-mcp timeout at 300s. Document angr built-in MCP and C compile/run MCP in README.
…deps - Keep radare2-src after sys/install.sh — binaries symlink to it - Patch r2mcp: r_core_call_str_at → r_core_cmd_str_at for radare2 6.0+ - Add gcc/g++/make to base image for C MCP support - Pin pycparser==2.22 for angr compatibility - Set LD_LIBRARY_PATH and PKG_CONFIG_PATH for radare2 - Add r2pm prefix bin to PATH - Rename service: ctf-re → re-toolbox - Add GHIDRA_MCP_AUTH_TOKEN env var
Four-step workflow: 1. Health-check MCP server via /health endpoint 2. Import binary via analyzeHeadless (create project, auto-analyze) 3. Load program into MCP bridge via /load_program 4. Verify program is loaded Supports --no-analyze for fast import, configurable via env vars: GHIDRA_MCP_URL, GHIDRA_MCP_AUTH_TOKEN, GHIDRA_PROJECTS_DIR.
…g tools Remove c-mcp.py section (file never created), angr-solve.py CLI examples (script deleted), fuzz-init.sh references (script deleted). Add shell MCP docs, angr built-in MCP config, load-ghidra.sh usage, project structure. All MCP configs match actual state of configs/base.json and .mcp.json.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Split the single-stage Dockerfile into 7 stages with pinned tool versions,
CI validation, and a tag-driven release workflow.
Dockerfile
base→base-build→python,r2-ghidra,fuzzing,android→finalbase, build toolchain (gcc, cmake,maven, autotools) in
base-build. Final stage FROM base — those ~400MBnever ship.
angr 9.2.194, AFL++ v5.00c, honggfuzz 2.5, apktool 2.10.0, jadx 1.5.1,
frida-tools 14.9.0, platform-tools 37.0.0, ghidra-mcp v5.13.1.
Bump one ARG, only that stage + final rebuilds.
/opt/tools/<name>(prefixed, no/usr/local pollution). Final stage merges via
COPY --from.CI
.github/workflows/build.yml— triggers on push/PR to main, builds withBuildKit + GHA cache,
push: false. Catches breakage before merge..github/workflows/release.yml— triggers onv*.*.*tag, builds +pushes to
ghcr.io/<repo>with semver tags. Auth viaGITHUB_TOKEN.Docs
Fallback for older Docker with
DOCKER_BUILDKIT=1.Impact
python+final(~2 min instead of ~30 min full rebuild).