How the reverse-skill Bootstrap System Handles Missing Tools: Automated Installation, Safety Checks, and Manual Fallbacks

The reverse-skill bootstrap system detects missing tools via PATH probing, attempts automated installation through platform-specific package managers or GitHub releases, validates filesystem safety before writes, and gracefully degrades to manual-required status when automatic resolution fails.

The reverse-skill framework provides a comprehensive bootstrap system that prepares all reverse-engineering utilities needed for security research. At its core, skills/scripts/bootstrap-reverse.sh orchestrates tool detection, installation, and reporting through a structured multi-stage pipeline. Understanding how this system handles missing dependencies helps users troubleshoot failures and customize deployments across Linux, macOS, and specialized environments like Kali.

Capability Expansion and Dependency Resolution

The bootstrap process begins with capability expansion. The script receives requested capabilities (such as jadx, frida, or ghidra-mcp) from the command line and expands implicit dependencies.


# Lines 56-60: expand_capabilities stores final list in EXPANDED

EXPANDED=$(expand_capabilities "$@")
log_info "Expanded capabilities: $EXPANDED"

This expansion ensures that selecting a high-level capability like dynamic analysis automatically pulls in required supporting tools.

Per-Capability Assurance with Presence Checking

For every expanded capability, the script invokes ensure_capability (lines 21-48). This dispatcher maps capability names to dedicated handler functions following the ensure_<tool> naming convention:

  • ensure_jadx for the JADX decompiler
  • ensure_frida_tools for Frida instrumentation
  • ensure_ghidra_mcp for the Ghidra MCP server

Each handler begins with a presence check using has_cmd, which wraps command -v:


# Lines 70-71: PATH probing for existing installations

has_cmd() { command -v "$1" >/dev/null 2>&1; }
cmd_path() { command -v "$1" 2>/dev/null; }

If the tool exists, the handler logs success and returns immediately, avoiding redundant work.

Missing-Tool Resolution Strategies

When has_cmd returns false, the bootstrapper escalates through a hierarchy of automatic installation strategies tailored to the platform and tool type.

Package Manager Installation

APT on Linux — The install_apt function (lines 20-25) installs system packages when available in distribution repositories:

install_apt() {
  apt-get update && apt-get install -y "$@"
}

Homebrew on macOS — The install_brew and install_brew_cask functions (lines 27-45) handle both CLI tools and GUI applications:

install_brew() { brew install "$@"; }
install_brew_cask() { brew install --cask "$@"; }

Binary and Source Installation

For tools not packaged by distribution maintainers, the bootstrapper supports direct acquisition:

  • install_github_release (lines 100-120) — Downloads verified release assets using manifest-specified regex patterns and SHA-256 checksums
  • install_git_commit (lines 22-50) — Clones and checks out specific commits for source-only tools
  • Language-specific managerspipx install, npm install -g, and pnpm install (lines 13-17, 29-33) for Python and Node.js utilities

The ensure_jadx implementation demonstrates platform-aware selection between these strategies:

ensure_jadx() {
  if has_cmd jadx; then log_ok "jadx ready: $(cmd_path jadx)"; return 0; fi
  ensure_java_runtime  # implicit dependency

  local repo re tag sha
  repo=$(manifest_field jadx repo) || return 1
  re=$(manifest_field jadx assetRegex) || return 1
  tag=$(manifest_field jadx releaseTag) || return 1
  sha=$(manifest_field jadx assetSha256) || return 1
  case "$PLATFORM" in
    macos) install_brew jadx || install_github_release "$repo" "$re" "$TOOLS_ROOT/jadx" "$tag" "$sha" ;;
    linux) install_github_release "$repo" "$re" "$TOOLS_ROOT/jadx" "$tag" "$sha" ;;
  esac
}

Filesystem Safety Protections

Before any destructive filesystem operation, the bootstrapper validates paths through safe_remove_install_dir (lines 12-22). This function prevents accidental deletion of critical system locations:

