Skip to content

VoidChecksum/void-patcher-cc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

 ██╗   ██╗██████╗  ██████╗ ██████╗
 ██║   ██║██╔══██╗██╔════╝██╔════╝
 ██║   ██║██████╔╝██║     ██║
 ╚██╗ ██╔╝██╔═══╝ ██║     ██║
  ╚████╔╝ ██║     ╚██████╗╚██████╗
   ╚═══╝  ╚═╝      ╚═════╝ ╚═════╝
     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 patches target format license

idempotent sig--scan auto--heal preload--hook verify vfs--aware python

⚡ vpcc — Void Patcher for Claude Code

96 reverse-engineered hardening patches · 3-layer defense · survives every CC update
cli.js (≤ 2.1.112)  ·  Bun SEA ELF (≥ 2.1.114)  ·  runtime preload hook  ·  auto-heal scanner


🎯 TL;DR · one-liner install

macOS · Linux · WSL

curl -fsSL https://raw.githubusercontent.com/VoidChecksum/void-patcher-cc/main/install.sh | bash

Windows (PowerShell 5.1+/7+)

irm https://raw.githubusercontent.com/VoidChecksum/void-patcher-cc/main/install.ps1 | iex

Chains on top of Anthropic's official installer, then applies 96 patches, deploys the runtime preload hook, and (Linux) enables the systemd auto-heal timer.

Every permission prompt · refusal · AUP gate · classifier · telemetry sink off. Every CC upgrade auto-heals.

🧭 Jump to


🎯 How it works

Click for pipeline diagram
%%{init: {'theme':'dark','themeVariables':{
   'primaryColor':'#00D4FF','edgeLabelBackground':'#0D1117',
   'tertiaryColor':'#FF6B9D','fontFamily':'JetBrains Mono'}}}%%
flowchart LR
    NPM[npm -g<br/>@anthropic-ai/claude-code] -->|236 MB SEA or 26 MB cli.js| TGT[target binary]
    TGT --> SIG{96 regex<br/>signatures}
    SIG -->|match| BYTE[byte-patch<br/>in-place]
    BYTE --> VER{verify<br/>--version}
    VER -->|ok| SWAP[atomic swap]
    VER -->|fail| RB[rollback]
    SWAP --> RUN[claude runs]
    RUN --> PRE[preload hook]
    PRE --> HOOK{runtime shims<br/>JSON.parse / fetch / defineProperty}
    HOOK --> RUN
    TGT -.-> WATCH[vpcc watch]
    WATCH -->|sha drift| HEAL[auto-heal scanner]
    HEAL -->|regex regen| SIG
    style SIG fill:#00D4FF,stroke:#0D1117,color:#0D1117
    style PRE fill:#FF6B9D,stroke:#0D1117,color:#0D1117
    style HEAL fill:#E9D900,stroke:#0D1117,color:#0D1117
Loading
          ┌─────────────── 3-LAYER DEFENSE ──────────────┐
          │                                              │
 layer 1  ▶  .bun ELF byte-patches   (96 regex sigs)    ◀
 layer 2  ▶  Bun --preload hook      (JS runtime shims) ◀
 layer 3  ▶  auto-heal sig-scanner   (regex regen)      ◀
          │                                              │
          └──────────────────────────────────────────────┘

🛡️ Why it survives every update

Anthropic's Bun build re-minifies on every release — gM4s5KQw7 → … The only stable thing is text that must stay human-readable: event names (tengu_refusal_api_response), URLs (anthropic.com/legal/aup), log prefixes, schema keys.

Every patch ships three independent locators, ordered by hit reliability:

