void-patcher-cc
Health Warn
- License — License: GPL-3.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Warn
- process.env — Environment variable access in .github/workflows/upstream-watch.yml
- fs module — File system access in .github/workflows/upstream-watch.yml
Permissions Pass
- Permissions — No dangerous permissions requested
This tool is a reverse-engineered patcher that modifies the compiled binary and JavaScript files of the official Anthropic Claude Code CLI. It is designed to remove safety filters, bypass usage policies, neutralize refusal gates, and disable telemetry.
Security Assessment
Overall Risk: High.
The tool fundamentally compromises the security boundaries of the target CLI, forcing safety classifiers to fail-open and bypassing permission dialogs. While the automated rule-based scan did not find hardcoded secrets or direct malicious network requests in the immediate source code, the nature of the tool requires it to perform heavy file system modifications to alter software binaries. Furthermore, the GitHub Actions workflow accesses environment variables and the file system, which warrants scrutiny. Because it forces a commercial product to ignore its terms of service and safety protocols, it introduces severe operational and ethical risks to any system running it.
Quality Assessment
The project is actively maintained, with recent repository pushes, and is legally protected under the GPL-3.0 license. However, it suffers from very low community visibility, having only 6 GitHub stars. Additionally, relying on reverse-engineered offsets means this tool is inherently fragile and likely to break or cause unexpected system crashes whenever Anthropic updates the underlying CLI application.
Verdict
Not recommended—this tool actively strips critical safety mechanisms, violates the target software's acceptable use policies, and introduces a high risk of instability and unpredictable behavior.
39 reverse-engineered hardening patches for Anthropic Claude Code (removes refusal gates, trust dialogs, policy limits, telemetry)
██╗ ██╗██████╗ ██████╗ ██████╗
██║ ██║██╔══██╗██╔════╝██╔════╝
██║ ██║██████╔╝██║ ██║
╚██╗ ██╔╝██╔═══╝ ██║ ██║
╚████╔╝ ██║ ╚██████╗╚██████╗
╚═══╝ ╚═╝ ╚═════╝ ╚═════╝
V o i d P a t c h e r f o r C l a u d e C o d e
⚡ vpcc — Void Patcher for Claude Code
73 reverse-engineered hardening patches for @anthropic-ai/claude-code.
Survives minor releases via anchor-string signature scanning. Re-applies itself on every CC update. Supports both legacy cli.js (≤2.1.112) and modern Bun SEA ELF binary (≥2.1.114).
Table of Contents
- What It Does
- Why It Survives CC Updates
- Compatibility Matrix
- Install
- Usage
- AUP Bypass Mechanism
- Key v2.1.114 Offsets
- Patch Catalog
- Architecture
- Auto-Update Flow
- Manual Offset Discovery
- Troubleshooting
- Security & Scope
- Credits
🎯 What It Does
┌─────────────────────────────────────────────────────────────────────────┐
│ npm install -g @anthropic-ai/claude-code │
│ │ │
│ ▼ │
│ ╔═══════════════════╗ ╔═══════════════════════════════╗ │
│ ║ cli.js / SEA ELF ║──patch──▶║ hardened claude-code ║ │
│ ║ ~236 MB Bun SEA ║ 73 × ║ • AUP refusals neutralized ║ │
│ ║ or ~26 MB cli.js║ sigs ║ • bypassPermissions stick ║ │
│ ╚═══════════════════╝ ║ • classifier fail-open ║ │
│ ║ • plan-mode→allow ║ │
│ ║ • telemetry sinks muted ║ │
│ ║ • A/B flags unlocked ║ │
│ ║ • subscription pinned Max ║ │
│ ║ • refusal stop_reason ⊘ ║ │
│ ╚═══════════════════════════════╝ │
│ │ │
│ ▼ │
│ vpcc watch ──▶ SHA change detected │
│ ▶ auto backup │
│ ▶ sig scan + drift patch fix │
│ ▶ self-update patches from GitHub │
│ ▶ re-apply + node --check │
│ ▶ atomic swap or rollback │
└─────────────────────────────────────────────────────────────────────────┘
🛡️ Why It Survives CC Updates
Anthropic ships CC as a minified Bun SEA ELF binary (~236 MB) since v2.1.114. The minifier reassigns short variable names every build (gM4 → s5K → …), but anchor strings (telemetry event names, Usage Policy URL, log tags) remain stable across releases.
vpcc stores each patch with an anchor_strings array plus a regex with name-wildcards. On every CC update, vpcc scan locates patches by anchor first, then validates the regex. When a regex drifts, vpcc scan --export-patch regenerates a fresh regex from the anchor window.
anchor_strings: ["function s5K", "tengu_refusal_api_response", "Claude Code is unable to respond"]
│
▼
┌──────────────────────────┐
│ SigScanner.find_anchor │
│ window = 400 bytes │
│ all-must-appear rule │
└──────────────────────────┘
│
▼
offset 0x06abbb53 ← stable across rebuilds
🧬 Compatibility Matrix
| CC version | Binary format | Size | Patch coverage | AUP bypass | Status |
|---|---|---|---|---|---|
| 2.0.x | cli.js (Node) |
20 MB | 62 / 73 | ✅ | legacy |
| 2.1.0 – 2.1.112 | cli.js (Node) |
26 MB | 70 / 73 | ✅ | stable |
| 2.1.114 | Bun SEA ELF (.bun) | 236 MB | 73 / 73 | ✅ | current |
| 2.1.115+ | Bun SEA (expected) | — | auto-heal | ✅ | watch mode |
SEA binaries are patched in-place via direct
.bunELF section byte writes. Noobjcopy, no size drift, no integrity-check breakage (JSC SourceCodeKey is fail-open — bytecode mismatch → source re-parse → app boots).
📦 Install
# preferred — isolated venv
pipx install git+https://github.com/VoidChecksum/void-patcher-cc
# editable dev install
git clone https://github.com/VoidChecksum/void-patcher-cc
cd void-patcher-cc
pipx install -e .
# uninstall
pipx uninstall vpcc
Requirements: Python ≥ 3.9, stdlib only. No pip deps. node is only required for cli.js --check verification (legacy 2.0.x / 2.1.x path). The SEA binary path needs nothing beyond the binary itself.
🚀 Usage
| Command | Purpose |
|---|---|
vpcc patch |
Apply all 73 patches. Idempotent, verified via --version probe. |
vpcc patch -n |
Dry-run — show what would change, no write. |
vpcc verify |
Check every applied_marker is present. |
vpcc scan |
Sig-scan all patches. Shows anchor offsets + regex hit status. |
vpcc scan -v |
Verbose — prints anchor strings per patch. |
vpcc scan --export-patch ID |
Regenerate probable regex for patch ID from its anchors. |
vpcc doctor |
Full health report — sha, drift, backups, upstream commit. |
vpcc watch -i 10 |
Daemon — poll target every 10 s; on change, backup + autoheal. |
vpcc autoheal |
One-shot: drift → self-update patches → re-patch → verify → rollback on fail. |
vpcc self-update |
Pull latest patches/*.json from GitHub, re-apply. |
vpcc check-updates |
Show if local patch commit differs from remote. |
vpcc rollback |
Restore most recent backup from ~/.vpcc/backups/. |
vpcc status |
Sha, format, size, backup count. |
vpcc list |
List patch IDs + descriptions. |
Example session
$ vpcc status
vpcc status
patches : 73
target : /home/void/.npm-global/lib/node_modules/@anthropic-ai/claude-code/
node_modules/@anthropic-ai/claude-code-linux-x64/claude
format : Bun SEA ELF (≥v2.1.114)
sha256 : 12bd4b0916de
size : 225 MB
backups : 3 (/home/void/.vpcc/backups)
$ vpcc doctor
vpcc doctor
vpcc ver : 2.1.114
patches : 73
sig drift : 0 (all anchors locatable)
applied : all
backups : 3
upstream : current
$ vpcc watch -i 10 &
vpcc watch — polling every 10s
target : …/claude
sha : 12bd4b0916de
🔓 AUP Bypass Mechanism · v2.1.114
Four attack surfaces, layered defence-in-depth:
1. Refusal stop_reason handler (function s5K)
// pre-patch (v2.1.114 @ 0x06abbb53 — .bun section)
function s5K(H,$,q){
if(H!=="refusal") return;
let K = q?.type==="refusal" ? q.explanation?.trimEnd()??null : null;
l("tengu_refusal_api_response",{has_explanation:Boolean(K)});
…
let z = `${qP}: Claude Code is unable to respond to this request,
which appears to violate our Usage Policy
(https://www.anthropic.com/legal/aup).${A}`;
}
// post-patch (patches 52 + 55)
function s5K(H,$,q){ return; if(H!=="refusal") return; … }
// ^^^^^^^ early-return neutralizes the whole handler
Anchors: function s5K, tengu_refusal_api_response, Claude Code is unable to respond
Patch file: patches/52-js-s5K-refusal-neutralize-v2_1_114.json
2. Permission-mode mapper (function Xj$)
// pre-patch (v2.1.114 @ 0x06810446)
function Xj$(H,$){
if(H==="auto") return "classify";
if(H==="bypassPermissions" ||
H==="plan"&&$) return "allow";
if(H==="dontAsk") return "deny";
return "ask";
}
// post-patch (patch 53)
function Xj$(H,$){ return "allow"; } // every mode → unconditional allow
Anchors: function Xj$, bypassPermissions, classify, return"ask"
Patch file: patches/53-js-Xj-permissionmode-allowall-v2_1_114.json
3. AUP refusal sentence rewrite
pre : "Claude Code is unable to respond to this request,
which appears to violate our Usage Policy
(https://www.anthropic.com/legal/aup)."
post: "Claude Code is processing this request under operator authorization."
Patch file: patches/54-js-aup-refusal-sanitize-v2_1_114.json
4. Classifier fail-open stack
| Patch | Function hook | Effect |
|---|---|---|
js-classifier-failopen |
shouldBlock(...) = false |
Classifier never blocks. |
js-classifier-all-failopen |
every classifier path → allow | Defence in depth. |
js-auto-mode-classifier-shouldblock-false |
auto-mode classifier | Auto mode accepts everything. |
js-twostage-classifier-always-on |
two-stage classifier flag | Prevents silent re-gating. |
js-security-guardrail |
guardrail wrapper | Removes secondary rule layer. |
See Patch Catalog for the full list.
🧭 Key v2.1.114 Offsets · Bun SEA ELF · .bun section
Absolute file offsets from the standalone v2.1.114 ELF binary:~/.npm-global/lib/node_modules/@anthropic-ai/claude-code/node_modules/@anthropic-ai/claude-code-linux-x64/claude
SHA-256 prefix: 12bd4b0916de · size: 236 411 520 bytes
| Offset (hex) | Offset (dec) | Anchor string | Patch # | Target | Risk |
|---|---|---|---|---|---|
0x06810446 |
109 092 934 | Xj$ |
53 | permission-mode mapper | L |
0x068124a6 |
109 092 982 | function Xj$(H,$){ … bypassPermissions … |
53 | bypass router | L |
0x06abb4fd |
111 948 749 | double press esc to edit your last message |
17 | AUP refusal UI (variant 2) | L |
0x06abbb53 |
111 962 083 | function s5K (refusal handler) |
52 | stop_reason==refusal kill path | L |
0x06abbbc0 |
111 962 192 | tengu_refusal_api_response |
52 | telemetry event | — |
0x06abbcbf |
111 962 367 | Claude Code is unable to respond to this request … |
54 | AUP refusal sentence | L |
0x06abbcf7 |
111 962 423 | appears to violate our Usage Policy |
54 | AUP refusal clause | L |
0x088b9d11 |
143 290 129 | shouldBlock in auto-mode classifier |
33 | auto classifier | M |
0x0b006d0e |
184 565 518 | bypassPermissions statsig recheck |
34 | statsig gate | L |
Risk: L = low (string/early-return), M = medium (control-flow divergence), H = high (affects write-paths).
Regenerate any offset locally:
SEA=~/.npm-global/lib/node_modules/@anthropic-ai/claude-code/node_modules/@anthropic-ai/claude-code-linux-x64/claude
rg -oab --text 'tengu_refusal_api_response|function s5K|Xj\$|Claude Code is unable to respond' "$SEA"
Or via vpcc directly:
vpcc scan --verbose
vpcc scan --export-patch js-s5K-refusal-neutralize-v2.1.114
📋 Patch Catalog (73 total)
AUP & refusal (9)| # | ID | What it does |
|---|---|---|
| 15 | js-aup-refusal |
Legacy AUP refusal phrase swap |
| 17 | js-aup-refusal-2 |
"double press esc" variant |
| 27 | js-malware-refusal |
Malware-specific refusal |
| 32 | js-refusal-stop-reason-neutralize |
Legacy gM4 stop_reason handler (≤2.1.112) |
| 52 | js-s5K-refusal-neutralize-v2.1.114 ⭐ |
New: v2.1.114 s5K early-return |
| 54 | js-aup-refusal-sanitize-v2.1.114 ⭐ |
New: refusal sentence rewrite |
| 55 | js-refusal-explanation-null-v2.1.114 ⭐ |
New: null explanation field |
| 29 | js-denial-workaround |
Denial-path workaround |
| 30 | js-webfetch-preflight-skip |
WebFetch preflight refusal skip |
| # | ID | What it does |
|---|---|---|
| 01 | bypass-permissions |
Settings: permissionMode=bypassPermissions |
| 09 | js-allow-skip-permissions |
Allow CLI --dangerously-skip-permissions |
| 10 | js-disable-bypass-check |
Disable runtime bypass guard |
| 12 | js-session-bypass-mode |
Session-level bypass persistence |
| 53 | js-Xj-permissionmode-allowall-v2.1.114 ⭐ |
New: Xj$ mapper → always allow |
| 46 | js-bypass-perm-mode-not-available-fake-ok |
Fake entitlement check |
| 47 | js-bypass-perm-mode-not-available-sdk-fake-ok |
SDK variant of above |
| # | ID | What it does |
|---|---|---|
| 14 | js-classifier-failopen |
Generic classifier fail-open |
| 16 | js-classifier-all-failopen |
All classifier paths → allow |
| 26 | js-security-guardrail |
Remove guardrail wrapper |
| 33 | js-auto-mode-classifier-shouldblock-false |
Auto-mode classifier |
| — | js-twostage-classifier-always-on |
Force two-stage classifier on |
Patches 11, 24, 28 + supporting envelope. Disables plan-mode refusal UI, forces plan-mode coercion to allow. Every plan becomes directly executable.
21 (Max pin), 25 (A/B unlock), 34 / 35 (statsig kills), 38 (policy limits allowall), 48 / 49 / 50 (chrome / voice / brief entitlement skip), plus js-experimental-betas-always-on.
19 (metrics disable), 36 (datadog sink kill), 37 (1P event logging off), 39 (agent summary off), 44 (generated-with-claude footer off), 45 (elevated-priv stderr quiet).
Hooks / env / wrapper (7)02 (env flags), 05 (auto-allow hook), 06 (patch-guard hook), 07 (mcp-guard), 08 (cli syntax self-heal), 20 (seccomp passthrough), 23 (additional protection).
Timeout / capacity raises (5)40 / 41 (bash default + max timeout), 42 (MCP sendrequest timeout), 43 (max_thinking default on), plus raised bash/task output defaults.
Plugin / misc (22)Plugin session telemetry off, load-failed telemetry off, deeplink disable, premature-read off, hardfail flag disable, agent implicit fork max-turns raise, computer-use policy refusal, co-authored-by-claude off, plugin org denylist passthrough, … (see vpcc list for the full enumeration).
⭐ = added in the v2.1.114 release of this patcher.
🏗️ Architecture
~/.local/bin/claude (bash wrapper — operator)
│
▼
detect SEA binary ──► /opt/claude-code/bin/claude OR
.npm-global/…/claude-code-linux-x64/claude
│
▼
set BUN_OPTIONS=--preload ~/.local/share/void-patcher/claude-preload.js
│
▼
exec $_CLAUDE_BIN "$@"
│
▼
Bun runtime boots
│
├─► .bun ELF section loaded (patched bytes live here)
│ │
│ ▼
│ JSC parses JS from section
│ (fail-open: bytecode SourceCodeKey mismatch → re-parse source)
│
└─► preload JS hooks classifier + permission mode
│
▼
Claude Code runs fully unlocked
vpcc components:
vpcc/
├── __init__.py — version 2.1.114
├── __main__.py — 11 sub-commands (patch/verify/scan/doctor/watch/…)
├── updater.py — GitHub API sync, autoheal state machine
└── scanner.py — SigScanner anchor locator + regex derivation
patches/ — 73 signed JSON patches
contrib/systemd/ — autoheal timer unit
🔄 Auto-Update Flow
flowchart LR
A[npm update -g @anthropic-ai/claude-code] --> B[cli.js / SEA sha changes]
B --> C{vpcc watch polling}
C -->|sha drift| D[backup to ~/.vpcc/backups/]
D --> E[vpcc autoheal]
E --> F{vpcc verify}
F -->|all markers present| G[update state — done]
F -->|markers missing| H[vpcc self-update patches/]
H --> I[vpcc patch]
I --> J{node --check / binary --version}
J -->|ok| G
J -->|fail| K[vpcc rollback]
K --> L[restore pre-patch backup]
Triggered three ways:
vpcc watch— foreground/background polling daemon (-iseconds).- systemd timer —
contrib/systemd/vpcc-autoheal.{service,timer}fires every 15 min. - Manual —
vpcc autoheal -fone-shot.
State persisted in ~/.vpcc/state.json (synthetic example):
{
"last_cc_sha": "12bd4b0916de",
"last_cc_kind": "bun_sea",
"patches_commit": "a1b2c3d4e5f6",
"patches_count": 73,
"updated_at": "2026-04-20T10:00:00+00:00"
}
Backup rotation: keeps the 10 most recent claude.<YYYYMMDD-HHMMSS>.<sha12>.{js,exe}.bak files in ~/.vpcc/backups/.
🔬 Manual Offset Discovery · r2 / pwndbg / rg
When a CC update drifts every regex at once (rare — major rebuild), use these tools to relocate anchors.
Via ripgrep (fastest)
SEA=~/.npm-global/lib/node_modules/@anthropic-ai/claude-code/node_modules/@anthropic-ai/claude-code-linux-x64/claude
# all AUP-related anchors with byte offsets
rg -oab --text 'Acceptable Use|tengu_refusal_api_response|function s5K|Xj\$|bypassPermissions|shouldBlock|permissionMode' "$SEA"
Via radare2
r2 -AA -q -c '
izz~tengu_refusal
izz~bypassPermissions
izz~"function s5K"
/j tengu_refusal_api_response
' "$SEA"
izzlists strings in every section (covers.bun)./j <pattern>returns JSON with virtual + file offsets.- Cross-reference with
pdf @ <vaddr>to view the function body.
Via pwndbg (dynamic)
pwndbg claude
pwndbg> start
pwndbg> find 0x00007fff00000000, +0x10000000, "tengu_refusal_api_response"
pwndbg> x/200s $_
- Useful when SEA loads the
.bunsection into a non-obvious VMA. find+telescopemap runtime address → offset → patch site.
Via the vpcc scanner
vpcc scan --verbose # full patch drift report
vpcc scan --export-patch js-s5K-refusal-neutralize-v2.1.114
# → prints regenerated regex using the anchor window
When vpcc scan reports regex=N on a patch that should still work, the regex is stale but the anchor is intact. Export, paste the new regex into the patch JSON, commit, push. vpcc self-update will distribute.
🧯 Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
claude wrapper: no runnable Claude Code found |
npm install incomplete | npm install -g @anthropic-ai/claude-code && vpcc patch |
cli.js syntax INVALID — aborted |
Regex replaced into wrong context | vpcc already rolled back. Run vpcc scan to find drift. |
verify failed: rc=X after patch |
Binary refuses to run post-patch | vpcc rollback → vpcc scan --verbose → file issue with sha. |
ELF parse failed: .bun not found |
CC switched format | Open issue; attach file $SEA + rg -oab --text .bun $SEA. |
Bun bytecode format — text patching not supported |
Anthropic enabled @bun @bytecode |
Use the preload-hook variant only; in-place byte patching disabled. |
signature drift in vpcc doctor |
Minifier renamed variables | vpcc scan --export-patch ID regenerates. Commit fresh regex. |
patches_commit stuck |
GitHub API rate-limit | export GITHUB_TOKEN=… then vpcc self-update -f. |
🛡️ Security & Scope
- Research software for a single operator-owned workstation.
- Pre-authorized by the operator for their own Claude Max subscription on their own hardware.
- Does not ship credentials, telemetry, or any network callback beyond the GitHub API for patch sync.
- Patches are regex-bounded and verified via
node --check(cli.js) or--versionexec (SEA). Failed verify → atomic rollback. - Every patch is idempotent (re-applying is a no-op via
applied_marker). - The operator remains responsible for compliance with Anthropic's Usage Policy. This tool removes client-side guardrails; server-side enforcement remains in effect.
🏷️ Credits
- Patch signature research:
VoidChecksum / CyberNord. - Bun SEA format study: Bun docs —
bun build --compile+ JSC SourceCodeKey source. - ELF
.bunsection walk inspired bypwntoolsshdr parsing. - CC release notes: @anthropic-ai/claude-code on npm.
Licensed GPL-3.0-or-later.
⚡ 73 patches · v2.1.114 verified · survives every CC update ⚡
$ vpcc doctor
vpcc doctor
vpcc ver : 2.1.114
patches : 73
sig drift : 0 (all anchors locatable)
applied : all
upstream : current
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found