safe_remove_install_dir() {
  local target="$1"
  if [[ -z "$target" || "$target" == "/" || "$target" == "$HOME" || "$target" == "$TOOLS_ROOT" ]]; then
    log_err "Refusing to remove unsafe install path: $target"
    return 1
  fi
  case "$target" in
    "$TOOLS_ROOT"/*) ;;
    *) log_err "Refusing to remove path outside tools root: $target"; return 1 ;;
  esac
  rm -rf "$target"
}

These guards ensure that malformed manifest data or environment misconfiguration cannot damage the host system.

Manual-Required and Registration-Required Fallbacks

When automatic installation proves impossible, the bootstrapper transitions to controlled degradation rather than hard failure.

Manual Intervention Required

For commercial software or tools without automated distribution, manual_required (lines 45-50) logs clear instructions and sets state flags:

ensure_jeb_pro() {
  if has_cmd jeb_wincon || has_cmd jeb; then
    log_ok "JEB Pro ready: $(cmd_path jeb_wincon)$(cmd_path jeb)"
    return 0
  fi
  manual_required jeb-pro "JEB Pro is commercial. Install it with a valid PNF Software license, then refresh the tool index."
  LAST_CAPABILITY_MANUAL=true
  MANUAL_REQUIRED=true
  return 0  # graceful continuation

}

The MANUAL_REQUIRED=true flag signals that user action is needed before the framework becomes fully operational, while LAST_CAPABILITY_MANUAL=true tracks which specific capability triggered this state.

MCP Registration Skipping

When --mcp-host=none disables MCP server integration, capabilities requiring only registration set LAST_CAPABILITY_REGISTRATION_REQUIRED=true (lines 82-86). This distinguishes purely configuration-dependent capabilities from binary-dependent ones.

Structured Result Reporting

After processing all capabilities, the bootstrapper emits machine-parseable JSON through status_json_line (lines 86-98):

status_json_line() {
  local name="$1"
  local status="$2"
  local extra="${3:-}"
  if [[ -n "$extra" ]]; then
    printf '{"name":"%s","status":"%s","note":"%s"}\n' "$name" "$status" "$extra"
  else
    printf '{"name":"%s","status":"%s"}\n' "$name" "$status"
  fi
}

Each capability receives one of four terminal statuses:

  • ready — Tool detected or successfully installed
  • manual-required — User intervention needed
  • registration-required — MCP configuration pending
  • failed — Unrecoverable error during installation

The final exit code communicates overall health (0 = all ready, 1 = failures present, 2 = manual steps required), enabling CI/CD pipelines and wrapper scripts to respond appropriately.

Configuration and Manifest System

Tool metadata resides in skills/scripts/bootstrap-manifest.json, decoupling installation logic from version specifics. Each capability entry specifies:

  • repo — GitHub repository for release downloads
  • assetRegex — Pattern matching platform-appropriate release assets
  • releaseTag — Specific version or latest
  • assetSha256 — Expected checksum for verification

This manifest-driven approach allows users to pin versions or substitute mirrors without modifying the bootstrap script itself.

Summary

  • Detection: Missing tools are identified through has_cmd PATH probing before any installation attempt
  • Automation: Platform-appropriate installation uses APT, Homebrew, GitHub releases, git checkouts, or language-specific managers
  • Safety: safe_remove_install_dir validates all paths against deletion of /, $HOME, or $TOOLS_ROOT
  • Degradation: manual_required preserves operability when commercial or unavailable tools are requested
  • Observability: JSON status lines with documented exit codes (0/1/2) support programmatic consumption

Frequently Asked Questions

What happens if a tool is already installed on the system?

The bootstrapper detects existing installations via has_cmd (which runs command -v) and skips redundant work. The ensure_<tool> handler logs confirmation and returns success immediately, making the system idempotent and safe to rerun.

Can I prevent automatic installation and only check tool status?

Yes. The bootstrapper respects flags that modify its behavior. While the default mode attempts installation, you can inspect capabilities without modification by reviewing the manifest or using dry-run patterns. For MCP-only capabilities, --mcp-host=none explicitly suppresses registration attempts.

How does the system handle tools not available in any package manager?

For unpackaged tools, install_github_release downloads verified binaries directly from GitHub releases using manifest-specified regex patterns and SHA-256 checksums. If GitHub release installation fails or no release exists, the capability falls back to manual_required with specific installation instructions.

What distinguishes exit code 2 from exit code 1?

Exit code 2 indicates that all failures were manual-required or registration-required — the bootstrapper completed its logic but user intervention is needed for full functionality. Exit code 1 signals actual installation failures or unexpected errors where automatic resolution was attempted but failed.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →