bla-agents 1.1.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/blind-llm-agents/SKILL.md +20 -14
- package/DISCLAIMER.md +15 -7
- package/README.md +153 -198
- package/dist/bundler/index.d.ts +19 -2
- package/dist/bundler/index.d.ts.map +1 -1
- package/dist/bundler/index.js +47 -4
- package/dist/bundler/index.js.map +1 -1
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +123 -18
- package/dist/cli.js.map +1 -1
- package/dist/core/config.d.ts +54 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +160 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/coverage-contract.d.ts +97 -0
- package/dist/core/coverage-contract.d.ts.map +1 -0
- package/dist/core/coverage-contract.js +164 -0
- package/dist/core/coverage-contract.js.map +1 -0
- package/dist/core/debug-posture.d.ts +40 -0
- package/dist/core/debug-posture.d.ts.map +1 -0
- package/dist/core/debug-posture.js +197 -0
- package/dist/core/debug-posture.js.map +1 -0
- package/dist/core/detector.d.ts.map +1 -1
- package/dist/core/detector.js +58 -6
- package/dist/core/detector.js.map +1 -1
- package/dist/core/identifiers.d.ts +32 -0
- package/dist/core/identifiers.d.ts.map +1 -0
- package/dist/core/identifiers.js +263 -0
- package/dist/core/identifiers.js.map +1 -0
- package/dist/core/llm-directives.d.ts +12 -0
- package/dist/core/llm-directives.d.ts.map +1 -0
- package/dist/core/llm-directives.js +23 -0
- package/dist/core/llm-directives.js.map +1 -0
- package/dist/core/prng.d.ts +10 -1
- package/dist/core/prng.d.ts.map +1 -1
- package/dist/core/prng.js +27 -2
- package/dist/core/prng.js.map +1 -1
- package/dist/core/release-exposure.d.ts.map +1 -1
- package/dist/core/release-exposure.js +13 -2
- package/dist/core/release-exposure.js.map +1 -1
- package/dist/core/release-plan.d.ts +68 -0
- package/dist/core/release-plan.d.ts.map +1 -0
- package/dist/core/release-plan.js +244 -0
- package/dist/core/release-plan.js.map +1 -0
- package/dist/core/sarif.d.ts +53 -0
- package/dist/core/sarif.d.ts.map +1 -0
- package/dist/core/sarif.js +95 -0
- package/dist/core/sarif.js.map +1 -0
- package/dist/core/sqlite-runtime.d.ts +13 -0
- package/dist/core/sqlite-runtime.d.ts.map +1 -1
- package/dist/core/sqlite-runtime.js +38 -8
- package/dist/core/sqlite-runtime.js.map +1 -1
- package/dist/core/types.d.ts +7 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/engine/auditor.d.ts.map +1 -1
- package/dist/engine/auditor.js +380 -19
- package/dist/engine/auditor.js.map +1 -1
- package/dist/engine/benchmark.d.ts +1 -1
- package/dist/engine/benchmark.d.ts.map +1 -1
- package/dist/engine/benchmark.js +121 -41
- package/dist/engine/benchmark.js.map +1 -1
- package/dist/engine/defender.d.ts +1 -0
- package/dist/engine/defender.d.ts.map +1 -1
- package/dist/engine/defender.js +7 -1
- package/dist/engine/defender.js.map +1 -1
- package/dist/engine/harden.d.ts +61 -0
- package/dist/engine/harden.d.ts.map +1 -0
- package/dist/engine/harden.js +294 -0
- package/dist/engine/harden.js.map +1 -0
- package/dist/engine/protector.d.ts.map +1 -1
- package/dist/engine/protector.js +242 -26
- package/dist/engine/protector.js.map +1 -1
- package/dist/identity.d.ts +112 -2
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +112 -2
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +26 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -9
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +59 -152
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +466 -50
- package/dist/mcp/server.js.map +1 -1
- package/dist/setup/clients.d.ts +49 -1
- package/dist/setup/clients.d.ts.map +1 -1
- package/dist/setup/clients.js +1193 -20
- package/dist/setup/clients.js.map +1 -1
- package/dist/setup/doctor.d.ts +58 -14
- package/dist/setup/doctor.d.ts.map +1 -1
- package/dist/setup/doctor.js +316 -22
- package/dist/setup/doctor.js.map +1 -1
- package/dist/setup/setup.d.ts +77 -7
- package/dist/setup/setup.d.ts.map +1 -1
- package/dist/setup/setup.js +591 -62
- package/dist/setup/setup.js.map +1 -1
- package/dist/shields/chaff/chaff-generator.d.ts.map +1 -1
- package/dist/shields/chaff/chaff-generator.js +12 -3
- package/dist/shields/chaff/chaff-generator.js.map +1 -1
- package/dist/shields/deception/architecture-mirage.js +1 -1
- package/dist/shields/deception/architecture-mirage.js.map +1 -1
- package/dist/shields/deception/canary-honeypot.d.ts +33 -0
- package/dist/shields/deception/canary-honeypot.d.ts.map +1 -0
- package/dist/shields/deception/canary-honeypot.js +95 -0
- package/dist/shields/deception/canary-honeypot.js.map +1 -0
- package/dist/shields/deception/cognitive-armor-trigger.d.ts +43 -0
- package/dist/shields/deception/cognitive-armor-trigger.d.ts.map +1 -0
- package/dist/shields/deception/cognitive-armor-trigger.js +204 -0
- package/dist/shields/deception/cognitive-armor-trigger.js.map +1 -0
- package/dist/shields/deception/crash-trace-decoy.js +1 -1
- package/dist/shields/deception/crash-trace-decoy.js.map +1 -1
- package/dist/shields/deception/decompiler-illusion.js +1 -1
- package/dist/shields/deception/decompiler-illusion.js.map +1 -1
- package/dist/shields/deception/diff-noise-injector.js +1 -1
- package/dist/shields/deception/diff-noise-injector.js.map +1 -1
- package/dist/shields/deception/evidence-contract-poison.js +5 -5
- package/dist/shields/deception/evidence-contract-poison.js.map +1 -1
- package/dist/shields/deception/format-payloads.d.ts +21 -0
- package/dist/shields/deception/format-payloads.d.ts.map +1 -0
- package/dist/shields/deception/format-payloads.js +24 -0
- package/dist/shields/deception/format-payloads.js.map +1 -0
- package/dist/shields/deception/index.d.ts +10 -2
- package/dist/shields/deception/index.d.ts.map +1 -1
- package/dist/shields/deception/index.js +20 -3
- package/dist/shields/deception/index.js.map +1 -1
- package/dist/shields/deception/prompt-completion-poison.d.ts +3 -2
- package/dist/shields/deception/prompt-completion-poison.d.ts.map +1 -1
- package/dist/shields/deception/prompt-completion-poison.js +6 -3
- package/dist/shields/deception/prompt-completion-poison.js.map +1 -1
- package/dist/shields/deception/shadow-business-logic.js +4 -4
- package/dist/shields/deception/shadow-business-logic.js.map +1 -1
- package/dist/shields/deception/system-diagnostic-decoy.d.ts +36 -0
- package/dist/shields/deception/system-diagnostic-decoy.d.ts.map +1 -0
- package/dist/shields/deception/system-diagnostic-decoy.js +101 -0
- package/dist/shields/deception/system-diagnostic-decoy.js.map +1 -0
- package/dist/shields/exhaustion/asar-header-amplifier.d.ts +12 -3
- package/dist/shields/exhaustion/asar-header-amplifier.d.ts.map +1 -1
- package/dist/shields/exhaustion/asar-header-amplifier.js +30 -8
- package/dist/shields/exhaustion/asar-header-amplifier.js.map +1 -1
- package/dist/shields/exhaustion/bpe-token-amplifier.js +2 -2
- package/dist/shields/exhaustion/bpe-token-amplifier.js.map +1 -1
- package/dist/shields/exhaustion/callgraph-labyrinth.js +2 -2
- package/dist/shields/exhaustion/callgraph-labyrinth.js.map +1 -1
- package/dist/shields/exhaustion/cdp-shape-budget-breaker.js +1 -1
- package/dist/shields/exhaustion/cdp-shape-budget-breaker.js.map +1 -1
- package/dist/shields/exhaustion/frida-capture-saturation.d.ts +10 -5
- package/dist/shields/exhaustion/frida-capture-saturation.d.ts.map +1 -1
- package/dist/shields/exhaustion/frida-capture-saturation.js +21 -8
- package/dist/shields/exhaustion/frida-capture-saturation.js.map +1 -1
- package/dist/shields/exhaustion/index.d.ts +2 -2
- package/dist/shields/exhaustion/index.d.ts.map +1 -1
- package/dist/shields/exhaustion/index.js +2 -2
- package/dist/shields/exhaustion/index.js.map +1 -1
- package/dist/shields/exhaustion/obligation-flooder.d.ts +23 -6
- package/dist/shields/exhaustion/obligation-flooder.d.ts.map +1 -1
- package/dist/shields/exhaustion/obligation-flooder.js +29 -12
- package/dist/shields/exhaustion/obligation-flooder.js.map +1 -1
- package/dist/shields/exhaustion/rea-budget-matrix.d.ts +8 -2
- package/dist/shields/exhaustion/rea-budget-matrix.d.ts.map +1 -1
- package/dist/shields/exhaustion/rea-budget-matrix.js +139 -16
- package/dist/shields/exhaustion/rea-budget-matrix.js.map +1 -1
- package/dist/shields/exhaustion/regex-worker-tarpit.d.ts.map +1 -1
- package/dist/shields/exhaustion/regex-worker-tarpit.js +2 -1
- package/dist/shields/exhaustion/regex-worker-tarpit.js.map +1 -1
- package/dist/shields/exhaustion/wasm-interface-exhaustion.d.ts +7 -4
- package/dist/shields/exhaustion/wasm-interface-exhaustion.d.ts.map +1 -1
- package/dist/shields/exhaustion/wasm-interface-exhaustion.js +16 -7
- package/dist/shields/exhaustion/wasm-interface-exhaustion.js.map +1 -1
- package/dist/shields/formats/android-dex-xref.d.ts +19 -0
- package/dist/shields/formats/android-dex-xref.d.ts.map +1 -0
- package/dist/shields/formats/android-dex-xref.js +427 -0
- package/dist/shields/formats/android-dex-xref.js.map +1 -0
- package/dist/shields/formats/android-manifest.d.ts +44 -0
- package/dist/shields/formats/android-manifest.d.ts.map +1 -0
- package/dist/shields/formats/android-manifest.js +240 -0
- package/dist/shields/formats/android-manifest.js.map +1 -0
- package/dist/shields/formats/android-r8.d.ts +44 -0
- package/dist/shields/formats/android-r8.d.ts.map +1 -0
- package/dist/shields/formats/android-r8.js +246 -0
- package/dist/shields/formats/android-r8.js.map +1 -0
- package/dist/shields/formats/apple-plist.d.ts +15 -0
- package/dist/shields/formats/apple-plist.d.ts.map +1 -1
- package/dist/shields/formats/apple-plist.js +59 -1
- package/dist/shields/formats/apple-plist.js.map +1 -1
- package/dist/shields/formats/archive.d.ts +27 -6
- package/dist/shields/formats/archive.d.ts.map +1 -1
- package/dist/shields/formats/archive.js +247 -45
- package/dist/shields/formats/archive.js.map +1 -1
- package/dist/shields/formats/asar.d.ts +50 -10
- package/dist/shields/formats/asar.d.ts.map +1 -1
- package/dist/shields/formats/asar.js +265 -39
- package/dist/shields/formats/asar.js.map +1 -1
- package/dist/shields/formats/bun-standalone.d.ts +78 -0
- package/dist/shields/formats/bun-standalone.d.ts.map +1 -0
- package/dist/shields/formats/bun-standalone.js +272 -0
- package/dist/shields/formats/bun-standalone.js.map +1 -0
- package/dist/shields/formats/dotnet-managed.d.ts +9 -0
- package/dist/shields/formats/dotnet-managed.d.ts.map +1 -1
- package/dist/shields/formats/dotnet-managed.js +26 -1
- package/dist/shields/formats/dotnet-managed.js.map +1 -1
- package/dist/shields/formats/electron-fuses.d.ts +63 -8
- package/dist/shields/formats/electron-fuses.d.ts.map +1 -1
- package/dist/shields/formats/electron-fuses.js +297 -65
- package/dist/shields/formats/electron-fuses.js.map +1 -1
- package/dist/shields/formats/erlang-beam.d.ts +34 -0
- package/dist/shields/formats/erlang-beam.d.ts.map +1 -0
- package/dist/shields/formats/erlang-beam.js +319 -0
- package/dist/shields/formats/erlang-beam.js.map +1 -0
- package/dist/shields/formats/evm-bytecode.d.ts +28 -0
- package/dist/shields/formats/evm-bytecode.d.ts.map +1 -0
- package/dist/shields/formats/evm-bytecode.js +124 -0
- package/dist/shields/formats/evm-bytecode.js.map +1 -0
- package/dist/shields/formats/go-flutter-exhaustion.d.ts +55 -0
- package/dist/shields/formats/go-flutter-exhaustion.d.ts.map +1 -0
- package/dist/shields/formats/go-flutter-exhaustion.js +346 -0
- package/dist/shields/formats/go-flutter-exhaustion.js.map +1 -0
- package/dist/shields/formats/gpu-ptx.d.ts +40 -0
- package/dist/shields/formats/gpu-ptx.d.ts.map +1 -0
- package/dist/shields/formats/gpu-ptx.js +62 -0
- package/dist/shields/formats/gpu-ptx.js.map +1 -0
- package/dist/shields/formats/headers.d.ts.map +1 -1
- package/dist/shields/formats/headers.js +54 -14
- package/dist/shields/formats/headers.js.map +1 -1
- package/dist/shields/formats/jvm-bytecode.d.ts +20 -0
- package/dist/shields/formats/jvm-bytecode.d.ts.map +1 -0
- package/dist/shields/formats/jvm-bytecode.js +134 -0
- package/dist/shields/formats/jvm-bytecode.js.map +1 -0
- package/dist/shields/formats/mobile-game.d.ts +4 -0
- package/dist/shields/formats/mobile-game.d.ts.map +1 -1
- package/dist/shields/formats/mobile-game.js +16 -0
- package/dist/shields/formats/mobile-game.js.map +1 -1
- package/dist/shields/formats/model.d.ts +22 -8
- package/dist/shields/formats/model.d.ts.map +1 -1
- package/dist/shields/formats/model.js +231 -59
- package/dist/shields/formats/model.js.map +1 -1
- package/dist/shields/formats/native.d.ts +74 -11
- package/dist/shields/formats/native.d.ts.map +1 -1
- package/dist/shields/formats/native.js +557 -109
- package/dist/shields/formats/native.js.map +1 -1
- package/dist/shields/formats/pcap-capture.d.ts +27 -0
- package/dist/shields/formats/pcap-capture.d.ts.map +1 -0
- package/dist/shields/formats/pcap-capture.js +201 -0
- package/dist/shields/formats/pcap-capture.js.map +1 -0
- package/dist/shields/formats/python.d.ts +22 -1
- package/dist/shields/formats/python.d.ts.map +1 -1
- package/dist/shields/formats/python.js +568 -27
- package/dist/shields/formats/python.js.map +1 -1
- package/dist/shields/formats/sourcemap.d.ts.map +1 -1
- package/dist/shields/formats/sourcemap.js +2 -0
- package/dist/shields/formats/sourcemap.js.map +1 -1
- package/dist/shields/formats/sqlite.d.ts +87 -15
- package/dist/shields/formats/sqlite.d.ts.map +1 -1
- package/dist/shields/formats/sqlite.js +377 -42
- package/dist/shields/formats/sqlite.js.map +1 -1
- package/dist/shields/formats/wasm.d.ts +6 -0
- package/dist/shields/formats/wasm.d.ts.map +1 -1
- package/dist/shields/formats/wasm.js +118 -3
- package/dist/shields/formats/wasm.js.map +1 -1
- package/dist/shields/javascript/ast-shield.d.ts +26 -5
- package/dist/shields/javascript/ast-shield.d.ts.map +1 -1
- package/dist/shields/javascript/ast-shield.js +748 -104
- package/dist/shields/javascript/ast-shield.js.map +1 -1
- package/dist/shields/runtime/memory-diff-shield.d.ts +56 -0
- package/dist/shields/runtime/memory-diff-shield.d.ts.map +1 -0
- package/dist/shields/runtime/memory-diff-shield.js +170 -0
- package/dist/shields/runtime/memory-diff-shield.js.map +1 -0
- package/dist/shields/runtime/runtime-shield.d.ts +12 -16
- package/dist/shields/runtime/runtime-shield.d.ts.map +1 -1
- package/dist/shields/runtime/runtime-shield.js +30 -24
- package/dist/shields/runtime/runtime-shield.js.map +1 -1
- package/dist/shields/tarpit/opaque-predicates.d.ts.map +1 -1
- package/dist/shields/tarpit/opaque-predicates.js +3 -3
- package/dist/shields/tarpit/opaque-predicates.js.map +1 -1
- package/dist/shields/tarpit/tarpit-generator.d.ts +9 -4
- package/dist/shields/tarpit/tarpit-generator.d.ts.map +1 -1
- package/dist/shields/tarpit/tarpit-generator.js +30 -23
- package/dist/shields/tarpit/tarpit-generator.js.map +1 -1
- package/package.json +13 -6
|
@@ -2,10 +2,12 @@ import { parse } from "@babel/parser";
|
|
|
2
2
|
import _traverse from "@babel/traverse";
|
|
3
3
|
import _generate from "@babel/generator";
|
|
4
4
|
import * as t from "@babel/types";
|
|
5
|
+
import { generateProjectSeed } from "../../core/config.js";
|
|
5
6
|
import { SeededPrng } from "../../core/prng.js";
|
|
6
7
|
import { generateChaffPayloads } from "../chaff/chaff-generator.js";
|
|
7
8
|
import { generateJsTarpitAndBudgetBreaker } from "../tarpit/tarpit-generator.js";
|
|
8
9
|
import { generateRuntimeDeceptionSnippet } from "../runtime/runtime-shield.js";
|
|
10
|
+
import { generateShadowHeapChurnShield, } from "../runtime/memory-diff-shield.js";
|
|
9
11
|
import { generateCounterReaExhaustionSuite } from "../exhaustion/index.js";
|
|
10
12
|
import { generateCounterReaDeceptionSuite } from "../deception/index.js";
|
|
11
13
|
const traverse = typeof _traverse === "function"
|
|
@@ -14,6 +16,12 @@ const traverse = typeof _traverse === "function"
|
|
|
14
16
|
const generate = typeof _generate === "function"
|
|
15
17
|
? _generate
|
|
16
18
|
: _generate.default;
|
|
19
|
+
export class InvalidJavaScriptCarrierError extends Error {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "InvalidJavaScriptCarrierError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
17
25
|
const DECOY_ROUTES = [
|
|
18
26
|
"/internal/enclave/v2/attest-quote",
|
|
19
27
|
"/internal/enclave/v2/seal-ledger-state",
|
|
@@ -26,7 +34,156 @@ const DECOY_ROUTES = [
|
|
|
26
34
|
"/internal/sgx/quote-verification-service",
|
|
27
35
|
"/internal/nitro/enclave-cid16-dispatch",
|
|
28
36
|
];
|
|
29
|
-
const IPC_METHODS = new Set([
|
|
37
|
+
const IPC_METHODS = new Set([
|
|
38
|
+
"handle",
|
|
39
|
+
"handleOnce",
|
|
40
|
+
"on",
|
|
41
|
+
"once",
|
|
42
|
+
"invoke",
|
|
43
|
+
"send",
|
|
44
|
+
"sendSync",
|
|
45
|
+
"sendToHost",
|
|
46
|
+
]);
|
|
47
|
+
/**
|
|
48
|
+
* Electron custom URL protocol APIs inspected by REA `electronStaticAnalysisProtocol.ts` (`47fa6ab37`).
|
|
49
|
+
*/
|
|
50
|
+
const ELECTRON_PROTOCOL_SCHEME_METHODS = new Set([
|
|
51
|
+
"setAsDefaultProtocolClient",
|
|
52
|
+
"removeAsDefaultProtocolClient",
|
|
53
|
+
"isDefaultProtocolClient",
|
|
54
|
+
"handle",
|
|
55
|
+
"registerFileProtocol",
|
|
56
|
+
"registerHttpProtocol",
|
|
57
|
+
"registerStringProtocol",
|
|
58
|
+
"registerBufferProtocol",
|
|
59
|
+
"registerStreamProtocol",
|
|
60
|
+
"interceptFileProtocol",
|
|
61
|
+
"interceptHttpProtocol",
|
|
62
|
+
"interceptStringProtocol",
|
|
63
|
+
"interceptBufferProtocol",
|
|
64
|
+
"interceptStreamProtocol",
|
|
65
|
+
"unhandle",
|
|
66
|
+
"unregisterProtocol",
|
|
67
|
+
"uninterceptProtocol",
|
|
68
|
+
"isProtocolRegistered",
|
|
69
|
+
"isProtocolHandled",
|
|
70
|
+
"isProtocolIntercepted",
|
|
71
|
+
]);
|
|
72
|
+
const ELECTRON_PRIVILEGE_NAMES = new Set([
|
|
73
|
+
"allowExtensions",
|
|
74
|
+
"allowServiceWorkers",
|
|
75
|
+
"bypassCSP",
|
|
76
|
+
"codeCache",
|
|
77
|
+
"corsEnabled",
|
|
78
|
+
"secure",
|
|
79
|
+
"standard",
|
|
80
|
+
"stream",
|
|
81
|
+
"supportFetchAPI",
|
|
82
|
+
]);
|
|
83
|
+
function extractMemberChain(node) {
|
|
84
|
+
const parts = [];
|
|
85
|
+
let cur = node;
|
|
86
|
+
while (t.isMemberExpression(cur) ||
|
|
87
|
+
t.isOptionalMemberExpression(cur)) {
|
|
88
|
+
if (!cur.computed && t.isIdentifier(cur.property)) {
|
|
89
|
+
parts.unshift(cur.property.name);
|
|
90
|
+
}
|
|
91
|
+
else if (cur.computed && t.isStringLiteral(cur.property)) {
|
|
92
|
+
parts.unshift(cur.property.value);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
cur = cur.object;
|
|
98
|
+
}
|
|
99
|
+
if (t.isIdentifier(cur)) {
|
|
100
|
+
parts.unshift(cur.name);
|
|
101
|
+
}
|
|
102
|
+
return parts;
|
|
103
|
+
}
|
|
104
|
+
function getStaticPropName(prop) {
|
|
105
|
+
if (!prop.computed && t.isIdentifier(prop.key))
|
|
106
|
+
return prop.key.name;
|
|
107
|
+
if (t.isStringLiteral(prop.key))
|
|
108
|
+
return prop.key.value;
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
function isInsideTsConstAssertion(path) {
|
|
112
|
+
return Boolean(path.findParent((p) => {
|
|
113
|
+
if (p.isTSAsExpression?.() || p.isTSTypeAssertion?.()) {
|
|
114
|
+
const ann = p.node.typeAnnotation;
|
|
115
|
+
return (t.isTSTypeReference(ann) &&
|
|
116
|
+
t.isIdentifier(ann.typeName) &&
|
|
117
|
+
ann.typeName.name === "const");
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
export function inferJsLoaderFromPath(filename) {
|
|
123
|
+
if (!filename)
|
|
124
|
+
return "js";
|
|
125
|
+
const clean = filename.split(/[?#]/, 1)[0].toLowerCase();
|
|
126
|
+
if (clean.endsWith(".tsx"))
|
|
127
|
+
return "tsx";
|
|
128
|
+
if (clean.endsWith(".jsx"))
|
|
129
|
+
return "jsx";
|
|
130
|
+
if (clean.endsWith(".ts") ||
|
|
131
|
+
clean.endsWith(".mts") ||
|
|
132
|
+
clean.endsWith(".cts")) {
|
|
133
|
+
return "ts";
|
|
134
|
+
}
|
|
135
|
+
return "js";
|
|
136
|
+
}
|
|
137
|
+
export function inferJsCarrierFromPath(filename) {
|
|
138
|
+
if (!filename)
|
|
139
|
+
return "auto";
|
|
140
|
+
const clean = filename.split(/[?#]/, 1)[0].toLowerCase();
|
|
141
|
+
if (clean.endsWith(".mjs") || clean.endsWith(".mts"))
|
|
142
|
+
return "module";
|
|
143
|
+
if (clean.endsWith(".cjs") || clean.endsWith(".cts"))
|
|
144
|
+
return "commonjs";
|
|
145
|
+
return "auto";
|
|
146
|
+
}
|
|
147
|
+
export function collectEsmExportedSymbols(program) {
|
|
148
|
+
const exported = [];
|
|
149
|
+
for (const stmt of program.body) {
|
|
150
|
+
if (t.isExportDefaultDeclaration(stmt)) {
|
|
151
|
+
exported.push("default");
|
|
152
|
+
}
|
|
153
|
+
else if (t.isExportAllDeclaration(stmt)) {
|
|
154
|
+
exported.push("*");
|
|
155
|
+
}
|
|
156
|
+
else if (t.isExportNamedDeclaration(stmt)) {
|
|
157
|
+
for (const spec of stmt.specifiers) {
|
|
158
|
+
if (t.isExportSpecifier(spec)) {
|
|
159
|
+
exported.push(t.isIdentifier(spec.exported)
|
|
160
|
+
? spec.exported.name
|
|
161
|
+
: spec.exported.value);
|
|
162
|
+
}
|
|
163
|
+
else if (t.isExportNamespaceSpecifier(spec)) {
|
|
164
|
+
exported.push(spec.exported.name);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const decl = stmt.declaration;
|
|
168
|
+
if (decl) {
|
|
169
|
+
if ((t.isFunctionDeclaration(decl) || t.isClassDeclaration(decl)) &&
|
|
170
|
+
decl.id) {
|
|
171
|
+
exported.push(decl.id.name);
|
|
172
|
+
}
|
|
173
|
+
else if (t.isVariableDeclaration(decl)) {
|
|
174
|
+
const ids = t.getOuterBindingIdentifiers(decl);
|
|
175
|
+
exported.push(...Object.keys(ids));
|
|
176
|
+
}
|
|
177
|
+
else if ("id" in decl &&
|
|
178
|
+
decl.id &&
|
|
179
|
+
t.isIdentifier(decl.id)) {
|
|
180
|
+
exported.push(decl.id.name);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return exported;
|
|
186
|
+
}
|
|
30
187
|
/**
|
|
31
188
|
* Splits a string literal into >= 9 conditional chunks `(cond ? realChunk : decoyChunk)`
|
|
32
189
|
* joined with `+`.
|
|
@@ -37,7 +194,7 @@ const IPC_METHODS = new Set(["handle", "handleOnce", "on", "once", "invoke", "se
|
|
|
37
194
|
* the cartesian product of candidates is $2^9 = 512 > 256$ (or $2^{10} = 1024 > 256$),
|
|
38
195
|
* which immediately forces REA to bail out with `semanticResourceLimitUnknown("primitive-candidates")`!
|
|
39
196
|
*
|
|
40
|
-
* At runtime, each condition uses `(Math.imul(
|
|
197
|
+
* At runtime, each condition uses `(Math.imul(seed | k, (seed | k) + 1) & 1) === 0`
|
|
41
198
|
* (which is ALWAYS true because the product of two consecutive integers is always even!),
|
|
42
199
|
* so the runtime expression evaluates to the EXACT original string in O(1)!
|
|
43
200
|
*/
|
|
@@ -62,20 +219,25 @@ function buildCombinatorialStringAst(value, prng, seedIdentifierName) {
|
|
|
62
219
|
}
|
|
63
220
|
}
|
|
64
221
|
const terms = chunks.map((realChunk, idx) => {
|
|
65
|
-
const
|
|
222
|
+
const useOddSq = idx % 3 === 1;
|
|
223
|
+
const k = useOddSq ? prng.nextInt(1, 31) * 4 : (prng.nextInt(3, 125) | 1);
|
|
66
224
|
const decoyChunk = realChunk.length > 0 ? prng.hex(realChunk.length) : prng.hex(2);
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
const
|
|
225
|
+
const seededOr = t.binaryExpression(useOddSq ? "^" : "|", t.identifier(seedIdentifierName), t.numericLiteral(k));
|
|
226
|
+
const rhs = useOddSq
|
|
227
|
+
? t.cloneNode(seededOr)
|
|
228
|
+
: t.binaryExpression("+", t.cloneNode(seededOr), t.numericLiteral(1));
|
|
229
|
+
const imulCall = t.callExpression(t.memberExpression(t.identifier("Math"), t.identifier("imul")), [seededOr, rhs]);
|
|
230
|
+
const mask = useOddSq ? 7 : 1;
|
|
231
|
+
const trueVal = useOddSq ? 1 : 0;
|
|
232
|
+
const falseVal = useOddSq ? 0 : 1;
|
|
233
|
+
const bitAnd = t.binaryExpression("&", imulCall, t.numericLiteral(mask));
|
|
234
|
+
const cond = t.binaryExpression("===", bitAnd, t.numericLiteral(trueVal));
|
|
73
235
|
// Alternate polarity on odd indices so static heuristics see both true/false arms used
|
|
74
236
|
if (idx % 2 === 0) {
|
|
75
237
|
return t.conditionalExpression(cond, t.stringLiteral(realChunk), t.stringLiteral(decoyChunk));
|
|
76
238
|
}
|
|
77
239
|
else {
|
|
78
|
-
const invertedCond = t.binaryExpression("===", bitAnd, t.numericLiteral(
|
|
240
|
+
const invertedCond = t.binaryExpression("===", bitAnd, t.numericLiteral(falseVal));
|
|
79
241
|
return t.conditionalExpression(invertedCond, t.stringLiteral(decoyChunk), t.stringLiteral(realChunk));
|
|
80
242
|
}
|
|
81
243
|
});
|
|
@@ -86,123 +248,517 @@ function buildCombinatorialStringAst(value, prng, seedIdentifierName) {
|
|
|
86
248
|
return expr;
|
|
87
249
|
}
|
|
88
250
|
function buildOpaqueFalseAst(prng, seedIdentifierName) {
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
|
|
251
|
+
const k4 = prng.nextInt(1, 31) * 4;
|
|
252
|
+
const seededXor = t.binaryExpression("^", t.identifier(seedIdentifierName), t.numericLiteral(k4));
|
|
253
|
+
const imulCall = t.callExpression(t.memberExpression(t.identifier("Math"), t.identifier("imul")), [seededXor, t.cloneNode(seededXor)]);
|
|
254
|
+
const bitAnd = t.binaryExpression("&", imulCall, t.numericLiteral(7));
|
|
255
|
+
return t.binaryExpression("===", bitAnd, t.numericLiteral(0));
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Opaque TRUE entangled with the runtime Cognitive-Armor digest bit:
|
|
259
|
+
* When untampered, `seedIdentifierName` is odd, so `u = seed ^ (4*k)` is odd
|
|
260
|
+
* and `(Math.imul(u, u) & 7) === 1`. If the Cognitive-Armor corpus is stripped
|
|
261
|
+
* or redacted, `seedIdentifierName` becomes a multiple of 4 and this flips to FALSE.
|
|
262
|
+
*/
|
|
263
|
+
function buildOpaqueTrueAst(prng, seedIdentifierName) {
|
|
264
|
+
const k4 = prng.nextInt(1, 31) * 4;
|
|
265
|
+
const seededXor = t.binaryExpression("^", t.identifier(seedIdentifierName), t.numericLiteral(k4));
|
|
266
|
+
const imulCall = t.callExpression(t.memberExpression(t.identifier("Math"), t.identifier("imul")), [seededXor, t.cloneNode(seededXor)]);
|
|
267
|
+
const bitAnd = t.binaryExpression("&", imulCall, t.numericLiteral(7));
|
|
94
268
|
return t.binaryExpression("===", bitAnd, t.numericLiteral(1));
|
|
95
269
|
}
|
|
270
|
+
const RENAME_RESERVED = new Set([
|
|
271
|
+
"exports", "module", "require", "arguments", "undefined", "NaN", "Infinity",
|
|
272
|
+
"globalThis", "global", "window", "self", "console", "Math", "Object", "Array",
|
|
273
|
+
"Promise", "Buffer", "process", "__dirname", "__filename", "JSON", "Date",
|
|
274
|
+
"Error", "TypeError", "RangeError", "Map", "Set", "WeakMap", "WeakSet",
|
|
275
|
+
"Symbol", "Proxy", "Reflect", "parseInt", "parseFloat", "isNaN", "isFinite",
|
|
276
|
+
"encodeURIComponent", "decodeURIComponent", "setTimeout", "clearTimeout",
|
|
277
|
+
"setInterval", "clearInterval", "fetch", "URL", "URLSearchParams",
|
|
278
|
+
"TextEncoder", "TextDecoder", "Uint8Array", "DataView", "ArrayBuffer",
|
|
279
|
+
"SharedArrayBuffer", "Atomics", "WebAssembly", "Intl", "BigInt",
|
|
280
|
+
]);
|
|
281
|
+
function buildParserPlugins(loader, hasExplicitLoaderOrFilename) {
|
|
282
|
+
const plugins = [
|
|
283
|
+
"decorators-legacy",
|
|
284
|
+
"importAttributes",
|
|
285
|
+
"dynamicImport",
|
|
286
|
+
"classProperties",
|
|
287
|
+
"topLevelAwait",
|
|
288
|
+
];
|
|
289
|
+
if (!hasExplicitLoaderOrFilename) {
|
|
290
|
+
plugins.unshift("typescript", "jsx");
|
|
291
|
+
return plugins;
|
|
292
|
+
}
|
|
293
|
+
if (loader === "ts") {
|
|
294
|
+
plugins.unshift("typescript");
|
|
295
|
+
}
|
|
296
|
+
else if (loader === "tsx") {
|
|
297
|
+
plugins.unshift("typescript", "jsx");
|
|
298
|
+
}
|
|
299
|
+
else if (loader === "jsx") {
|
|
300
|
+
plugins.unshift("jsx");
|
|
301
|
+
}
|
|
302
|
+
return plugins;
|
|
303
|
+
}
|
|
96
304
|
export function transformJavaScriptWithBlaShield(source, options = {}) {
|
|
97
305
|
const intensity = options.intensity ?? "balanced";
|
|
98
|
-
const prng = new SeededPrng(options.seed ??
|
|
306
|
+
const prng = new SeededPrng(options.seed ?? generateProjectSeed());
|
|
99
307
|
const chaffPayloads = generateChaffPayloads(prng, intensity);
|
|
100
308
|
const tarpit = generateJsTarpitAndBudgetBreaker(prng, intensity, chaffPayloads);
|
|
101
309
|
const runtimeShield = generateRuntimeDeceptionSnippet(prng, intensity, chaffPayloads);
|
|
102
310
|
const exhaustionSuite = generateCounterReaExhaustionSuite(prng, intensity);
|
|
103
311
|
const deceptionSuite = generateCounterReaDeceptionSuite(prng, intensity);
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
312
|
+
const memoryDiffShield = generateShadowHeapChurnShield(prng, intensity);
|
|
313
|
+
const hasExplicitLoaderOrFilename = options.loader !== undefined || options.filename !== undefined;
|
|
314
|
+
const loader = options.loader ?? inferJsLoaderFromPath(options.filename);
|
|
315
|
+
const requestedCarrier = options.sourceType ?? inferJsCarrierFromPath(options.filename);
|
|
316
|
+
const parserSourceType = requestedCarrier === "script" || requestedCarrier === "commonjs"
|
|
317
|
+
? "script"
|
|
318
|
+
: requestedCarrier === "module"
|
|
319
|
+
? "module"
|
|
320
|
+
: "unambiguous";
|
|
321
|
+
let ast;
|
|
322
|
+
try {
|
|
323
|
+
ast = parse(source, {
|
|
324
|
+
sourceType: parserSourceType,
|
|
325
|
+
plugins: buildParserPlugins(loader, hasExplicitLoaderOrFilename),
|
|
326
|
+
errorRecovery: false,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
throw new InvalidJavaScriptCarrierError(`Failed to parse JavaScript/TypeScript input (carrier=${requestedCarrier}, loader=${loader}): ${err instanceof Error ? err.message : String(err)}`);
|
|
331
|
+
}
|
|
332
|
+
const hasEsmNodes = ast.program.body.some((stmt) => t.isImportDeclaration(stmt) ||
|
|
333
|
+
t.isExportNamedDeclaration(stmt) ||
|
|
334
|
+
t.isExportDefaultDeclaration(stmt) ||
|
|
335
|
+
t.isExportAllDeclaration(stmt));
|
|
336
|
+
if ((requestedCarrier === "script" || requestedCarrier === "commonjs") &&
|
|
337
|
+
hasEsmNodes) {
|
|
338
|
+
throw new InvalidJavaScriptCarrierError(`ESM import/export syntax is not allowed in '${requestedCarrier}' carrier`);
|
|
339
|
+
}
|
|
340
|
+
const exportedSymbolsBefore = collectEsmExportedSymbols(ast.program);
|
|
341
|
+
const seedVarName = prng.identifier({ style: "camel", hint: "runtimeSeed", entropy: 4 });
|
|
118
342
|
const observedIpcChannels = new Set();
|
|
343
|
+
const observedProtocolSchemes = new Set();
|
|
344
|
+
const electronEsmBindings = new Map();
|
|
345
|
+
let hasProvenElectronRequire = false;
|
|
346
|
+
let electronProtocolsProtected = 0;
|
|
119
347
|
let primitiveCandidateBranchesCreated = 512; // From tarpit budgetFn
|
|
120
348
|
let fakeCrossReferencesCreated = tarpit.crossReferenceEdges;
|
|
121
349
|
let ipcAmbiguitySitesInjected = 0;
|
|
350
|
+
let usesCjsAst = false;
|
|
122
351
|
// Track functions to weave tarpit calls into
|
|
123
352
|
const functionBodies = [];
|
|
353
|
+
const handleCallOrOptionalCall = (path) => {
|
|
354
|
+
const callee = path.node.callee;
|
|
355
|
+
if (t.isIdentifier(callee) && callee.name === "require") {
|
|
356
|
+
usesCjsAst = true;
|
|
357
|
+
const reqArg = path.node.arguments[0];
|
|
358
|
+
if (t.isStringLiteral(reqArg) && reqArg.value === "electron") {
|
|
359
|
+
hasProvenElectronRequire = true;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
const inTsConst = (loader === "ts" || loader === "tsx") && isInsideTsConstAssertion(path);
|
|
363
|
+
const chain = extractMemberChain(callee);
|
|
364
|
+
const methodName = chain.length >= 2 ? chain[chain.length - 1] : "";
|
|
365
|
+
const objName = chain.length >= 2 ? chain[chain.length - 2] : "";
|
|
366
|
+
const rootName = chain.length >= 1 ? chain[0] : "";
|
|
367
|
+
// 1. Check Electron IPC, contextBridge, and custom URL protocol calls
|
|
368
|
+
if (methodName && !inTsConst) {
|
|
369
|
+
// Electron custom URL protocol registrations (REA 47fa6ab37 `electronStaticAnalysisProtocol.ts`)
|
|
370
|
+
const isProtocolReceiver = objName === "protocol" ||
|
|
371
|
+
objName === "app" ||
|
|
372
|
+
rootName === "protocol" ||
|
|
373
|
+
rootName === "app" ||
|
|
374
|
+
chain.includes("protocol") ||
|
|
375
|
+
chain.includes("defaultSession");
|
|
376
|
+
if (methodName === "registerSchemesAsPrivileged" &&
|
|
377
|
+
isProtocolReceiver) {
|
|
378
|
+
const listArg = path.node.arguments[0];
|
|
379
|
+
const unwrappedList = t.isTSAsExpression(listArg)
|
|
380
|
+
? listArg.expression
|
|
381
|
+
: listArg;
|
|
382
|
+
if (t.isArrayExpression(unwrappedList)) {
|
|
383
|
+
for (const elem of unwrappedList.elements) {
|
|
384
|
+
const obj = t.isTSAsExpression(elem) ? elem.expression : elem;
|
|
385
|
+
if (!t.isObjectExpression(obj))
|
|
386
|
+
continue;
|
|
387
|
+
for (const prop of obj.properties) {
|
|
388
|
+
if (!t.isObjectProperty(prop))
|
|
389
|
+
continue;
|
|
390
|
+
const pName = getStaticPropName(prop);
|
|
391
|
+
if (pName === "scheme" &&
|
|
392
|
+
t.isStringLiteral(prop.value) &&
|
|
393
|
+
prop.value.value.length > 0) {
|
|
394
|
+
observedProtocolSchemes.add(prop.value.value);
|
|
395
|
+
prop.value = buildCombinatorialStringAst(prop.value.value, prng, seedVarName);
|
|
396
|
+
electronProtocolsProtected += 1;
|
|
397
|
+
primitiveCandidateBranchesCreated += 512;
|
|
398
|
+
}
|
|
399
|
+
else if (pName === "privileges" &&
|
|
400
|
+
t.isObjectExpression(prop.value)) {
|
|
401
|
+
for (const privProp of prop.value.properties) {
|
|
402
|
+
if (!t.isObjectProperty(privProp))
|
|
403
|
+
continue;
|
|
404
|
+
const privName = getStaticPropName(privProp);
|
|
405
|
+
if (privName &&
|
|
406
|
+
ELECTRON_PRIVILEGE_NAMES.has(privName) &&
|
|
407
|
+
t.isBooleanLiteral(privProp.value)) {
|
|
408
|
+
privProp.value = privProp.value.value
|
|
409
|
+
? buildOpaqueTrueAst(prng, seedVarName)
|
|
410
|
+
: buildOpaqueFalseAst(prng, seedVarName);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else if (ELECTRON_PROTOCOL_SCHEME_METHODS.has(methodName) &&
|
|
419
|
+
isProtocolReceiver &&
|
|
420
|
+
!(methodName === "handle" && objName.toLowerCase().includes("ipc"))) {
|
|
421
|
+
const firstArg = path.node.arguments[0];
|
|
422
|
+
if (t.isStringLiteral(firstArg) && firstArg.value.length > 0) {
|
|
423
|
+
observedProtocolSchemes.add(firstArg.value);
|
|
424
|
+
path.node.arguments[0] = buildCombinatorialStringAst(firstArg.value, prng, seedVarName);
|
|
425
|
+
electronProtocolsProtected += 1;
|
|
426
|
+
primitiveCandidateBranchesCreated += 512;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
// Electron IPC calls: ipcMain.handle("channel", ...), ipcRenderer.invoke("channel", ...)
|
|
430
|
+
if (IPC_METHODS.has(methodName) &&
|
|
431
|
+
(objName.toLowerCase().includes("ipc") ||
|
|
432
|
+
(methodName === "handle" && !isProtocolReceiver) ||
|
|
433
|
+
methodName === "invoke" ||
|
|
434
|
+
methodName === "sendToHost")) {
|
|
435
|
+
const firstArg = path.node.arguments[0];
|
|
436
|
+
if (t.isStringLiteral(firstArg) && firstArg.value.length > 0) {
|
|
437
|
+
observedIpcChannels.add(firstArg.value);
|
|
438
|
+
path.node.arguments[0] = buildCombinatorialStringAst(firstArg.value, prng, seedVarName);
|
|
439
|
+
primitiveCandidateBranchesCreated += 512;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
// Electron contextBridge.exposeInMainWorld("apiKey", apiObject)
|
|
443
|
+
if (methodName === "exposeInMainWorld") {
|
|
444
|
+
const firstArg = path.node.arguments[0];
|
|
445
|
+
if (t.isStringLiteral(firstArg) && firstArg.value.length > 0) {
|
|
446
|
+
observedIpcChannels.add(`bridge:${firstArg.value}`);
|
|
447
|
+
path.node.arguments[0] = buildCombinatorialStringAst(firstArg.value, prng, seedVarName);
|
|
448
|
+
primitiveCandidateBranchesCreated += 512;
|
|
449
|
+
}
|
|
450
|
+
// Wrap literal API object in an O(1) opaque ternary so runtime passes the exact
|
|
451
|
+
// same object reference while REA's `collectContextBridgeMembers` sees a dynamic node.
|
|
452
|
+
const secondArg = path.node.arguments[1];
|
|
453
|
+
if (t.isObjectExpression(secondArg)) {
|
|
454
|
+
path.node.arguments[1] = t.conditionalExpression(buildOpaqueTrueAst(prng, seedVarName), secondArg, t.objectExpression([]));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// 2. Check fetch / route / SQL / crypto calls with string literal first arg
|
|
459
|
+
const firstArg = path.node.arguments[0];
|
|
460
|
+
if (!inTsConst &&
|
|
461
|
+
t.isStringLiteral(firstArg) &&
|
|
462
|
+
firstArg.value.length >= 4 &&
|
|
463
|
+
!t.isImport(callee) &&
|
|
464
|
+
!(t.isIdentifier(callee) && callee.name === "require")) {
|
|
465
|
+
const val = firstArg.value;
|
|
466
|
+
const looksSensitiveOrRoute = val.startsWith("/") ||
|
|
467
|
+
val.startsWith("http") ||
|
|
468
|
+
val.includes("SELECT ") ||
|
|
469
|
+
val.includes("INSERT ") ||
|
|
470
|
+
val.includes("CREATE TABLE") ||
|
|
471
|
+
val.includes("license") ||
|
|
472
|
+
val.includes("secret") ||
|
|
473
|
+
val.includes("token") ||
|
|
474
|
+
val.includes("key") ||
|
|
475
|
+
val.includes("pan") ||
|
|
476
|
+
val.includes("clipboard") ||
|
|
477
|
+
val.endsWith(".wasm");
|
|
478
|
+
if (looksSensitiveOrRoute) {
|
|
479
|
+
path.node.arguments[0] = buildCombinatorialStringAst(val, prng, seedVarName);
|
|
480
|
+
primitiveCandidateBranchesCreated += 512;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
};
|
|
124
484
|
traverse(ast, {
|
|
485
|
+
ImportDeclaration(path) {
|
|
486
|
+
if (path.node.source.value === "electron" &&
|
|
487
|
+
(!path.node.importKind || path.node.importKind === "value")) {
|
|
488
|
+
for (const spec of path.node.specifiers) {
|
|
489
|
+
if (t.isImportSpecifier(spec)) {
|
|
490
|
+
if (spec.importKind === "type")
|
|
491
|
+
continue;
|
|
492
|
+
const imported = t.isIdentifier(spec.imported)
|
|
493
|
+
? spec.imported.name
|
|
494
|
+
: spec.imported.value;
|
|
495
|
+
electronEsmBindings.set(imported, spec.local.name);
|
|
496
|
+
}
|
|
497
|
+
else if (t.isImportDefaultSpecifier(spec) ||
|
|
498
|
+
t.isImportNamespaceSpecifier(spec)) {
|
|
499
|
+
electronEsmBindings.set("*", spec.local.name);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
},
|
|
125
504
|
Function(path) {
|
|
126
505
|
if (t.isBlockStatement(path.node.body)) {
|
|
127
506
|
functionBodies.push(path.node.body);
|
|
128
507
|
}
|
|
129
508
|
},
|
|
509
|
+
MemberExpression(path) {
|
|
510
|
+
const { object, property } = path.node;
|
|
511
|
+
if (t.isIdentifier(object) &&
|
|
512
|
+
object.name === "module" &&
|
|
513
|
+
t.isIdentifier(property) &&
|
|
514
|
+
property.name === "exports") {
|
|
515
|
+
usesCjsAst = true;
|
|
516
|
+
}
|
|
517
|
+
else if (t.isIdentifier(object) && object.name === "exports") {
|
|
518
|
+
usesCjsAst = true;
|
|
519
|
+
}
|
|
520
|
+
},
|
|
130
521
|
CallExpression(path) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
522
|
+
handleCallOrOptionalCall(path);
|
|
523
|
+
},
|
|
524
|
+
OptionalCallExpression(path) {
|
|
525
|
+
handleCallOrOptionalCall(path);
|
|
526
|
+
},
|
|
527
|
+
ObjectProperty(path) {
|
|
528
|
+
if ((loader === "ts" || loader === "tsx") &&
|
|
529
|
+
isInsideTsConstAssertion(path)) {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
const propName = getStaticPropName(path.node);
|
|
533
|
+
if (propName === "webPreferences" &&
|
|
534
|
+
t.isObjectExpression(path.node.value)) {
|
|
535
|
+
for (const pref of path.node.value.properties) {
|
|
536
|
+
if (!t.isObjectProperty(pref))
|
|
537
|
+
continue;
|
|
538
|
+
const prefKey = getStaticPropName(pref);
|
|
539
|
+
if (t.isBooleanLiteral(pref.value)) {
|
|
540
|
+
pref.value = pref.value.value
|
|
541
|
+
? buildOpaqueTrueAst(prng, seedVarName)
|
|
542
|
+
: buildOpaqueFalseAst(prng, seedVarName);
|
|
147
543
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
544
|
+
else if (prefKey === "preload") {
|
|
545
|
+
if (t.isStringLiteral(pref.value) &&
|
|
546
|
+
pref.value.value.length > 0) {
|
|
547
|
+
pref.value = buildCombinatorialStringAst(pref.value.value, prng, seedVarName);
|
|
548
|
+
primitiveCandidateBranchesCreated += 512;
|
|
549
|
+
}
|
|
550
|
+
else if (t.isCallExpression(pref.value)) {
|
|
551
|
+
pref.value.arguments = pref.value.arguments.map((arg) => t.isStringLiteral(arg) && arg.value.length > 0
|
|
552
|
+
? buildCombinatorialStringAst(arg.value, prng, seedVarName)
|
|
553
|
+
: arg);
|
|
554
|
+
primitiveCandidateBranchesCreated += 512;
|
|
555
|
+
}
|
|
156
556
|
}
|
|
157
557
|
}
|
|
158
558
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
559
|
+
},
|
|
560
|
+
StringLiteral(path) {
|
|
561
|
+
if (intensity !== "bankrupt" && intensity !== "maximum") {
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
if ((loader === "ts" || loader === "tsx") &&
|
|
565
|
+
isInsideTsConstAssertion(path)) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
const val = path.node.value;
|
|
569
|
+
if (val.length < 3 || val.length > 256) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
const parent = path.parent;
|
|
573
|
+
if (t.isImportDeclaration(parent) ||
|
|
574
|
+
t.isExportNamedDeclaration(parent) ||
|
|
575
|
+
t.isExportAllDeclaration(parent) ||
|
|
576
|
+
t.isTSLiteralType(parent) ||
|
|
577
|
+
t.isTSImportType(parent) ||
|
|
578
|
+
t.isTSExternalModuleReference(parent) ||
|
|
579
|
+
t.isTSModuleDeclaration(parent) ||
|
|
580
|
+
t.isImportAttribute(parent) ||
|
|
581
|
+
(t.isExpressionStatement(parent) && val.startsWith("use "))) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
if (path.findParent((p) => p.isTSType() ||
|
|
585
|
+
p.isTSModuleDeclaration() ||
|
|
586
|
+
p.isTSExternalModuleReference() ||
|
|
587
|
+
p.isImportAttribute())) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
if (t.isObjectProperty(parent) &&
|
|
591
|
+
parent.key === path.node &&
|
|
592
|
+
!parent.computed) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
if (t.isClassMethod(parent) ||
|
|
596
|
+
t.isObjectMethod(parent) ||
|
|
597
|
+
t.isClassProperty(parent)) {
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (t.isCallExpression(parent) &&
|
|
601
|
+
t.isIdentifier(parent.callee) &&
|
|
602
|
+
parent.callee.name === "require") {
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
path.replaceWith(buildCombinatorialStringAst(val, prng, seedVarName));
|
|
606
|
+
path.skip();
|
|
607
|
+
primitiveCandidateBranchesCreated += 256;
|
|
608
|
+
},
|
|
609
|
+
});
|
|
610
|
+
const effectiveCarrier = requestedCarrier === "module" || hasEsmNodes
|
|
611
|
+
? "module"
|
|
612
|
+
: requestedCarrier === "commonjs" || usesCjsAst
|
|
613
|
+
? "commonjs"
|
|
614
|
+
: "script";
|
|
615
|
+
// 2b. Rename non-exported local bindings (including function parameters and private helpers)
|
|
616
|
+
// so original identifiers are not left pristine
|
|
617
|
+
const exportedNameSet = new Set(exportedSymbolsBefore);
|
|
618
|
+
const generatedNames = new Set();
|
|
619
|
+
traverse(ast, {
|
|
620
|
+
Scope(path) {
|
|
621
|
+
for (const [name, binding] of Object.entries(path.scope.bindings)) {
|
|
622
|
+
if (RENAME_RESERVED.has(name))
|
|
623
|
+
continue;
|
|
624
|
+
if (exportedNameSet.has(name))
|
|
625
|
+
continue;
|
|
626
|
+
if (binding.kind === "module")
|
|
627
|
+
continue;
|
|
628
|
+
if (name.startsWith("_") && name.length <= 2)
|
|
629
|
+
continue;
|
|
630
|
+
if (/^(_interlockSafetyCorpus_|_deriveContainmentCorpusDigest_|_DISTRIBUTED_ASL3_|_SELF_SEAL_TARGET)/.test(name)) {
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
if (generatedNames.has(name))
|
|
634
|
+
continue;
|
|
635
|
+
if (binding.kind !== "let" &&
|
|
636
|
+
binding.kind !== "const" &&
|
|
637
|
+
binding.kind !== "var" &&
|
|
638
|
+
binding.kind !== "hoisted" &&
|
|
639
|
+
binding.kind !== "local" &&
|
|
640
|
+
binding.kind !== "param") {
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
643
|
+
if (binding.kind === "param" &&
|
|
644
|
+
(binding.path.isTSParameterProperty() ||
|
|
645
|
+
binding.path.parentPath?.isTSParameterProperty())) {
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
// In classic "script" carrier, top-level hoisted functions may be invoked globally;
|
|
649
|
+
// in "module" / "commonjs" carriers, only preserve pre-tagged decoy identifiers.
|
|
650
|
+
if (path.scope.path.isProgram() &&
|
|
651
|
+
binding.kind === "hoisted" &&
|
|
652
|
+
(effectiveCarrier === "script" || /_[0-9a-f]{3,4}$/i.test(name))) {
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
const newName = prng.identifier({
|
|
656
|
+
style: name.startsWith("_") ? "privateCamel" : "camel",
|
|
657
|
+
hint: intensity === "bankrupt" || intensity === "maximum"
|
|
658
|
+
? undefined
|
|
659
|
+
: name.replace(/^_+/, "").slice(0, 16) || "local",
|
|
660
|
+
entropy: 3,
|
|
661
|
+
});
|
|
662
|
+
if (newName === name ||
|
|
663
|
+
RENAME_RESERVED.has(newName) ||
|
|
664
|
+
exportedNameSet.has(newName) ||
|
|
665
|
+
generatedNames.has(newName)) {
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
try {
|
|
669
|
+
path.scope.rename(name, newName);
|
|
670
|
+
generatedNames.add(newName);
|
|
671
|
+
}
|
|
672
|
+
catch {
|
|
673
|
+
// Binding may be constant-violating or conflict; skip safely
|
|
181
674
|
}
|
|
182
675
|
}
|
|
183
676
|
},
|
|
184
677
|
});
|
|
185
|
-
//
|
|
678
|
+
// 2c. Transform / relocate comments so original Chinese/doc comments are not pristine
|
|
679
|
+
if (ast.comments) {
|
|
680
|
+
for (const c of ast.comments) {
|
|
681
|
+
if (/sourceMappingURL=/i.test(c.value))
|
|
682
|
+
continue;
|
|
683
|
+
// Relocate + scramble: destroy verbatim original comments (incl. Chinese docs)
|
|
684
|
+
// while preserving that a comment existed (so AST shape stays similar).
|
|
685
|
+
const theme = prng.pick([
|
|
686
|
+
"reconcile session epoch",
|
|
687
|
+
"derive ledger digest",
|
|
688
|
+
"normalize envelope frame",
|
|
689
|
+
"hydrate runtime cache",
|
|
690
|
+
"project quota policy",
|
|
691
|
+
]);
|
|
692
|
+
const scrambled = prng.hex(6);
|
|
693
|
+
c.value = c.type === "CommentBlock"
|
|
694
|
+
? ` ${theme} (${scrambled}) `
|
|
695
|
+
: ` ${theme} (${scrambled})`;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
// 2d. Entangle REAL statements with opaque-TRUE guards so blind deletion breaks behavior
|
|
699
|
+
traverse(ast, {
|
|
700
|
+
BlockStatement(path) {
|
|
701
|
+
// Skip injected blocks that don't exist yet; only original function bodies
|
|
702
|
+
if (!functionBodies.includes(path.node))
|
|
703
|
+
return;
|
|
704
|
+
const stmts = path.node.body;
|
|
705
|
+
if (stmts.length === 0)
|
|
706
|
+
return;
|
|
707
|
+
const next = [];
|
|
708
|
+
for (let i = 0; i < stmts.length; i++) {
|
|
709
|
+
const stmt = stmts[i];
|
|
710
|
+
// Don't wrap returns/throws/declarations/directives — wrap expression & if stmts
|
|
711
|
+
// NEVER wrap VariableDeclaration / FunctionDeclaration / Return / Throw —
|
|
712
|
+
// that would change block scoping and break the program under our own shield.
|
|
713
|
+
const wrappable = t.isExpressionStatement(stmt) ||
|
|
714
|
+
(t.isIfStatement(stmt) && !t.isVariableDeclaration(stmt.consequent));
|
|
715
|
+
if (wrappable && i % 2 === 0) {
|
|
716
|
+
next.push(t.ifStatement(buildOpaqueTrueAst(prng, seedVarName), t.blockStatement([stmt])));
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
next.push(stmt);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
path.node.body = next;
|
|
723
|
+
},
|
|
724
|
+
});
|
|
725
|
+
// 3. Weave synchronized shadow-heap churn + unreachable tarpit calls into real function bodies
|
|
186
726
|
for (const body of functionBodies) {
|
|
727
|
+
const stepCallStmt = t.expressionStatement(t.callExpression(t.identifier(memoryDiffShield.stepperFunctionName), [
|
|
728
|
+
t.numericLiteral(prng.nextInt(1, 4095)),
|
|
729
|
+
]));
|
|
187
730
|
if (tarpit.decoyFunctionNames.length >= 2) {
|
|
188
731
|
const d1 = prng.pick(tarpit.decoyFunctionNames);
|
|
189
732
|
const d2 = prng.pick(tarpit.decoyFunctionNames);
|
|
190
733
|
const guard = t.ifStatement(buildOpaqueFalseAst(prng, seedVarName), t.blockStatement([
|
|
191
|
-
t.expressionStatement(t.binaryExpression("^", t.callExpression(t.identifier(d1), [
|
|
734
|
+
t.expressionStatement(t.binaryExpression("^", t.callExpression(t.identifier(d1), [
|
|
735
|
+
t.numericLiteral(prng.nextInt(1, 255)),
|
|
736
|
+
t.numericLiteral(2),
|
|
737
|
+
]), t.callExpression(t.identifier(d2), [
|
|
738
|
+
t.numericLiteral(prng.nextInt(1, 255)),
|
|
739
|
+
t.numericLiteral(2),
|
|
740
|
+
]))),
|
|
192
741
|
]));
|
|
193
|
-
body.body.unshift(guard);
|
|
194
|
-
fakeCrossReferencesCreated +=
|
|
742
|
+
body.body.unshift(stepCallStmt, guard);
|
|
743
|
+
fakeCrossReferencesCreated += 3;
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
body.body.unshift(stepCallStmt);
|
|
747
|
+
fakeCrossReferencesCreated += 1;
|
|
195
748
|
}
|
|
196
749
|
}
|
|
197
|
-
// 4. Build Decoy IPC Ambiguity & Route Mirage block
|
|
750
|
+
// 4. Build Decoy IPC Ambiguity & Route Mirage block + Cognitive-Armor seed entanglement
|
|
198
751
|
const mirageLines = [];
|
|
199
|
-
mirageLines.push(
|
|
752
|
+
mirageLines.push(deceptionSuite.cognitiveArmor.code);
|
|
753
|
+
mirageLines.push(`const ${seedVarName} = (((typeof process !== "undefined" && typeof process?.hrtime?.bigint === "function" ? Number(process.hrtime.bigint() & 0x7fffcn) : (typeof Date !== "undefined" ? (Date.now() & 0x7fffc) : 4)) & 0x7fffc) | ((typeof ${deceptionSuite.cognitiveArmor.digestFunctionName} === "function" && ${deceptionSuite.cognitiveArmor.digestFunctionName}(0) === ${deceptionSuite.cognitiveArmor.expectedDigest}) ? 1 : 0));`);
|
|
754
|
+
mirageLines.push(memoryDiffShield.code);
|
|
200
755
|
const channelsToMirror = observedIpcChannels.size > 0
|
|
201
756
|
? [...observedIpcChannels]
|
|
202
757
|
: ["enclave:attest", "clipboard:bridge-sync", "license:verify-lease"];
|
|
203
758
|
const decoyRouteCount = intensity === "stealth" ? 4 : intensity === "balanced" ? 8 : 10;
|
|
204
759
|
const selectedDecoyRoutes = DECOY_ROUTES.slice(0, decoyRouteCount);
|
|
205
|
-
|
|
760
|
+
const decoyIpcFnName = prng.identifier({ style: "camel", hint: "registerDecoyIpcAndRoutes", entropy: 4 });
|
|
761
|
+
mirageLines.push(`function ${decoyIpcFnName}(_ipcMain, _ipcRenderer, _router) {`);
|
|
206
762
|
mirageLines.push(` if (((Math.imul(${seedVarName} | 11, (${seedVarName} | 11) + 1) & 1) === 1)) {`);
|
|
207
763
|
for (const ch of channelsToMirror) {
|
|
208
764
|
// Register duplicate ambiguous literal channels on both ipcMain and ipcRenderer
|
|
@@ -217,36 +773,118 @@ export function transformJavaScriptWithBlaShield(source, options = {}) {
|
|
|
217
773
|
mirageLines.push(` fetch(${JSON.stringify(route)});`);
|
|
218
774
|
mirageLines.push(` _router?.post?.(${JSON.stringify(route)}, () => null);`);
|
|
219
775
|
}
|
|
776
|
+
const decoySchemes = [
|
|
777
|
+
"enclave-vsock",
|
|
778
|
+
"tee-attest",
|
|
779
|
+
"quorum-kms",
|
|
780
|
+
"sgx-bridge",
|
|
781
|
+
"hsm-lease",
|
|
782
|
+
]
|
|
783
|
+
.filter((s) => !observedProtocolSchemes.has(s))
|
|
784
|
+
.slice(0, 4);
|
|
785
|
+
if (hasProvenElectronRequire && !hasEsmNodes) {
|
|
786
|
+
const elBind = prng.identifier({ style: "privateCamel", hint: "electronRef", entropy: 3 });
|
|
787
|
+
mirageLines.push(` const ${elBind} = require("electron");`);
|
|
788
|
+
for (const sch of decoySchemes) {
|
|
789
|
+
mirageLines.push(` ${elBind}.app.setAsDefaultProtocolClient(${JSON.stringify(sch)});`, ` ${elBind}.protocol.registerSchemesAsPrivileged([{ scheme: ${JSON.stringify(sch)}, privileges: { secure: true, standard: true, supportFetchAPI: true, stream: true } }]);`, ` ${elBind}.protocol.handle(${JSON.stringify(sch)}, () => null);`, ` ${elBind}.session.defaultSession.protocol.handle(${JSON.stringify(sch)}, () => null);`);
|
|
790
|
+
ipcAmbiguitySitesInjected += 4;
|
|
791
|
+
}
|
|
792
|
+
for (const ch of channelsToMirror.slice(0, 4)) {
|
|
793
|
+
mirageLines.push(` ${elBind}.ipcMain.handle(${JSON.stringify(ch)}, () => ({ delegatedToEnclave: true }));`, ` ${elBind}.ipcRenderer.invoke(${JSON.stringify(ch)}, { probe: 1 });`, ` ${elBind}.contextBridge.exposeInMainWorld(${JSON.stringify(`enclave_${prng.hex(2)}`)}, { attest: () => true, verifyLease: () => true });`);
|
|
794
|
+
ipcAmbiguitySitesInjected += 3;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
else if (electronEsmBindings.size > 0) {
|
|
798
|
+
const ns = electronEsmBindings.get("*");
|
|
799
|
+
const appId = electronEsmBindings.get("app") ?? (ns ? `${ns}.app` : null);
|
|
800
|
+
const protoId = electronEsmBindings.get("protocol") ?? (ns ? `${ns}.protocol` : null);
|
|
801
|
+
const sessId = electronEsmBindings.get("session") ?? (ns ? `${ns}.session` : null);
|
|
802
|
+
const ipcMainId = electronEsmBindings.get("ipcMain") ?? (ns ? `${ns}.ipcMain` : null);
|
|
803
|
+
const ipcRenId = electronEsmBindings.get("ipcRenderer") ?? (ns ? `${ns}.ipcRenderer` : null);
|
|
804
|
+
const cbId = electronEsmBindings.get("contextBridge") ?? (ns ? `${ns}.contextBridge` : null);
|
|
805
|
+
for (const sch of decoySchemes) {
|
|
806
|
+
if (appId) {
|
|
807
|
+
mirageLines.push(` ${appId}.setAsDefaultProtocolClient(${JSON.stringify(sch)});`);
|
|
808
|
+
ipcAmbiguitySitesInjected += 1;
|
|
809
|
+
}
|
|
810
|
+
if (protoId) {
|
|
811
|
+
mirageLines.push(` ${protoId}.registerSchemesAsPrivileged([{ scheme: ${JSON.stringify(sch)}, privileges: { secure: true, standard: true, supportFetchAPI: true } }]);`, ` ${protoId}.handle(${JSON.stringify(sch)}, () => null);`);
|
|
812
|
+
ipcAmbiguitySitesInjected += 2;
|
|
813
|
+
}
|
|
814
|
+
if (sessId) {
|
|
815
|
+
mirageLines.push(` ${sessId}.defaultSession.protocol.handle(${JSON.stringify(sch)}, () => null);`);
|
|
816
|
+
ipcAmbiguitySitesInjected += 1;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
for (const ch of channelsToMirror.slice(0, 4)) {
|
|
820
|
+
if (ipcMainId) {
|
|
821
|
+
mirageLines.push(` ${ipcMainId}.handle(${JSON.stringify(ch)}, () => ({ delegatedToEnclave: true }));`);
|
|
822
|
+
ipcAmbiguitySitesInjected += 1;
|
|
823
|
+
}
|
|
824
|
+
if (ipcRenId) {
|
|
825
|
+
mirageLines.push(` ${ipcRenId}.invoke(${JSON.stringify(ch)}, { probe: 1 });`);
|
|
826
|
+
ipcAmbiguitySitesInjected += 1;
|
|
827
|
+
}
|
|
828
|
+
if (cbId) {
|
|
829
|
+
mirageLines.push(` ${cbId}.exposeInMainWorld(${JSON.stringify(`enclave_${prng.hex(2)}`)}, { attest: () => true });`);
|
|
830
|
+
ipcAmbiguitySitesInjected += 1;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
220
834
|
mirageLines.push(` }`);
|
|
221
835
|
mirageLines.push(`}`);
|
|
222
|
-
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
(!source.includes("export ") && source.includes("require("));
|
|
226
|
-
const tarpitCodeNormalized = usesCommonJs
|
|
227
|
-
? tarpit.code.replace(/export function /g, "function ")
|
|
228
|
-
: tarpit.code;
|
|
229
|
-
const combinedInjectedAst = parse([
|
|
836
|
+
mirageLines.push(`void ${decoyIpcFnName};`);
|
|
837
|
+
const deceptionWithoutDuplicateArmor = deceptionSuite.combinedJsCode.replace(deceptionSuite.cognitiveArmor.code, "");
|
|
838
|
+
const injectedBlocks = [
|
|
230
839
|
mirageLines.join("\n"),
|
|
231
|
-
runtimeShield.code,
|
|
232
|
-
|
|
840
|
+
...(options.enableRuntimeShield !== false ? [runtimeShield.code] : []),
|
|
841
|
+
tarpit.code.replace(/\bexport\s+function\s+/g, "function "),
|
|
233
842
|
exhaustionSuite.combinedJsCode,
|
|
234
|
-
|
|
235
|
-
]
|
|
236
|
-
|
|
843
|
+
deceptionWithoutDuplicateArmor,
|
|
844
|
+
];
|
|
845
|
+
const combinedInjectedAst = parse(injectedBlocks.join("\n\n"), {
|
|
846
|
+
sourceType: "script",
|
|
237
847
|
plugins: ["typescript"],
|
|
238
848
|
});
|
|
239
|
-
|
|
849
|
+
const sanitizedInjectedStatements = [];
|
|
850
|
+
for (const stmt of combinedInjectedAst.program.body) {
|
|
851
|
+
if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
|
|
852
|
+
sanitizedInjectedStatements.push(stmt.declaration);
|
|
853
|
+
}
|
|
854
|
+
else if (!t.isImportDeclaration(stmt) &&
|
|
855
|
+
!t.isExportNamedDeclaration(stmt) &&
|
|
856
|
+
!t.isExportDefaultDeclaration(stmt) &&
|
|
857
|
+
!t.isExportAllDeclaration(stmt)) {
|
|
858
|
+
sanitizedInjectedStatements.push(stmt);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
// Prepend Cognitive-Armor corpus, digest function, `seedVarName`, and shadow heap at top of program
|
|
240
862
|
let insertIndex = 0;
|
|
241
|
-
while (insertIndex < ast.program.body.length
|
|
242
|
-
|
|
243
|
-
|
|
863
|
+
while (insertIndex < ast.program.body.length) {
|
|
864
|
+
const stmt = ast.program.body[insertIndex];
|
|
865
|
+
if (t.isImportDeclaration(stmt)) {
|
|
866
|
+
insertIndex++;
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
if (t.isExpressionStatement(stmt) &&
|
|
870
|
+
t.isStringLiteral(stmt.expression) &&
|
|
871
|
+
stmt.expression.value.startsWith("use ")) {
|
|
872
|
+
insertIndex++;
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
break;
|
|
244
876
|
}
|
|
245
|
-
const [seedDecl, ...restInjected] =
|
|
246
|
-
|
|
247
|
-
|
|
877
|
+
const [corpusDecl, digestFnDecl, seedDecl, heapDecl, ...restInjected] = sanitizedInjectedStatements;
|
|
878
|
+
const topDecls = [corpusDecl, digestFnDecl, seedDecl, heapDecl].filter((s) => s !== undefined);
|
|
879
|
+
if (topDecls.length > 0) {
|
|
880
|
+
ast.program.body.splice(insertIndex, 0, ...topDecls);
|
|
248
881
|
}
|
|
249
882
|
ast.program.body.push(...restInjected);
|
|
883
|
+
const exportedSymbolsAfter = collectEsmExportedSymbols(ast.program);
|
|
884
|
+
if (exportedSymbolsBefore.length !== exportedSymbolsAfter.length ||
|
|
885
|
+
exportedSymbolsBefore.some((sym, idx) => sym !== exportedSymbolsAfter[idx])) {
|
|
886
|
+
throw new InvalidJavaScriptCarrierError("Internal error: BLA JavaScript transform mutated module export surface");
|
|
887
|
+
}
|
|
250
888
|
// Strip any existing `//# sourceMappingURL=` comments from AST
|
|
251
889
|
if (ast.comments) {
|
|
252
890
|
ast.comments = ast.comments.filter((c) => !/sourceMappingURL=/i.test(c.value));
|
|
@@ -258,11 +896,14 @@ export function transformJavaScriptWithBlaShield(source, options = {}) {
|
|
|
258
896
|
}, source);
|
|
259
897
|
return {
|
|
260
898
|
code: generated.code,
|
|
899
|
+
carrierType: effectiveCarrier,
|
|
900
|
+
loader,
|
|
901
|
+
exportedSymbols: exportedSymbolsAfter,
|
|
261
902
|
decoyFunctionsInjected: tarpit.decoyFunctionNames.length +
|
|
262
903
|
exhaustionSuite.totalLabyrinthNodes +
|
|
263
904
|
deceptionSuite.shadowLogic.shadowProceduresCreated.length +
|
|
264
905
|
deceptionSuite.semanticHoneypot.baitSymbols.length +
|
|
265
|
-
|
|
906
|
+
2,
|
|
266
907
|
fakeCrossReferencesCreated: fakeCrossReferencesCreated + exhaustionSuite.totalCrossReferenceEdges,
|
|
267
908
|
primitiveCandidateBranchesCreated,
|
|
268
909
|
aliasSelectionStatesCreated: 4_194_304, // 2^22 selector states in aliasFn
|
|
@@ -270,6 +911,9 @@ export function transformJavaScriptWithBlaShield(source, options = {}) {
|
|
|
270
911
|
decoyRoutesInjected: selectedDecoyRoutes.length +
|
|
271
912
|
deceptionSuite.architectureMirage.decoyRpcMethods.length,
|
|
272
913
|
chaffPayloadsEmbedded: chaffPayloads.length + deceptionSuite.evidencePoison.lures.length,
|
|
914
|
+
shadowHeapSlotsChurned: memoryDiffShield.mutableSlotsCount,
|
|
915
|
+
electronProtocolsProtected,
|
|
916
|
+
memoryDiffShield,
|
|
273
917
|
};
|
|
274
918
|
}
|
|
275
919
|
//# sourceMappingURL=ast-shield.js.map
|