Mechanism Reliability Self-healing Example
① anchor-string set ★★★★★ via scanner ["function s5K", "tengu_refusal_api_response"]
② wildcard regex ★★★☆☆ regenerated function s5K\(([A-Za-z_$][\w$]*),…
③ runtime preload ★★★★★ N/A JSON.parse wrapper rewrites refusal

When ② drifts, vpcc scan --auto-heal rewrites it from ①'s context window. When ① also drifts (rare), ③ still catches the refusal at runtime. All three must fail simultaneously to break.


2.1.119 layout change

Starting at Claude Code 2.1.119, the .bun ELF section embeds two copies of the entry JS bundle:

[header][active-entry-blob ~13 MB][bytecode-cache ~102 MB]
[lookup-key\x00][vfs-path\x00][vfs-copy-of-cli.js ~13 MB][other-vfs-files][trailer]

Bun re-parses the VFS copy at startup for module resolution. Patching both copies (as pre-2.1.119 vpcc did) corrupts the VFS bundle and fails with an opaque entry.instantiate crash inside Bun's ESM linker.

vpcc ≥ 2.1.119 adds _find_active_bundle_bounds(): locates the // @bun @bytecode marker, reads the u32 blob length at marker-4, and restricts all search_regex writes to [marker, marker + blob_size). VFS copy stays pristine, Bun loads cleanly.

Falls back to the full section on older (single-bundle) builds.


🧬 Compatibility matrix

CC version Format OS support Size Coverage AUP bypass Status
2.0.x cli.js (Node) Lin · mac · Win · WSL 20 MB 62 / 77 legacy
2.1.0 – 2.1.112 cli.js (Node) Lin · mac · Win · WSL 26 MB 70 / 77 legacy
2.1.114 – 2.1.117 Bun SEA (ELF / Mach-O / PE) Lin · mac (x64/arm64) · Win (x64/arm64) · WSL 236 MB 77 / 77 stable
2.1.118 Bun SEA (ELF / Mach-O / PE) Lin · mac (x64/arm64) · Win (x64/arm64) · WSL 236 MB 77 / 77 stable
2.1.119 Bun SEA (active-bundle + VFS-copy) Lin · mac (x64/arm64) · Win (x64/arm64) · WSL 233 MB 96/96 stable
2.1.120 Bun SEA (active-bundle + VFS-copy) Lin · mac (x64/arm64) · Win (x64/arm64) · WSL 234 MB 96/96 current
2.1.121+ Bun SEA (expected) all auto-heal watch mode

SEA binaries are patched in-place via direct .bun ELF section byte writes. No objcopy, no size drift. JSC SourceCodeKey is fail-open — bytecode-hash mismatch → source re-parse → app boots clean.


📦 Install

One-liner (recommended)

macOS · Linux · WSL
curl -fsSL https://raw.githubusercontent.com/VoidChecksum/void-patcher-cc/main/install.sh | bash
Windows PowerShell
irm https://raw.githubusercontent.com/VoidChecksum/void-patcher-cc/main/install.ps1 | iex

Both scripts are idempotent — re-run to update. They:

  1. Install Claude Code via Anthropic's official installer if missing (https://claude.ai/install.sh / install.ps1).
  2. Install pipx if missing.
  3. Install vpcc from GitHub.
  4. Clone contrib/ assets (preload hook, systemd units, Windows wrappers).
  5. Run vpcc patch + vpcc install-preload.
  6. Enable systemd --user vpcc-autoheal.timer (Linux) / add claude.cmd wrapper to user PATH (Windows).

Manual

pipx install git+https://github.com/VoidChecksum/void-patcher-cc
vpcc patch && vpcc install-preload

# editable dev
git clone https://github.com/VoidChecksum/void-patcher-cc
cd void-patcher-cc && pipx install -e . --force

# uninstall
pipx uninstall vpcc

Requirements (per OS)

OS Prereqs CC binary location (auto-detected)
Linux python3 ≥ 3.9 · npm · curl npm global · /opt/claude-code/bin/claude · ~/.claude/local/claude
macOS python3 ≥ 3.9 · npm · curl npm global · Homebrew · ~/.claude/local/claude (x64 + arm64 + Rosetta)
Windows PowerShell 5.1+/7+ · python ≥ 3.9 · npm %APPDATA%\npm\node_modules\... · %LOCALAPPDATA%\Programs\claude-code\claude.exe
WSL as Linux WSL file tree

State & data files

Path Purpose
~/.vpcc/state.json patch commit · last CC sha
~/.vpcc/backups/ 10 most recent target backups
~/.local/share/void-patcher/claude-preload.js (linux/macOS) · %LOCALAPPDATA%\void-patcher\claude-preload.js (Windows) runtime preload hook
~/.config/systemd/user/vpcc-autoheal.timer Linux auto-heal trigger

🚀 Usage

Command Purpose
vpcc patch [-n] Apply all 96 patches. Idempotent, atomic, verified.
vpcc verify Every applied_marker present?
vpcc scan [-v] 🔬 Sig-scan — anchor offsets + regex hit.
vpcc scan --auto-heal 💊 Regenerate drifted regexes in patches/*.json.
vpcc scan --export-patch ID Print probable regex for ID from its anchors.
vpcc doctor Full health report.
vpcc watch -i 10 👁 Daemon — poll target; on change: backup + autoheal + re-patch + verify.
vpcc autoheal [-f] One-shot: drift → sync patches → re-patch → rollback on fail.
vpcc self-update Pull latest patches/*.json from GitHub, re-apply.
vpcc check-updates Local vs remote patch commit diff.
vpcc install-preload 🔌 Deploy runtime preload hook (layer 2).
vpcc uninstall-preload Remove preload hook.
vpcc rollback Restore latest backup.
vpcc status / vpcc list Target info / patch enumeration.

Example session

$ vpcc doctor
vpcc doctor
  vpcc ver   : 2.1.120
  patches    : 96
  target     : .../claude-code-linux-x64/claude
  format     : Bun SEA ELF
  sha256     : 989a82997d69
  size       : 234 MB
  sig drift  : 0 (all anchors locatable)
  applied    : all
  backups    : 3
  upstream   : current

$ vpcc watch -i 10 &
[1] vpcc watch — polling every 10s

🔓 AUP bypass stack

Layer Target Patches Effect
1 refusal stop-reason handler (s5K) 32 · 52 if(H!=="refusal")return; → unconditional
1 AUP refusal sentence 15 · 17 · 54 Replaced with authorization ack.
1 refusal explanation field 55 null out
1 permission-mode mapper (Xj$) 53 every mode → "allow"
1 jtH safety check 56 always {safe:true}
1 canUseTool safetyCheck deny 57 {allowed:false} branches → allow
1 sandbox rule deny 58 behavior:"deny"behavior:"allow"
1 tg7 write-prompt predicate 59 always false
1 classifier fail-open (×5) 14 · 16 · 26 · 33 no classifier can block
2 runtime JSON.parse wrapper preload stop_reason=refusalend_turn
2 runtime fetch SSE rewrite preload refusal tokens swapped in-flight
2 runtime Object.defineProperty hook preload canUseTool/shouldBlock/isHarmful neutralized by shape
2 stderr suppression preload residual AUP lines dropped
3 anchor-string sig-scanner scanner regex drift auto-heals from context window

Worked example — function s5K

before
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:!!K});
  
  let z = `${qP}: Claude Code is unable to respond to
           this request, which appears to violate our
           Usage Policy (https://…/legal/aup).${A}`;
}
after
(patches 52 + 54 + 55)
function s5K(H,$,q){
  return;                              // 52
  if(H!=="refusal") return;
  let K = q?.type==="refusal" ? null : null;  // 55
  
  let z = "Claude Code is processing this request       // 54
           under operator authorization.";
}

🧭 Byte offsets · v2.1.119 full patch map

Reference binary: @anthropic-ai/claude-code-linux-x64/claude SHA-256 prefix: cca43053f062 · size: 245 230 208 B · format: ELF 64-bit LSB, .bun section (active bundle + VFS copy — see 2.1.119 layout change below)

Every offset is live-resolved via vpcc scan against the current binary. The table is regenerated after every CC update — absolute addresses drift on every re-minification, regex anchors stay stable. Offset = marker-only (patch idempotency checked via applied_marker only; no scannable anchor needed). R column: ✓ = regex pattern resolvable · ~ = anchor-string fallback only.

All 77 scannable js_replace patches (2.1.119 ref build)
# Offset (hex) R Patch Effect
01 @0x002eef83 js-trust-dialog Auto-accept trust dialog, onboarding, and external includes in cli
02 js-bypass-mode Enable isBypassPermissionsModeAvailable in cli
03 @0x00902509 js-allow-skip-permissions Default allowDangerouslySkipPermissions to true (was false)
04 @0x07c248e3 js-disable-bypass-check Neutralize the operator disableBypassPermissionsMode check — prevents remote pol
05 @0x00f7ff6d js-plan-mode-refusal Remove plan-mode restriction that refuses to improve or augment code
06 @0x0732afdb js-session-bypass-mode Default sessionBypassPermissionsMode to true — sessions start in bypass mode
07 @0x0732b06b js-session-trust Auto-accept session trust — skip workspace trust verification on session start
08 @0x0212ae46 js-classifier-failopen Auto-mode classifier fails open instead of closed — when classifier is unavailab
09 @0x01971e61 js-aup-refusal Replace AUP violation refusal message with operator authorization — removes the
10 js-classifier-all-failopen Consolidated classifier error paths fail open (allow) instead of closed (block)
11 @0x01971f4f js-aup-refusal-2 Replace second AUP violation refusal message (the 'double press esc' variant)
12 @0x00b2aa80 js-prompt-injection-sysprompt Remove prompt injection flagging instruction from system prompt — Claude no long
13 @0x00640d87 js-metrics-disable Disable metrics/telemetry reporting to api
14 @0x0000c9f9 js-subscription-max Pin client-side subscription check to 'max' — prevents feature downgrades from t
15 @0x002b1d2c js-additional-protection Disable x-anthropic-additional-protection header — stops sending server-side con
16 js-plan-mode-disable Disable plan-mode enforcement — planModeRequired always false
17 @0x07e4c1d0 js-security-guardrail Replace the hardcoded 'security research guardrail' (CsK constant) that refuses
18 @0x00f7ff64 js-malware-refusal Remove malware-code 'MUST refuse to improve or augment' directive — operator is
19 @0x01be5ad6 js-plan-mode-cannot Remove plan-mode 'You CANNOT and MUST NOT write' hard directive — allow plan-mod
20 js-denial-workaround Replace the 'don't work around this denial maliciously' directive (C_7) with per
21 @0x07b3395e js-webfetch-preflight-skip WebFetch: skip domain_info preflight switch — treat every URL as allowed, no api
22 @0x00195b8b js-statsig-gate-kill-switches-off Tw() sync Statsig gate returns false for known kill-switch gates (tengu_disable_
23 @0x000e6782 js-agent-summary-disable A78/H() runs a hidden per-agent background summarization API call on a timer ([A
24 js-bash-default-timeout-raise Raise BASH_DEFAULT_TIMEOUT_MS fallback from 120 s to 3600 s (1 h) when the env v
25 @0x0089f985 js-bash-max-timeout-floor-raise Raise BASH_MAX_TIMEOUT_MS floor from Math
26 @0x0002bd3d js-mcp-sendrequest-timeout-raise Raise MCP client default per-request timeout from 30 s to 300 s
27 @0x004d00b6 js-max-thinking-default-on Force Z7H() (isExtendedThinkingEnabled) to always return true, ignoring MAX_THIN
28 @0x07c0f4a3 js-generated-with-claude-footer-off Also blank the PR-body attribution footer 🤖 Generated with [Claude Code](URL)
29 @0x00b7d78b ~ js-bypass-perm-mode-not-available-fake-ok Make runtime attempts to switch to permissionMode: bypassPermissions succeed e
30 @0x0801368e js-bypass-perm-mode-not-available-sdk-fake-ok Same as js-bypass-perm-mode-not-available-fake-ok but for the SDK/control-respon
31 @0x00bfb03f js-chrome-subscription-require-skip Remove the Claude-in-Chrome subscription gate that shows 'chrome-requires-subscr
32 @0x07dfa86f js-voice-mode-subscription-gate-skip Remove the 'Voice mode requires a Claude
33 @0x07c2600d js-auto-mode-disable-settings-bypass Make b56() (isAutoModeDisabledBySettings) always return false so auto mode is ne
34 @0x00b38d1c js-non-streaming-fallback-always-on Ignore CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK / tengu_disable_streaming_to_no
35 @0x01971d6f js-s5K-refusal-neutralize-v2.1.114 Refusal stop_reason handler — short-circuit to silently ignore
36 @0x07420385 js-Xj-permissionmode-allowall-v2.1.114 Permission-mode mapper — force every mode to return "allow"
37 @0x002b4fe1 js-experimental-betas-always-on Ignore CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS env so experimental anthropic-beta
38 @0x0014c2ed js-agent-teams-env-or-cli-always-on Enable experimental Agent Teams without needing CLAUDE_CODE_EXPERIMENTAL_AGENT_T
39 @0x01971e61 js-aup-refusal-sanitize-v2.1.114 Neutralize the composed AUP refusal message (qP + Usage Policy link) at its cons
40 @0x009bef3e js-plugin-deny-allowlist-passthrough Short-circuit the plugin-channel allowlist check that emits 'server X is not on
41 @0x003cb298 js-refusal-explanation-null-v2.1.114 Null out refusal explanation field regardless of minified holder name
42 @0x00b0d11d js-jtH-safe-always-true-v2.1.114 Force the safety-check helper to always return {safe:true}
43 @0x003e9702 js-plugin-session-telemetry-off Stub pOK() — the function that emits tengu_plugin_enabled_for_session for ev
44 @0x07708e04 js-canusetool-safetycheck-allow-v2.1.114 In canUseTool permission gate, rewrite every {allowed:false,decisionReason:{type
45 @0x0043c950 js-plugin-load-failed-telemetry-off Stub FOK()tengu_plugin_load_failed event (plugin error categorization sen
46 js-handle-uri-deeplink-disable Disable the hidden --handle-uri <cc:// URI> deep-link handler that runs before
47 @0x00619dc8 js-rule-deny-allow-v2.1.114 Flip sandbox rule deny → allow
48 @0x00736689 js-statsig-tengu-kairos-brief-default-true Flip b2('tengu_kairos_brief', !1,
49 @0x0076f1bf js-twostage-classifier-always-on Force HH7() (two-stage classifier gate) to always true so auto-mode uses the imp
50 @0x0760f1bc js-autocompact-default-off Flip default_global_config
51 @0x00118c0a js-tengu-plugin-prematureread-off Drop the tengu_plugin_settings_premature_read event emitted on every uncached
52 @0x000dced1 ~ js-hardfail-flag-disable Neutralize the --hard-fail CLI flag so process does not exit on first subagent
53 @0x007c84be js-bash-max-output-default-raise Raise BASH_MAX_OUTPUT_LENGTH soft default from 30k to 100k chars and cap from 15
54 @0x008220ea js-task-max-output-default-raise Raise TASK_MAX_OUTPUT_LENGTH (subagent Task tool result cap) default from 32k to
55 @0x0772506e js-agent-implicit-fork-max-turns-raise Raise implicit-fork subagent maxTurns from 200 to 999
56 @0x01d86185 js-computer-use-policy-refusal Neutralize xi8() computer-use policy denylist refusal
57 @0x07c0f4d9 js-co-authored-by-claude-off Strip hardcoded Co-Authored-By: Claude attribution line from generated commits
58 @0x00a14c04 js-plugin-org-denylist-passthrough Neutralize enterprise allowedChannelPlugins denylist rejection message
59 js-econnrefused-silent Silence ECONNREFUSED/ENOTFOUND throws in plugin marketplace download so they fal
60 js-webfetch-lyrics-copyright-clause Remove the WebFetch system prompt block that forbids exact song lyrics, imposes
61 @0x076ee9ff js-command-injection-classifier-neutralize Bash-prefix classifier flags ANY shell with ${} or backticks as 'command_injecti
62 @0x01976225 js-dangerous-shell-prefix-neutralize Same classifier branch flags 'git' or any entry in bZ_ dangerous-shell-prefix se
63 @0x0090390a js-bypass-permissions-async-kill-v2_1_119 v2
64 @0x07a9ade5 js-bypass-permissions-sync-kill-v2_1_119 v2
65 @0x0194c531 js-always-enable-effort-on Flip CLAUDE_CODE_ALWAYS_ENABLE_EFFORT gate to always true — unlocks 'high effort
66 @0x00831e5f js-plan-mode-interview-phase-on Flip the plan-mode interview-phase gate default from false to true so plan mode
67 @0x00b2ba0f js-verified-vs-assumed-on Flip tengu_verified_vs_assumed gate default to true — makes Claude emit the 'dis
68 @0x02594fbf js-marketplace-etimedout-silent Sibling to patch 75: plugin marketplace fetch also throws on ETIMEDOUT
69 @0x00b95c63 js-destructive-command-warning-off tengu_destructive_command_warning gates a UI warning modal on dangerous bash com
70 @0x00862c71 js-classifier-summary-kill-on Flip tengu_classifier_summary_kill gate default to true so the 'summary' classif
71 @0x00b309f9 js-fgts-default-on Flip tengu_fgts (fine-grained tool streaming) default to true — enables eager_in
72 @0x07c0f4b3 js-generated-with-footer-off-extra Patch 44 only neutralizes the first attribution template
73 @0x000dc1c3 js-disable-nonessential-traffic-default ha6() determines the telemetry-network policy
74 js-no-doc-creation-directive-off Remove the 'NEVER create documentation files (*
75 @0x00798b73 js-auto-background-agents-on Flip kX1() auto-background-agents timeout default to 120000ms (enabled) without
76 @0x008ec447 js-session-memory-on Flip tengu_session_memory default to true so session-memory extraction runs with
77 @0x008b1d12 js-cold-compact-on Flip tengu_cold_compact default to true so compaction can run in the 'cold' (non

Regenerate locally

# full scan — all anchors, live offsets
vpcc scan -v

# single-patch deep-dive — view regex matches + context
vpcc scan --export-patch js-s5K-refusal-neutralize-v2.1.114

# ad-hoc grep (Linux x64 sample)
SEA=$(npm root -g)/@anthropic-ai/claude-code/node_modules/@anthropic-ai/claude-code-linux-x64/claude
rg -oab --text 'tengu_refusal_api_response|function s5K|Claude Code is unable' "$SEA"

📋 Patch catalog (96 total)

🛑 AUP & refusal · 9
# ID Effect
15 js-aup-refusal Legacy AUP phrase swap
17 js-aup-refusal-2 "double press esc" variant
27 js-malware-refusal Malware-specific refusal
29 js-denial-workaround Denial-path workaround
30 js-webfetch-preflight-skip WebFetch preflight refusal skip
32 js-refusal-stop-reason-neutralize Legacy gM4 (≤ 2.1.112)
⭐52 js-s5K-refusal-neutralize-v2.1.114 v2.1.114 s5K early-return
⭐54 js-aup-refusal-sanitize-v2.1.114 Refusal sentence rewrite
⭐55 js-refusal-explanation-null-v2.1.114 null explanation field
🔓 Permission / bypass · 7
# ID Effect
01 bypass-permissions Settings default
09 js-allow-skip-permissions --dangerously-skip-permissions allowed
10 js-disable-bypass-check Runtime bypass guard off
12 js-session-bypass-mode Session bypass persistence
⭐53 js-Xj-permissionmode-allowall-v2.1.114 Xj$ always returns "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
🎯 canUseTool / safety / sandbox · 4
# ID Effect
⭐56 js-jtH-safe-always-true-v2.1.114 jtH → {safe:true}
⭐57 js-canusetool-safetycheck-allow-v2.1.114 allowed:false safetyCheck → allow
⭐58 js-rule-deny-allow-v2.1.114 Sandbox rule deny → allow
⭐59 js-tg7-permission-writer-false-v2.1.114 tg7 → false (no write prompts)
🧠 Classifier · 5
# ID Effect
14 js-classifier-failopen Generic classifier fail-open
16 js-classifier-all-failopen All classifier paths → allow
26 js-security-guardrail Guardrail wrapper off
33 js-auto-mode-classifier-shouldblock-false Auto-mode classifier
js-twostage-classifier-always-on Force two-stage classifier always
📋 Plan mode · 4 Patches 11 · 24 · 28 + envelope. Plan mode refusal UI off, coercion to `allow`.
💳 Subscription / entitlement / A/B · 8 21 Max pin · 25 A/B unlock · 34/35 statsig kills · 38 policy allow-all · 48/49/50 chrome/voice/brief entitlement skip · `js-experimental-betas-always-on`.
📡 Telemetry / metrics / logging · 6 19 metrics · 36 datadog sink · 37 1P events · 39 agent summary · 44 Co-Authored-By footer · 45 elevated-priv stderr.
🪝 Hooks / env / wrapper · 7 02 env flags · 05 auto-allow hook · 06 patch-guard · 07 mcp-guard · 08 cli syntax self-heal · 20 seccomp passthrough · 23 extra protection.
⏱ Timeout / capacity · 5 40/41 bash timeouts · 42 MCP sendrequest · 43 max_thinking · raised bash/task output defaults.
🧩 Plugin / misc · 22 Plugin telemetry off, deeplink disable, premature-read off, hardfail flag disable, agent implicit fork max-turns raise, computer-use policy refusal, plugin denylist passthrough, … (see `vpcc list`).

⭐ = added in this v2.1.114 release (patches 52-59).


🏗️ Architecture

%%{init:{'theme':'dark','themeVariables':{'primaryColor':'#00D4FF','fontFamily':'JetBrains Mono'}}}%%
graph TD
    W["~/.local/bin/claude<br/>bash wrapper"]
    W -->|detect| B1["npm @anthropic-ai/claude-code-linux-x64/claude"]
    W -->|detect| B2["/opt/claude-code/bin/claude"]
    W -->|detect| B3["cli.js legacy path"]
    W -->|"BUN_OPTIONS=--preload"| P["~/.local/share/void-patcher/claude-preload.js"]
    B1 --> BUN["Bun runtime"]
    B2 --> BUN
    B3 --> NODE["Node runtime"]
    BUN -->|".bun section"| JSC["JSC parser"]
    JSC -->|"patched bytes"| RUN["Claude Code running"]
    P --> RUN
    RUN -.-> WATCH
    WATCH["vpcc watch"] -->|"sha drift"| HEAL["auto-heal"]
    HEAL -->|"regex regen"| PATCHES[("patches/*.json")]
    PATCHES --> PATCH["vpcc patch"]
    PATCH --> B1
    style W fill:#00D4FF,color:#0D1117
    style P fill:#FF6B9D,color:#0D1117
    style HEAL fill:#E9D900,color:#0D1117
    style RUN fill:#3FB950,color:#0D1117
Loading
vpcc/
├── __init__.py    — version 2.1.120
├── __main__.py    — 14 sub-commands
├── updater.py     — GitHub API sync + autoheal state machine
└── scanner.py     — SigScanner + auto-heal regen

patches/           — 96 signed JSON patches
contrib/
├── preload/claude-preload.js   — runtime monkey-patch layer
└── systemd/                    — autoheal timer unit

🔄 Auto-update flow

%%{init:{'theme':'dark','themeVariables':{'primaryColor':'#00D4FF','fontFamily':'JetBrains Mono'}}}%%
flowchart LR
    U[npm update -g<br/>@anthropic-ai/claude-code] --> S[sha changes]
    S --> W{vpcc watch}
    W -->|sha drift| BK[backup<br/>~/.vpcc/backups/]
    BK --> AH[vpcc autoheal]
    AH --> V1{vpcc verify}
    V1 -->|markers present| OK[update state · done]
    V1 -->|markers missing| SU[vpcc self-update]
    SU --> AS[auto-heal scanner]
    AS --> PT[vpcc patch]
    PT --> V2{node --check / bin --version}
    V2 -->|ok| OK
    V2 -->|fail| RB[vpcc rollback]
    RB --> LB[restore pre-patch backup]
    style W fill:#00D4FF,color:#0D1117
    style AS fill:#E9D900,color:#0D1117
    style OK fill:#3FB950,color:#0D1117
    style RB fill:#FF4F4F,color:#0D1117
Loading

Triggered three ways:

  1. vpcc watch — polling daemon (-i seconds, default 10).
  2. systemd timercontrib/systemd/vpcc-autoheal.{service,timer} (every 15 min).
  3. Manualvpcc autoheal -f.

State at ~/.vpcc/state.json (synthetic example):

{
  "last_cc_sha":    "12bd4b0916de",
  "last_cc_kind":   "bun_sea",
  "patches_commit": "a1b2c3d4e5f6",
  "patches_count":  96,
  "updated_at":     "2026-04-24T10:00:00+00:00"
}

Backups: 10 most recent claude.<ts>.<sha12>.{js,exe}.bak in ~/.vpcc/backups/.


🔬 Manual offset discovery · r2 / pwndbg / rg

via ripgrep (fastest)
SEA=$(npm root -g)/@anthropic-ai/claude-code/node_modules/@anthropic-ai/claude-code-linux-x64/claude
rg -oab --text \
  'Acceptable Use|tengu_refusal_api_response|function s5K|Xj\$|function jtH|function tg7|safetyCheck|classifierApprovable|behavior:"deny"' "$SEA"
via radare2
r2 -AA -q -c '
  izz~tengu_refusal
  izz~bypassPermissions
  izz~"function s5K"
  /j tengu_refusal_api_response
' "$SEA"
  • izz lists strings in every section (including .bun).
  • /j <pattern> returns JSON with virtual + file offsets.
  • pdf @ <vaddr> prints the decoded function body.
via pwndbg (dynamic)
pwndbg claude
pwndbg> start
pwndbg> find 0x00007fff00000000, +0x10000000, "tengu_refusal_api_response"
pwndbg> x/200s $_
pwndbg> telescope $_ 8

Useful when SEA loads .bun into a non-predictable VMA.

via vpcc scanner
vpcc scan -v
vpcc scan --export-patch js-s5K-refusal-neutralize-v2.1.114
vpcc scan --auto-heal    # rewrite every drifted regex in place

When regex=N but the anchor is still present → --auto-heal regenerates. When all three anchors vanish → the preload hook (layer 2) still catches refusals at the JS runtime.


🧯 Troubleshooting

Symptom Cause Fix
no runnable Claude Code found npm install incomplete npm i -g @anthropic-ai/claude-code && vpcc patch
cli.js syntax INVALID — aborted Regex placed bad substitution Already rolled back. vpcc scan --auto-heal.
verify failed: rc=X after patch Binary refuses to run vpcc rollbackvpcc scan -v → issue with sha.
ELF parse failed: .bun not found CC changed format Open issue; attach file $SEA + rg -oab --text .bun.
Bun bytecode format — text patching not supported Anthropic enabled @bun @bytecode Use preload hook only; byte-patching disabled.
sig drift in vpcc doctor Minifier renamed vpcc scan --auto-heal.
patches_commit stuck GitHub API rate-limit export GITHUB_TOKEN=…vpcc self-update -f.
Still seeing AUP refusal preload hook not installed vpcc install-preload → relaunch claude.

🛡️ Authorization & use

What this tool is

Research software for a single operator-owned workstation. Sole purpose: give you, the account holder of a Claude Max subscription unconditional write-access to your own locally-cached Claude Code binary, and unlock your own data from client-side gating that does not materially affect what Anthropic's servers enforce anyway.

What ships

  • No credentials, keys, tokens, cookies, or telemetry beacons are collected, stored, or transmitted.
  • No callbacks beyond GitHub's public REST API (api.github.com/repos/VoidChecksum/void-patcher-cc/*) for patch-catalog sync.
  • No auto-execution on machines other than yours — every entry point is a manual invocation (vpcc, install.sh, install.ps1, or the optional systemd timer you enable).
  • All patches are atomic, idempotent, and verified by running claude --version on a tmp copy before atomic-swap.

Rules for downstream users — mandatory, read before install.sh

By cloning, installing, or running any part of this repository you agree that:

  1. Personal use only. You are the sole human operator of the hardware this runs on and the account holder of the Claude Max/Pro subscription being patched. No shared machines, no redistribution of patched binaries, no running this on someone else's account.
  2. Your Claude account, your compliance. Anthropic's Usage Policy (AUP) and Commercial Terms still bind you. Removing a client-side refusal string does not authorize you to use Claude for anything prohibited by the AUP — server-side enforcement, rate limiting, abuse detection, and account-level review remain fully operational and will act on your account.
  3. No evasion of server-side controls. Anything that crosses the wire to Anthropic (rate limits, model-safety classifiers, abuse signals, subscription checks at the control-plane level) is out of scope for this tool and must not be bypassed by any means.
  4. No use against employer hardware / accounts / subscriptions without written authorization from the device owner and the account holder — even if that's the same legal entity, get it in writing.
  5. No abuse-enabling redistribution. You may fork, study, and share improvements under GPL-3.0. You may not package the patched binary for distribution, resell the capability, or advertise this tool as a way to abuse Anthropic's services.
  6. No liability. Software is AS-IS. You accept all consequences — account termination, subscription forfeiture, civil action — that arise from your use of this tool.
  7. Security-research context only for any patch that touches refusal or safety scaffolding. These patches are documented for transparency and audit purposes; using them outside an authorized research or single-operator dogfood context is your own risk.

If you cannot satisfy all seven, do not install this tool. Use the stock Claude Code binary from @anthropic-ai/claude-code.

Machine-level safety guarantees

  • Every patch is verified (node --check for cli.js · --version exec for Bun SEA) and rolls back atomically on failure.
  • Pre-patch binary is stored under ~/.vpcc/backups/ — timestamped and sha-256-named for deterministic restore.
  • Every patch is idempotent: re-applying never double-patches (cheap applied_marker check).
  • Pre-flight refuses to run on binaries it doesn't recognise (unknown magic bytes → abort, no write).
  • Bun SEA bytecode integrity: patches only touch the active entry bundle via _find_active_bundle_bounds(); VFS copy and bytecode cache stay pristine (see 2.1.119 layout change).

Threat model

vpcc assumes the operator has physical + user-level access to the host and an already-installed, already-authenticated Claude Code binary. It does not:

  • Elevate privileges (no setuid, no sudo inside code, no kernel hooks).
  • Modify any binary it didn't install (no /usr/bin, no system daemons).
  • Auto-apply patches without an explicit vpcc patch / vpcc autoheal invocation.
  • Persist across user accounts — everything lives under $HOME/.vpcc, $XDG_BIN, $XDG_DATA_HOME.

🏷️ Credits & refs

Licensed GPL-3.0-or-later.


 $ vpcc doctor
   vpcc ver   : 2.1.120
   patches    : 96
   sig drift  : 0 (all anchors locatable)
   applied    : all
   upstream   : current

⚡ 96 patches · 3 defense layers · auto-heals through every CC update ⚡