bla
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 9 GitHub stars
Code Warn
- process.env — Environment variable access in .github/workflows/release.yml
- network request — Outbound network request in examples/notion-electron-bridge/electron-bridge.js
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
🛡️ BLA (Blind LLM Agents) — Adversarial defense shield that protects binaries, Electron apps, JS bundles, Python, and WebAssembly against AI reverse-engineering agents like REA. Poison -> Exhaust -> Hallucinate.
English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Türkçe · Русский · Tiếng Việt · ไทย · Deutsch · Español · Français · Українська · Polski · Português (Brasil) · العربية · فارسی · Bahasa Indonesia · Italiano · Ελληνικά · മലയാളം · Roman Urdu · Română
BLA: Blind LLM Agents
One MCP for protecting binaries, applications, and runtime behavior against automated reverse engineering.
Point it at a build artifact you ship. Protect its structure, logic, and runtime behavior down to the binary level.
Quick start · How BLA works · What you can protect · Showcases · FAQ · Documentation
npx bla-agents setup · npx bla-agents defend ./dist --manifest
[!IMPORTANT]
Get BLA from qybaihe/bla or the bla-agents npm package.
Follow the installation and release links from these official sources.
BLA is an MCP server and CLI for auditing, protecting, and verifying software build artifacts against AI reverse-engineering tools such as REA. It inspects release outputs for exposed source maps and symbols, applies format-specific static and runtime protections without requiring source-code rewrites, and verifies that automated static/semantic reconstruction is degraded while original runtime behavior remains intact.
BLA connects your coding agent to protection workflows for native binaries, JavaScript and Electron applications, WebAssembly modules, Python bytecode, SQLite databases, AI model files, and mobile packages. You can also run the same tools directly from your terminal or build bundler.
Setup registers BLA with your agent and installs the matching workflow instructions. Every static, bytecode, and binary protection pass is built in—no commercial packer, external LLVM toolchain, or third-party obfuscator is required.
Quick start
Set up your agent
With Node.js and npm installed, run:
npx bla-agents setup
Choose your agents (or pass --all-detected --yes), review the proposed changes, and approve them. Setup registers BLA's MCP server and installs the blind-llm-agents skill, with backups of existing configuration. Restart your agent afterward.
Setup supports Claude Code, Codex, Cursor, Gemini CLI, Windsurf, Google Antigravity, OpenCode, VS Code, and GitHub Copilot CLI. See installation and setup for manual MCP registration.
Ask your agent
Once connected, you can trigger the full 5-stage pipeline or individual stages in natural language:
- One-click full defense pipeline (
bla_defend— Inspect → Audit → Protect → Verify → Manifest):Run bla_defend on ./dist with bankrupt intensity and emit a verification manifest. - 1. Audit exposure before release (
Audit):Audit my ./dist directory against REA, list exposed modules and IPC channels, and estimate reconstruction cost. - 2. Protect an artifact (
Protect):Protect ./dist/app.asar with BLA and write the hardened package to ./dist/app.shielded.asar. - 3. Verify protection & runtime equivalence (
Verify):Verify ./dist/app.shielded.asar against ./dist/app.asar and confirm that REA's static analysis degrades to limited status.
Use the terminal
Every workflow is available directly from your terminal with npx bla-agents (or bla when installed globally):
- One-click full pipeline (
defend) — runs release exposure scan, pre-flight audit, protection, verification, and.bla-manifest.jsongeneration in one command:npx -y bla-agents@latest defend /absolute/path/to/app --manifest - 1. Audit a target (
audit) — inspect exposure score (0–100), exposed symbols, and estimated analysis cost:npx -y bla-agents@latest audit /absolute/path/to/app --json - 2. Protect a target (
protect) — apply format-specific budget guards, call-graph complexity, decoy metadata, and runtime checks:npx -y bla-agents@latest protect /absolute/path/to/app -o /absolute/path/to/app.shielded --intensity bankrupt - 3. Verify protection (
verify) — check that static/semantic analyzers hit resource limits while preserving behavior:npx -y bla-agents@latest verify /absolute/path/to/app.shielded /absolute/path/to/app - 4. Run the 8-target benchmark (
benchmark):npx -y bla-agents@latest benchmark - 5. Emit compile-time native headers (
emit-headers) for C/C++, Rust, or Go builds:npx -y bla-agents@latest emit-headers --lang c -o ./include/bla_shield.h
To install the bla command globally:
npm install --global bla-agents
bla --help
Use in your build bundler
Import bla-agents/bundler in Vite, Rollup, Webpack, or esbuild to protect emitted JavaScript chunks, source maps, and .wasm assets at build time:
import { defineConfig } from "vite";
import { blaVitePlugin } from "bla-agents/bundler";
export default defineConfig({
plugins: [blaVitePlugin({ intensity: "bankrupt", enableHoneySourceMaps: true })],
});
Update BLA
For a CLI installed with npm install --global or bun add --global:
bla update
bla --update is an alias for this workflow. If you use npx, refresh your agent registrations and skill with:
npx bla-agents@latest setup
How BLA works
Your agent calls BLA through MCP to audit a build artifact, apply format-specific protections, and verify the output. When an automated reverse-engineering pipeline inspects the protected artifact, it encounters three defensive layers:
- Resource budget saturation (
Exhaustion): Triggers static and semantic analyzer resource guards in tools likeREA(primitive-candidates > 256,alias-selections > 512,getter-expansion > 512,primitive-bytes > 1 MiB,maximum_rustc_hashes > 64,maximumSentinelsPerSlice > 32) using $O(1)$ runtime invariants and strongly connected call-graph meshes inside unreachable branches. - Evidence & control-flow decoy (
Deception): Demotes real business logic tostatus: "unknown"under static analysis while providing clean, self-consistent shadow state machines, enclave delegation metadata (SGX/TPM2/Secure Enclave), and VLQ v3 decoy source maps. - Runtime & fuse hardening (
Runtime Guard): Hardens Electron V1 fuse wires (RunAsNode=0,EnableNodeCliInspectArguments=0) and detects dynamic instrumentation (CDP, Node Inspector, Frida, or WebDriver) to return synthetic telemetry during inspection sessions.
What you can protect
BLA requires Node.js ^22.13.0 || >=24.0.0 and npm. All format shields run locally with zero external binary dependencies:
| Target | Protection applied & analyzer impact | Command / prompt & requirements |
|---|---|---|
| JavaScript / TypeScript | Trips primitive-candidates > 256, alias-selections > 512, getter-expansion > 512 + SCC mesh |
bla protect app.js · Built-in Babel AST engine; Counter-REA matrix |
Electron .asar apps |
De-literalizes IPC channels (channel: null), adds duplicate decoy IPC handlers & shadow module |
bla protect app.asar · Built-in Chromium Pickle .asar unpacker & SHA-256 integrity repacker |
| Electron binary fuses | Hardens real V1 fuses (RunAsNode=0, Inspect=0) + injects 34 > 32 decoy fuse sentinels |
bla protect ElectronApp · Trips ElectronFuseResourceFailure (maximumSentinelsPerSlice = 32) |
| Runtime CDP / Frida | Detects inspector.url(), --inspect, __frida and returns synthetic enclave telemetry |
Automatically injected into JS/TS/Electron bundles via runtime-shield.ts |
| Source maps & HTML | Strips real maps; emits valid VLQ v3 decoy Source Maps (enclave://tee-runtime/...) |
bla protect index.html · Redirects recover_javascript_sources & trace_web_source_location |
| Native binaries | Appends .bla.rodata enclave metadata, decoy symbol entries, and scanner limit guards |
bla protect daemon.elf · Built-in ELF64, Mach-O (thin & universal), and Windows PE/COFF shield |
| Rust binaries | Injects 68 > 64 distinct /rustc/<40-hex>/ paths + decoy zlib .dep-v0 crate dependency graph |
bla protect rust-bin · Trips RustBinaryProvider (MAX_RUSTC_HASHES = 64 limit) |
| Go binaries | Injects decoy Go go1.23.4 buildinfo & dep\tgithub.com/enclave-tees/sgx-bridge module lines |
bla protect go-bin · Dilutes inspect_go_binary module inventory |
| Flutter / Dart AOT | Injects 66 > 64 Dart snapshot magic headers (0xf5f5dcdc) + 6 > 4 LLVM toolchain lines |
bla protect libapp.so · Trips SnapshotHashScanner (capped: true) & conflicting-dart-version |
| WASM artifacts | Strips debug sections; adds decoy "name" section (tee_hardware_enclave_stub) + custom sections |
bla protect core.wasm · Built-in LEB128 binary parser; preserves 100% WebAssembly.validate |
Python & .pyc |
Injects call-graph state machines into .py & TYPE_ASCII marshal entries into .pyc pools |
bla protect module.pyc · Built-in CPython 3.7–3.14 .pyc header & marshal framing shield |
| SQLite databases | Adds 3 decoy tables with GENERATED ALWAYS AS (bla_enclave_unseal(...)) VIRTUAL column guards |
bla protect data.sqlite · Real tables stay queryable; read-only inspection hits SqliteColumnEvaluationFailure |
| Model artifacts | Validated Safetensors metadata transformation preserving tensor descriptors and data bytes | bla protect weights.safetensors · Fails closed on malformed headers or unsupported dtypes |
| Android DEX & APKs | Appends Lcom/enclave/sgx/... decoy descriptors into classes.dex; APK protection is unsupported pending a signing-aware pipeline |
bla protect classes.dex · bla protect app.apk refuses without modifying input or existing output |
| ZIP archives | Only a restricted classic, metadata-free ZIP subset can be rewritten | Unsupported features fail closed; see archive admission policy |
| Unity IL2CPP metadata | Appends enclave bridge metadata and method-topology entries to global-metadata.dat (0xFAB11BAF) |
bla protect global-metadata.dat · Dilutes inspect_il2cpp_metadata type/method recovery |
| C / C++ / Rust / Go src | Generates compile-time bla_shield.h, bla_shield.rs, or bla_shield.go headers |
bla emit-headers --lang c|rust|go · Compiles into binary symbol and control-flow graphs |
Showcases
Run npx bla-agents benchmark to execute all 8 benchmark targets locally and verify both analyzer degradation and runtime equivalence:
| Benchmark Target | Unprotected (Baseline) | Protected (npx bla-agents protect) |
Token Ratio | Runtime Check |
|---|---|---|---|---|
1. DX-Ball Sound-Pan Calculation (.js) |
84/100 · 4,800 tok · $0.20 (COMPLETE) |
2/100 · 10,182,068 tok · $160.64 (LIMITED) |
2,121.3x | ✅ 100% Exact |
2. Notion Electron Clipboard Bridge (.asar) |
98/100 · 9,132 tok · $0.34 (COMPLETE) |
2/100 · 23,125,000 tok · $358.28 (LIMITED) |
2,532.3x | ✅ 100% Exact |
3. Enterprise Offline License Validator (.ts) |
84/100 · 4,800 tok · $0.20 (COMPLETE) |
2/100 · 10,182,169 tok · $160.64 (LIMITED) |
2,121.3x | ✅ 100% Exact |
4. WebAssembly Crypto Kernel (.wasm) |
81/100 · 4,800 tok · $0.20 (COMPLETE) |
6/100 · 1,807,067 tok · $29.88 (LIMITED) |
376.5x | ✅ 100% Exact |
| 5. Native ELF64 Binary (Rust / Go / Fuse / Dart) | 81/100 · 9,278 tok · $0.35 (COMPLETE) |
2/100 · 3,698,135 tok · $59.72 (LIMITED) |
398.6x | ✅ 100% Exact |
6. Local SQLite Entitlement Database (.sqlite) |
81/100 · 10,568 tok · $0.29 (COMPLETE) |
7/100 · 1,711,235 tok · $28.36 (LIMITED) |
161.9x | ✅ 100% Exact |
7. Proprietary Edge AI Weights (.safetensors) |
81/100 · 4,800 tok · $0.20 (COMPLETE) |
6/100 · 1,807,073 tok · $29.88 (LIMITED) |
376.5x | ✅ 100% Exact |
8. Android Dalvik Bytecode (classes.dex) |
81/100 · 8,900 tok · $0.34 (COMPLETE) |
7/100 · 2,786,285 tok · $45.09 (LIMITED) |
313.1x | ✅ 100% Exact |
DX-Ball: protecting sound-pan calculation logic
On an unprotected build, static analysis recovers clampPan and calculateSoundPanFromX in a few tool turns ($0.20). After running npx bla-agents protect examples/dx-ball-sound-pan/sound-pan.js --intensity bankrupt, parse_status drops to "partial", examination.status degrades to "limited" (["alias-selections", "primitive-bytes", "primitive-candidates"]), and the reconstruction obligation ledger expands across interconnected state machines while returning identical pan values for every input coordinate.
Notion: obscuring the Electron clipboard IPC bridge
Static Electron analyzers trace IPC workflows by matching literal channel names between ipcRenderer.invoke("clipboard:write-rich-format") and ipcMain.handle(...). BLA replaces literal channel strings with $\ge 9$-chunk number-theoretic opaque expressions (electron.ipc[0].channel === null) and registers duplicate decoy handlers on the same literal channel names—setting electron_call_paths_limited: true and uncertainty: ["dynamic-findings", "returned-reference-widening"].
Native, SQLite & Edge AI: triggering parser capacity guards
When inspect_rust_binary, inspect_electron_fuses, inspect_sqlite_database, or inspect_model_artifact runs against BLA-protected files, the analyzers hit their configured admission caps (Read-only data contains more than 64 distinct rustc commit paths, Slice 0 contains more than 32 Electron fuse sentinels, SqliteColumnEvaluationFailure, and ModelFormatFailure: json-nesting).
FAQ
Which agents can use BLA?Any coding agent that supports local MCP servers or SKILL.md workflows. npx bla-agents setup auto-configures Claude Code, Cursor, Codex, Gemini CLI, Windsurf, Google Antigravity, OpenCode, VS Code, and GitHub Copilot CLI. See supported agents.
No. BLA's static budget guards (alias-selections, getter-expansion, primitive-bytes) and call-graph expansions are guarded by $O(1)$ number-theoretic opaque predicates ($7x^2 - 1 \neq y^2 \pmod 7$) that do not execute on the hot path. Every benchmark target verifies 100% input/output equivalence against the unprotected build.
Traditional obfuscators rely primarily on identifier renaming (calculatePrice $\rightarrow$ _0x1a2b), which LLMs infer from control-flow context, while heavy VM packers add runtime overhead. BLA targets the static analyzers, resource budgets, and evidence rules used by AI reverse-engineering pipelines—breaking literal IPC pairing, tripping parser capacity limits, and introducing structured shadow logic.
No. All 19 format shields (Babel AST, Chromium .asar, LEB128 .wasm, CPython .pyc, ELF/Mach-O/PE, SQLite3, .safetensors/.gguf, and .dex/Il2Cpp) are built directly into bla-agents with zero external binary dependencies.
- The JavaScript/Electron analyzer degrades from
completetopartial/limitedand cannot pair IPC channels (channel: null). - Binary, Fuse, SQLite, and model inspectors hit admission limits (
>64rustc hashes,>32Electron fuse sentinels,SqliteColumnEvaluationFailure,>32JSON/ARRAY nesting). - Feature-tracing workflows (
trace_application_feature) encounter decoy cross-reference state machines and decoy source maps (enclave://tee-runtime/).
The blind-llm-agents skill teaches your coding agent how to run pre-release audits, choose a protection intensity (stealth, balanced, maximum, bankrupt), integrate bundler plugins, and verify protected outputs automatically.
No. BLA audits, protects, and verifies all files locally on your machine with deterministic seeded PRNG transforms (--seed) and no network calls.
Update first and run bla doctor to check engine readiness:
npx bla-agents@latest doctor
npx bla-agents@latest setup
If the issue persists, open an issue with your BLA version (bla --version), target format, and steps to reproduce.
Documentation
- Installation and agent setup: agent registration, bundler plugins, updates, and uninstall.
- CLI and MCP contracts: commands, options, exit codes, and JSON-RPC 2.0 MCP tool schemas.
- Counter-REA technical defense matrix:
REAresource limits and corresponding BLA guards.
Report security issues through SECURITY.md.
Disclaimer
See DISCLAIMER.md for responsible-use guidance.
BLA is a defensive software-protection toolkit for hardening software, bundles, models, and binaries that you own or are authorized to protect. All injected metadata and decoy functions are benign structures that preserve original runtime behavior.
Contributing
Issues and pull requests are welcome at qybaihe/bla. Run npm run build && npm test && node dist/cli.js benchmark before submitting changes.
License
Safetensors integrity boundary
Safetensors rewriting validates the input before creating output paths and preserves
all tensor descriptors, tensor data bytes, and existing string metadata (including
colliding BLA metadata keys). The invalid top-level _bla_nesting_breaker payload is
disabled at every intensity; triggeredJsonNestingBreaker remains in the API for
compatibility and is always false. Previously generated malformed models are
rejected, not repaired or replaced with synthetic weights.
The local validator checks UTF-8/JSON, duplicate fields, string metadata, nonnegative
safe-integer shapes/offsets, byte sizes, contiguous nonoverlapping tensor ranges,
and complete data coverage. It follows the structural requirements in the
official Safetensors implementation
and emits an 8-byte-aligned header. Its deliberately conservative supported dtype
subset is BOOL, U8, I8, U16, I16, F16, BF16, U32, I32, F32, U64,I64, and F64. Other dtypes are reported as unsupported; this is not a claim that
those models are invalid. Headers above 100 MB and integers beyond JavaScript's
safe range are refused rather than silently rounded. Numeric tokens anywhere in
headers must use nonnegative integer notation; negative tokens (including -0),
fractional notation, and exponent notation are unsupported,
even if its mathematical value is integral. This lexical check prevents JSON
parsing from silently rounding malformed dimensions/offsets into accepted values.
Numbers inside string metadata remain unchanged.
These are structural and byte-preservation checks, not official-loader
validation, model inference, or evidence of effectiveness against REA. The
Safetensors benchmark's functional test remains not-run.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found