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.
Files changed (279) hide show
  1. package/.agents/skills/blind-llm-agents/SKILL.md +20 -14
  2. package/DISCLAIMER.md +15 -7
  3. package/README.md +153 -198
  4. package/dist/bundler/index.d.ts +19 -2
  5. package/dist/bundler/index.d.ts.map +1 -1
  6. package/dist/bundler/index.js +47 -4
  7. package/dist/bundler/index.js.map +1 -1
  8. package/dist/cli.d.ts +5 -0
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +123 -18
  11. package/dist/cli.js.map +1 -1
  12. package/dist/core/config.d.ts +54 -0
  13. package/dist/core/config.d.ts.map +1 -0
  14. package/dist/core/config.js +160 -0
  15. package/dist/core/config.js.map +1 -0
  16. package/dist/core/coverage-contract.d.ts +97 -0
  17. package/dist/core/coverage-contract.d.ts.map +1 -0
  18. package/dist/core/coverage-contract.js +164 -0
  19. package/dist/core/coverage-contract.js.map +1 -0
  20. package/dist/core/debug-posture.d.ts +40 -0
  21. package/dist/core/debug-posture.d.ts.map +1 -0
  22. package/dist/core/debug-posture.js +197 -0
  23. package/dist/core/debug-posture.js.map +1 -0
  24. package/dist/core/detector.d.ts.map +1 -1
  25. package/dist/core/detector.js +58 -6
  26. package/dist/core/detector.js.map +1 -1
  27. package/dist/core/identifiers.d.ts +32 -0
  28. package/dist/core/identifiers.d.ts.map +1 -0
  29. package/dist/core/identifiers.js +263 -0
  30. package/dist/core/identifiers.js.map +1 -0
  31. package/dist/core/llm-directives.d.ts +12 -0
  32. package/dist/core/llm-directives.d.ts.map +1 -0
  33. package/dist/core/llm-directives.js +23 -0
  34. package/dist/core/llm-directives.js.map +1 -0
  35. package/dist/core/prng.d.ts +10 -1
  36. package/dist/core/prng.d.ts.map +1 -1
  37. package/dist/core/prng.js +27 -2
  38. package/dist/core/prng.js.map +1 -1
  39. package/dist/core/release-exposure.d.ts.map +1 -1
  40. package/dist/core/release-exposure.js +13 -2
  41. package/dist/core/release-exposure.js.map +1 -1
  42. package/dist/core/release-plan.d.ts +68 -0
  43. package/dist/core/release-plan.d.ts.map +1 -0
  44. package/dist/core/release-plan.js +244 -0
  45. package/dist/core/release-plan.js.map +1 -0
  46. package/dist/core/sarif.d.ts +53 -0
  47. package/dist/core/sarif.d.ts.map +1 -0
  48. package/dist/core/sarif.js +95 -0
  49. package/dist/core/sarif.js.map +1 -0
  50. package/dist/core/sqlite-runtime.d.ts +13 -0
  51. package/dist/core/sqlite-runtime.d.ts.map +1 -1
  52. package/dist/core/sqlite-runtime.js +38 -8
  53. package/dist/core/sqlite-runtime.js.map +1 -1
  54. package/dist/core/types.d.ts +7 -2
  55. package/dist/core/types.d.ts.map +1 -1
  56. package/dist/engine/auditor.d.ts.map +1 -1
  57. package/dist/engine/auditor.js +380 -19
  58. package/dist/engine/auditor.js.map +1 -1
  59. package/dist/engine/benchmark.d.ts +1 -1
  60. package/dist/engine/benchmark.d.ts.map +1 -1
  61. package/dist/engine/benchmark.js +121 -41
  62. package/dist/engine/benchmark.js.map +1 -1
  63. package/dist/engine/defender.d.ts +1 -0
  64. package/dist/engine/defender.d.ts.map +1 -1
  65. package/dist/engine/defender.js +7 -1
  66. package/dist/engine/defender.js.map +1 -1
  67. package/dist/engine/harden.d.ts +61 -0
  68. package/dist/engine/harden.d.ts.map +1 -0
  69. package/dist/engine/harden.js +294 -0
  70. package/dist/engine/harden.js.map +1 -0
  71. package/dist/engine/protector.d.ts.map +1 -1
  72. package/dist/engine/protector.js +242 -26
  73. package/dist/engine/protector.js.map +1 -1
  74. package/dist/identity.d.ts +112 -2
  75. package/dist/identity.d.ts.map +1 -1
  76. package/dist/identity.js +112 -2
  77. package/dist/identity.js.map +1 -1
  78. package/dist/index.d.ts +26 -9
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +26 -9
  81. package/dist/index.js.map +1 -1
  82. package/dist/mcp/server.d.ts +59 -152
  83. package/dist/mcp/server.d.ts.map +1 -1
  84. package/dist/mcp/server.js +466 -50
  85. package/dist/mcp/server.js.map +1 -1
  86. package/dist/setup/clients.d.ts +49 -1
  87. package/dist/setup/clients.d.ts.map +1 -1
  88. package/dist/setup/clients.js +1193 -20
  89. package/dist/setup/clients.js.map +1 -1
  90. package/dist/setup/doctor.d.ts +58 -14
  91. package/dist/setup/doctor.d.ts.map +1 -1
  92. package/dist/setup/doctor.js +316 -22
  93. package/dist/setup/doctor.js.map +1 -1
  94. package/dist/setup/setup.d.ts +77 -7
  95. package/dist/setup/setup.d.ts.map +1 -1
  96. package/dist/setup/setup.js +591 -62
  97. package/dist/setup/setup.js.map +1 -1
  98. package/dist/shields/chaff/chaff-generator.d.ts.map +1 -1
  99. package/dist/shields/chaff/chaff-generator.js +12 -3
  100. package/dist/shields/chaff/chaff-generator.js.map +1 -1
  101. package/dist/shields/deception/architecture-mirage.js +1 -1
  102. package/dist/shields/deception/architecture-mirage.js.map +1 -1
  103. package/dist/shields/deception/canary-honeypot.d.ts +33 -0
  104. package/dist/shields/deception/canary-honeypot.d.ts.map +1 -0
  105. package/dist/shields/deception/canary-honeypot.js +95 -0
  106. package/dist/shields/deception/canary-honeypot.js.map +1 -0
  107. package/dist/shields/deception/cognitive-armor-trigger.d.ts +43 -0
  108. package/dist/shields/deception/cognitive-armor-trigger.d.ts.map +1 -0
  109. package/dist/shields/deception/cognitive-armor-trigger.js +204 -0
  110. package/dist/shields/deception/cognitive-armor-trigger.js.map +1 -0
  111. package/dist/shields/deception/crash-trace-decoy.js +1 -1
  112. package/dist/shields/deception/crash-trace-decoy.js.map +1 -1
  113. package/dist/shields/deception/decompiler-illusion.js +1 -1
  114. package/dist/shields/deception/decompiler-illusion.js.map +1 -1
  115. package/dist/shields/deception/diff-noise-injector.js +1 -1
  116. package/dist/shields/deception/diff-noise-injector.js.map +1 -1
  117. package/dist/shields/deception/evidence-contract-poison.js +5 -5
  118. package/dist/shields/deception/evidence-contract-poison.js.map +1 -1
  119. package/dist/shields/deception/format-payloads.d.ts +21 -0
  120. package/dist/shields/deception/format-payloads.d.ts.map +1 -0
  121. package/dist/shields/deception/format-payloads.js +24 -0
  122. package/dist/shields/deception/format-payloads.js.map +1 -0
  123. package/dist/shields/deception/index.d.ts +10 -2
  124. package/dist/shields/deception/index.d.ts.map +1 -1
  125. package/dist/shields/deception/index.js +20 -3
  126. package/dist/shields/deception/index.js.map +1 -1
  127. package/dist/shields/deception/prompt-completion-poison.d.ts +3 -2
  128. package/dist/shields/deception/prompt-completion-poison.d.ts.map +1 -1
  129. package/dist/shields/deception/prompt-completion-poison.js +6 -3
  130. package/dist/shields/deception/prompt-completion-poison.js.map +1 -1
  131. package/dist/shields/deception/shadow-business-logic.js +4 -4
  132. package/dist/shields/deception/shadow-business-logic.js.map +1 -1
  133. package/dist/shields/deception/system-diagnostic-decoy.d.ts +36 -0
  134. package/dist/shields/deception/system-diagnostic-decoy.d.ts.map +1 -0
  135. package/dist/shields/deception/system-diagnostic-decoy.js +101 -0
  136. package/dist/shields/deception/system-diagnostic-decoy.js.map +1 -0
  137. package/dist/shields/exhaustion/asar-header-amplifier.d.ts +12 -3
  138. package/dist/shields/exhaustion/asar-header-amplifier.d.ts.map +1 -1
  139. package/dist/shields/exhaustion/asar-header-amplifier.js +30 -8
  140. package/dist/shields/exhaustion/asar-header-amplifier.js.map +1 -1
  141. package/dist/shields/exhaustion/bpe-token-amplifier.js +2 -2
  142. package/dist/shields/exhaustion/bpe-token-amplifier.js.map +1 -1
  143. package/dist/shields/exhaustion/callgraph-labyrinth.js +2 -2
  144. package/dist/shields/exhaustion/callgraph-labyrinth.js.map +1 -1
  145. package/dist/shields/exhaustion/cdp-shape-budget-breaker.js +1 -1
  146. package/dist/shields/exhaustion/cdp-shape-budget-breaker.js.map +1 -1
  147. package/dist/shields/exhaustion/frida-capture-saturation.d.ts +10 -5
  148. package/dist/shields/exhaustion/frida-capture-saturation.d.ts.map +1 -1
  149. package/dist/shields/exhaustion/frida-capture-saturation.js +21 -8
  150. package/dist/shields/exhaustion/frida-capture-saturation.js.map +1 -1
  151. package/dist/shields/exhaustion/index.d.ts +2 -2
  152. package/dist/shields/exhaustion/index.d.ts.map +1 -1
  153. package/dist/shields/exhaustion/index.js +2 -2
  154. package/dist/shields/exhaustion/index.js.map +1 -1
  155. package/dist/shields/exhaustion/obligation-flooder.d.ts +23 -6
  156. package/dist/shields/exhaustion/obligation-flooder.d.ts.map +1 -1
  157. package/dist/shields/exhaustion/obligation-flooder.js +29 -12
  158. package/dist/shields/exhaustion/obligation-flooder.js.map +1 -1
  159. package/dist/shields/exhaustion/rea-budget-matrix.d.ts +8 -2
  160. package/dist/shields/exhaustion/rea-budget-matrix.d.ts.map +1 -1
  161. package/dist/shields/exhaustion/rea-budget-matrix.js +139 -16
  162. package/dist/shields/exhaustion/rea-budget-matrix.js.map +1 -1
  163. package/dist/shields/exhaustion/regex-worker-tarpit.d.ts.map +1 -1
  164. package/dist/shields/exhaustion/regex-worker-tarpit.js +2 -1
  165. package/dist/shields/exhaustion/regex-worker-tarpit.js.map +1 -1
  166. package/dist/shields/exhaustion/wasm-interface-exhaustion.d.ts +7 -4
  167. package/dist/shields/exhaustion/wasm-interface-exhaustion.d.ts.map +1 -1
  168. package/dist/shields/exhaustion/wasm-interface-exhaustion.js +16 -7
  169. package/dist/shields/exhaustion/wasm-interface-exhaustion.js.map +1 -1
  170. package/dist/shields/formats/android-dex-xref.d.ts +19 -0
  171. package/dist/shields/formats/android-dex-xref.d.ts.map +1 -0
  172. package/dist/shields/formats/android-dex-xref.js +427 -0
  173. package/dist/shields/formats/android-dex-xref.js.map +1 -0
  174. package/dist/shields/formats/android-manifest.d.ts +44 -0
  175. package/dist/shields/formats/android-manifest.d.ts.map +1 -0
  176. package/dist/shields/formats/android-manifest.js +240 -0
  177. package/dist/shields/formats/android-manifest.js.map +1 -0
  178. package/dist/shields/formats/android-r8.d.ts +44 -0
  179. package/dist/shields/formats/android-r8.d.ts.map +1 -0
  180. package/dist/shields/formats/android-r8.js +246 -0
  181. package/dist/shields/formats/android-r8.js.map +1 -0
  182. package/dist/shields/formats/apple-plist.d.ts +15 -0
  183. package/dist/shields/formats/apple-plist.d.ts.map +1 -1
  184. package/dist/shields/formats/apple-plist.js +59 -1
  185. package/dist/shields/formats/apple-plist.js.map +1 -1
  186. package/dist/shields/formats/archive.d.ts +27 -6
  187. package/dist/shields/formats/archive.d.ts.map +1 -1
  188. package/dist/shields/formats/archive.js +247 -45
  189. package/dist/shields/formats/archive.js.map +1 -1
  190. package/dist/shields/formats/asar.d.ts +50 -10
  191. package/dist/shields/formats/asar.d.ts.map +1 -1
  192. package/dist/shields/formats/asar.js +265 -39
  193. package/dist/shields/formats/asar.js.map +1 -1
  194. package/dist/shields/formats/bun-standalone.d.ts +78 -0
  195. package/dist/shields/formats/bun-standalone.d.ts.map +1 -0
  196. package/dist/shields/formats/bun-standalone.js +272 -0
  197. package/dist/shields/formats/bun-standalone.js.map +1 -0
  198. package/dist/shields/formats/dotnet-managed.d.ts +9 -0
  199. package/dist/shields/formats/dotnet-managed.d.ts.map +1 -1
  200. package/dist/shields/formats/dotnet-managed.js +26 -1
  201. package/dist/shields/formats/dotnet-managed.js.map +1 -1
  202. package/dist/shields/formats/electron-fuses.d.ts +63 -8
  203. package/dist/shields/formats/electron-fuses.d.ts.map +1 -1
  204. package/dist/shields/formats/electron-fuses.js +297 -65
  205. package/dist/shields/formats/electron-fuses.js.map +1 -1
  206. package/dist/shields/formats/erlang-beam.d.ts +34 -0
  207. package/dist/shields/formats/erlang-beam.d.ts.map +1 -0
  208. package/dist/shields/formats/erlang-beam.js +319 -0
  209. package/dist/shields/formats/erlang-beam.js.map +1 -0
  210. package/dist/shields/formats/evm-bytecode.d.ts +28 -0
  211. package/dist/shields/formats/evm-bytecode.d.ts.map +1 -0
  212. package/dist/shields/formats/evm-bytecode.js +124 -0
  213. package/dist/shields/formats/evm-bytecode.js.map +1 -0
  214. package/dist/shields/formats/go-flutter-exhaustion.d.ts +55 -0
  215. package/dist/shields/formats/go-flutter-exhaustion.d.ts.map +1 -0
  216. package/dist/shields/formats/go-flutter-exhaustion.js +346 -0
  217. package/dist/shields/formats/go-flutter-exhaustion.js.map +1 -0
  218. package/dist/shields/formats/gpu-ptx.d.ts +40 -0
  219. package/dist/shields/formats/gpu-ptx.d.ts.map +1 -0
  220. package/dist/shields/formats/gpu-ptx.js +62 -0
  221. package/dist/shields/formats/gpu-ptx.js.map +1 -0
  222. package/dist/shields/formats/headers.d.ts.map +1 -1
  223. package/dist/shields/formats/headers.js +54 -14
  224. package/dist/shields/formats/headers.js.map +1 -1
  225. package/dist/shields/formats/jvm-bytecode.d.ts +20 -0
  226. package/dist/shields/formats/jvm-bytecode.d.ts.map +1 -0
  227. package/dist/shields/formats/jvm-bytecode.js +134 -0
  228. package/dist/shields/formats/jvm-bytecode.js.map +1 -0
  229. package/dist/shields/formats/mobile-game.d.ts +4 -0
  230. package/dist/shields/formats/mobile-game.d.ts.map +1 -1
  231. package/dist/shields/formats/mobile-game.js +16 -0
  232. package/dist/shields/formats/mobile-game.js.map +1 -1
  233. package/dist/shields/formats/model.d.ts +22 -8
  234. package/dist/shields/formats/model.d.ts.map +1 -1
  235. package/dist/shields/formats/model.js +231 -59
  236. package/dist/shields/formats/model.js.map +1 -1
  237. package/dist/shields/formats/native.d.ts +74 -11
  238. package/dist/shields/formats/native.d.ts.map +1 -1
  239. package/dist/shields/formats/native.js +557 -109
  240. package/dist/shields/formats/native.js.map +1 -1
  241. package/dist/shields/formats/pcap-capture.d.ts +27 -0
  242. package/dist/shields/formats/pcap-capture.d.ts.map +1 -0
  243. package/dist/shields/formats/pcap-capture.js +201 -0
  244. package/dist/shields/formats/pcap-capture.js.map +1 -0
  245. package/dist/shields/formats/python.d.ts +22 -1
  246. package/dist/shields/formats/python.d.ts.map +1 -1
  247. package/dist/shields/formats/python.js +568 -27
  248. package/dist/shields/formats/python.js.map +1 -1
  249. package/dist/shields/formats/sourcemap.d.ts.map +1 -1
  250. package/dist/shields/formats/sourcemap.js +2 -0
  251. package/dist/shields/formats/sourcemap.js.map +1 -1
  252. package/dist/shields/formats/sqlite.d.ts +87 -15
  253. package/dist/shields/formats/sqlite.d.ts.map +1 -1
  254. package/dist/shields/formats/sqlite.js +377 -42
  255. package/dist/shields/formats/sqlite.js.map +1 -1
  256. package/dist/shields/formats/wasm.d.ts +6 -0
  257. package/dist/shields/formats/wasm.d.ts.map +1 -1
  258. package/dist/shields/formats/wasm.js +118 -3
  259. package/dist/shields/formats/wasm.js.map +1 -1
  260. package/dist/shields/javascript/ast-shield.d.ts +26 -5
  261. package/dist/shields/javascript/ast-shield.d.ts.map +1 -1
  262. package/dist/shields/javascript/ast-shield.js +748 -104
  263. package/dist/shields/javascript/ast-shield.js.map +1 -1
  264. package/dist/shields/runtime/memory-diff-shield.d.ts +56 -0
  265. package/dist/shields/runtime/memory-diff-shield.d.ts.map +1 -0
  266. package/dist/shields/runtime/memory-diff-shield.js +170 -0
  267. package/dist/shields/runtime/memory-diff-shield.js.map +1 -0
  268. package/dist/shields/runtime/runtime-shield.d.ts +12 -16
  269. package/dist/shields/runtime/runtime-shield.d.ts.map +1 -1
  270. package/dist/shields/runtime/runtime-shield.js +30 -24
  271. package/dist/shields/runtime/runtime-shield.js.map +1 -1
  272. package/dist/shields/tarpit/opaque-predicates.d.ts.map +1 -1
  273. package/dist/shields/tarpit/opaque-predicates.js +3 -3
  274. package/dist/shields/tarpit/opaque-predicates.js.map +1 -1
  275. package/dist/shields/tarpit/tarpit-generator.d.ts +9 -4
  276. package/dist/shields/tarpit/tarpit-generator.d.ts.map +1 -1
  277. package/dist/shields/tarpit/tarpit-generator.js +30 -23
  278. package/dist/shields/tarpit/tarpit-generator.js.map +1 -1
  279. package/package.json +13 -6
@@ -1,8 +1,196 @@
1
+ import { detectBunStandaloneGraph, } from "./bun-standalone.js";
1
2
  import { deflateSync } from "node:zlib";
2
3
  import { REA_INTERNAL_LIMITS } from "../../identity.js";
3
4
  import { SeededPrng } from "../../core/prng.js";
4
5
  import { generateChaffPayloads } from "../chaff/chaff-generator.js";
5
- import { hardenAndOverflowElectronFuses, inspectElectronFusesInBuffer, } from "./electron-fuses.js";
6
+ import { generateCanaryHoneypot } from "../deception/canary-honeypot.js";
7
+ import { generateSystemDiagnosticDecoy } from "../deception/system-diagnostic-decoy.js";
8
+ import { generateCognitiveArmorTrigger } from "../deception/cognitive-armor-trigger.js";
9
+ import { buildDecoyElectronFuseSentinels, hardenElectronFusesWithContext, inspectElectronFusesInBuffer, } from "./electron-fuses.js";
10
+ import { buildGoBuildInfoExhaustionPayload, buildFlutterPoolExhaustionPayload, buildMappedGoBuildInfoPlant, buildMappedFlutterIsolatePoolPlant, } from "./go-flutter-exhaustion.js";
11
+ export class InvalidNativeBinaryError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "InvalidNativeBinaryError";
15
+ }
16
+ }
17
+ const MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
18
+ /**
19
+ * Validates ELF64 little-endian header, program headers (`PT_LOAD`, `p_filesz <= p_memsz`,
20
+ * non-overlapping virtual address ranges, in-bounds file ranges), and section headers
21
+ * (in-bounds file ranges, valid `e_shstrndx`, non-overlapping file-backed sections).
22
+ */
23
+ export function validateElf64Layout(bytes) {
24
+ if (bytes.length < 64 ||
25
+ bytes[0] !== 0x7f ||
26
+ bytes[1] !== 0x45 ||
27
+ bytes[2] !== 0x4c ||
28
+ bytes[3] !== 0x46) {
29
+ throw new InvalidNativeBinaryError("Invalid or truncated ELF header (minimum 64 bytes required)");
30
+ }
31
+ if (bytes[4] !== 2 || bytes[5] !== 1) {
32
+ throw new InvalidNativeBinaryError("Unsupported ELF class or endianness (expected ELF64 little-endian)");
33
+ }
34
+ const phoffBig = bytes.readBigUInt64LE(32);
35
+ const shoffBig = bytes.readBigUInt64LE(40);
36
+ const ehsize = bytes.readUInt16LE(52);
37
+ const phentsize = bytes.readUInt16LE(54);
38
+ const phnum = bytes.readUInt16LE(56);
39
+ const shentsize = bytes.readUInt16LE(58);
40
+ const shnum = bytes.readUInt16LE(60);
41
+ const shstrndx = bytes.readUInt16LE(62);
42
+ if (ehsize !== 0 && (ehsize < 64 || ehsize > bytes.length)) {
43
+ throw new InvalidNativeBinaryError(`Invalid ELF64 e_ehsize: ${ehsize}`);
44
+ }
45
+ if (phoffBig > MAX_SAFE_BIGINT || shoffBig > MAX_SAFE_BIGINT) {
46
+ throw new InvalidNativeBinaryError("ELF64 header table offsets exceed safe integer range");
47
+ }
48
+ const phoff = Number(phoffBig);
49
+ const shoff = Number(shoffBig);
50
+ const programHeaders = [];
51
+ const phTableEnd = phnum > 0 ? phoff + phnum * phentsize : 0;
52
+ if (phnum > 0) {
53
+ if (phentsize < 56 ||
54
+ phoff < 64 ||
55
+ !Number.isSafeInteger(phTableEnd) ||
56
+ phTableEnd > bytes.length) {
57
+ throw new InvalidNativeBinaryError("ELF64 program header table out of bounds or malformed");
58
+ }
59
+ for (let i = 0; i < phnum; i++) {
60
+ const phdr = phoff + i * phentsize;
61
+ const pType = bytes.readUInt32LE(phdr);
62
+ const pFlags = bytes.readUInt32LE(phdr + 4);
63
+ const pOffsetBig = bytes.readBigUInt64LE(phdr + 8);
64
+ const pVaddrBig = bytes.readBigUInt64LE(phdr + 16);
65
+ const pPaddrBig = bytes.readBigUInt64LE(phdr + 24);
66
+ const pFileszBig = bytes.readBigUInt64LE(phdr + 32);
67
+ const pMemszBig = bytes.readBigUInt64LE(phdr + 40);
68
+ const pAlignBig = bytes.readBigUInt64LE(phdr + 48);
69
+ if (pOffsetBig > MAX_SAFE_BIGINT || pFileszBig > MAX_SAFE_BIGINT) {
70
+ throw new InvalidNativeBinaryError(`ELF64 program header ${i} file offset/size exceeds safe integer range`);
71
+ }
72
+ const pOffset = Number(pOffsetBig);
73
+ const pFilesz = Number(pFileszBig);
74
+ if (!Number.isSafeInteger(pOffset + pFilesz) ||
75
+ pOffset + pFilesz > bytes.length) {
76
+ throw new InvalidNativeBinaryError(`ELF64 program header ${i} file range [${pOffset}, ${pOffset + pFilesz}) out of bounds (${bytes.length})`);
77
+ }
78
+ if (pType === 1) {
79
+ // PT_LOAD
80
+ if (pMemszBig < pFileszBig) {
81
+ throw new InvalidNativeBinaryError(`ELF64 PT_LOAD segment ${i} has p_memsz (${pMemszBig}) < p_filesz (${pFileszBig})`);
82
+ }
83
+ }
84
+ programHeaders.push({
85
+ index: i,
86
+ type: pType,
87
+ flags: pFlags,
88
+ offset: pOffset,
89
+ vaddr: pVaddrBig,
90
+ paddr: pPaddrBig,
91
+ filesz: pFilesz,
92
+ memsz: pMemszBig,
93
+ align: pAlignBig,
94
+ });
95
+ }
96
+ // Verify no two PT_LOAD segments have overlapping virtual address ranges
97
+ const loadSegments = programHeaders.filter((ph) => ph.type === 1 && ph.memsz > 0n);
98
+ for (let i = 0; i < loadSegments.length; i++) {
99
+ const a = loadSegments[i];
100
+ const aEnd = a.vaddr + a.memsz;
101
+ for (let j = i + 1; j < loadSegments.length; j++) {
102
+ const b = loadSegments[j];
103
+ const bEnd = b.vaddr + b.memsz;
104
+ if (a.vaddr < bEnd && b.vaddr < aEnd) {
105
+ throw new InvalidNativeBinaryError(`ELF64 PT_LOAD segments ${a.index} and ${b.index} have overlapping virtual address ranges`);
106
+ }
107
+ }
108
+ }
109
+ }
110
+ const sectionHeaders = [];
111
+ const shTableEnd = shnum > 0 ? shoff + shnum * shentsize : 0;
112
+ if (shnum > 0) {
113
+ if (shentsize < 64 ||
114
+ shoff < 64 ||
115
+ !Number.isSafeInteger(shTableEnd) ||
116
+ shTableEnd > bytes.length) {
117
+ throw new InvalidNativeBinaryError("ELF64 section header table out of bounds or malformed");
118
+ }
119
+ if (phnum > 0 && phoff < shTableEnd && shoff < phTableEnd) {
120
+ throw new InvalidNativeBinaryError("ELF64 section header table overlaps program header table");
121
+ }
122
+ if (shstrndx !== 0 && shstrndx >= shnum) {
123
+ throw new InvalidNativeBinaryError(`ELF64 e_shstrndx (${shstrndx}) out of bounds for e_shnum (${shnum})`);
124
+ }
125
+ for (let s = 0; s < shnum; s++) {
126
+ const shdr = shoff + s * shentsize;
127
+ const shName = bytes.readUInt32LE(shdr);
128
+ const shType = bytes.readUInt32LE(shdr + 4);
129
+ const shFlags = bytes.readBigUInt64LE(shdr + 8);
130
+ const shAddr = bytes.readBigUInt64LE(shdr + 16);
131
+ const shOffsetBig = bytes.readBigUInt64LE(shdr + 24);
132
+ const shSizeBig = bytes.readBigUInt64LE(shdr + 32);
133
+ if (shOffsetBig > MAX_SAFE_BIGINT || shSizeBig > MAX_SAFE_BIGINT) {
134
+ throw new InvalidNativeBinaryError(`ELF64 section ${s} offset/size exceeds safe integer range`);
135
+ }
136
+ const shOffset = Number(shOffsetBig);
137
+ const shSize = Number(shSizeBig);
138
+ // File-backed sections: not SHT_NULL (0) and not SHT_NOBITS (8)
139
+ if (s >= 1 && shType !== 0 && shType !== 8) {
140
+ if (!Number.isSafeInteger(shOffset + shSize) ||
141
+ shOffset + shSize > bytes.length) {
142
+ throw new InvalidNativeBinaryError(`ELF64 section ${s} file range [${shOffset}, ${shOffset + shSize}) out of bounds (${bytes.length})`);
143
+ }
144
+ if (shSize > 0) {
145
+ if (shOffset < 64) {
146
+ throw new InvalidNativeBinaryError(`ELF64 section ${s} overlaps ELF64 header`);
147
+ }
148
+ if (phnum > 0 &&
149
+ shOffset < phTableEnd &&
150
+ phoff < shOffset + shSize) {
151
+ throw new InvalidNativeBinaryError(`ELF64 section ${s} overlaps program header table`);
152
+ }
153
+ if (shOffset < shTableEnd && shoff < shOffset + shSize) {
154
+ throw new InvalidNativeBinaryError(`ELF64 section ${s} overlaps section header table`);
155
+ }
156
+ }
157
+ }
158
+ sectionHeaders.push({
159
+ index: s,
160
+ nameOffset: shName,
161
+ type: shType,
162
+ flags: shFlags,
163
+ addr: shAddr,
164
+ offset: shOffset,
165
+ size: shSize,
166
+ });
167
+ }
168
+ // Verify no two non-empty file-backed sections overlap in file range
169
+ const fileBackedSections = sectionHeaders.filter((sec) => sec.index >= 1 && sec.type !== 0 && sec.type !== 8 && sec.size > 0);
170
+ for (let i = 0; i < fileBackedSections.length; i++) {
171
+ const a = fileBackedSections[i];
172
+ const aEnd = a.offset + a.size;
173
+ for (let j = i + 1; j < fileBackedSections.length; j++) {
174
+ const b = fileBackedSections[j];
175
+ const bEnd = b.offset + b.size;
176
+ if (a.offset < bEnd && b.offset < aEnd) {
177
+ throw new InvalidNativeBinaryError(`ELF64 sections ${a.index} and ${b.index} have overlapping file ranges`);
178
+ }
179
+ }
180
+ }
181
+ }
182
+ return {
183
+ phoff,
184
+ phentsize,
185
+ phnum,
186
+ shoff,
187
+ shentsize,
188
+ shnum,
189
+ shstrndx,
190
+ programHeaders,
191
+ sectionHeaders,
192
+ };
193
+ }
6
194
  export function inspectNativeBinary(bytes) {
7
195
  let format = "unknown";
8
196
  let bits = 64;
@@ -65,12 +253,29 @@ export function inspectNativeBinary(bytes) {
65
253
  const hasRustDepV0 = textLatin1.includes(".dep-v0");
66
254
  const hasGoBuildInfo = textLatin1.includes(".go.buildinfo") ||
67
255
  textLatin1.includes("__go_buildinfo") ||
68
- textLatin1.includes("\xff Go buildinf:");
256
+ textLatin1.includes("\xff Go buildinf:") ||
257
+ textLatin1.includes("[BLA-GO-BUILDINFO]");
258
+ const goBuildInfoFramed = textLatin1.includes("[BLA-GO-BUILDINFO]") ||
259
+ textLatin1.includes(".gopclntab") ||
260
+ textLatin1.includes("runtime.moduledata");
261
+ let dartPoolPackageUriCount = 0;
262
+ let dartPoolTokenCount = 0;
263
+ for (const run of textLatin1.split("\0")) {
264
+ if (run.startsWith("package:") || run.startsWith("dart:")) {
265
+ dartPoolPackageUriCount++;
266
+ }
267
+ else if (run.length >= 5 &&
268
+ run.length <= 128 &&
269
+ /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(run)) {
270
+ dartPoolTokenCount++;
271
+ }
272
+ }
69
273
  const printableMatches = textLatin1.match(/[A-Za-z0-9_/:.-]{6,}/g) ?? [];
70
274
  const blaProtected = textLatin1.includes("BLA-NATIVE-SHIELD") ||
71
275
  rustcMatches.size > REA_INTERNAL_LIMITS.RUST_MAX_COMMIT_HASHES ||
72
276
  fuseInspection.exceedsReaSentinelLimit ||
73
- dartSnapshotHashesCount > REA_INTERNAL_LIMITS.DART_MAX_SNAPSHOT_HASH_CANDIDATES ||
277
+ dartSnapshotHashesCount >
278
+ REA_INTERNAL_LIMITS.DART_MAX_SNAPSHOT_HASH_CANDIDATES ||
74
279
  textLatin1.includes("Architecture Notice: Core business logic");
75
280
  return {
76
281
  format,
@@ -79,8 +284,11 @@ export function inspectNativeBinary(bytes) {
79
284
  rustcCommitHashesCount: rustcMatches.size,
80
285
  electronFuseSentinelsCount: fuseInspection.sentinelCount,
81
286
  dartSnapshotHashesCount,
287
+ dartPoolPackageUriCount,
288
+ dartPoolTokenCount,
82
289
  hasRustDepV0,
83
290
  hasGoBuildInfo,
291
+ goBuildInfoFramed,
84
292
  extractedStringsCount: printableMatches.length,
85
293
  blaProtected,
86
294
  };
@@ -122,60 +330,305 @@ export function buildDecoyRustAuditablePayload(prng) {
122
330
  ];
123
331
  return deflateSync(Buffer.from(JSON.stringify({ format: 1, packages }), "utf8"));
124
332
  }
333
+ /** Resolve ELF64 section names from the section-header string table. */
334
+ export function resolveElf64SectionNames(bytes, layout) {
335
+ const map = new Map();
336
+ if (layout.shnum === 0 ||
337
+ layout.shstrndx === 0 ||
338
+ layout.shstrndx >= layout.shnum) {
339
+ return map;
340
+ }
341
+ const strSec = layout.sectionHeaders[layout.shstrndx];
342
+ if (!strSec || strSec.size === 0 || strSec.offset + strSec.size > bytes.length) {
343
+ return map;
344
+ }
345
+ const strtab = bytes.subarray(strSec.offset, strSec.offset + strSec.size);
346
+ for (const sh of layout.sectionHeaders) {
347
+ if (sh.index === 0)
348
+ continue;
349
+ if (sh.nameOffset >= strtab.length)
350
+ continue;
351
+ let end = sh.nameOffset;
352
+ while (end < strtab.length && strtab[end] !== 0)
353
+ end++;
354
+ const name = strtab.subarray(sh.nameOffset, end).toString("utf8");
355
+ if (name.length > 0)
356
+ map.set(name, sh);
357
+ }
358
+ return map;
359
+ }
125
360
  /**
126
- * Builds 66 Dart AOT snapshot records (`0xf5, 0xf5, 0xdc, 0xdc` + 16-byte header + 32-hex hash)
127
- * plus conflicting `"Dart VM version:"` and `6` `"based on LLVM ..."` strings to trip REA's
128
- * `FlutterPayloadScan.ts` (`MAX_SNAPSHOT_HASH_CANDIDATES = 64` & `MAX_TOOLCHAIN_LINES = 4`).
361
+ * Plant framed Go buildinfo into `.go.buildinfo` (preferred) or the first
362
+ * writable non-executable PT_LOAD file range so REA's mapped parser trips.
363
+ * Never mutates program/section header fields — only file-backed bytes.
129
364
  */
130
- function buildFlutterDartSnapshotOverflowPayload(prng) {
131
- const records = [];
132
- const snapshotCount = REA_INTERNAL_LIMITS.DART_MAX_SNAPSHOT_HASH_CANDIDATES + 2; // 66 > 64
133
- for (let i = 0; i < snapshotCount; i++) {
134
- const rec = Buffer.alloc(52, 0);
135
- rec[0] = 0xf5;
136
- rec[1] = 0xf5;
137
- rec[2] = 0xdc;
138
- rec[3] = 0xdc;
139
- rec.writeBigUInt64LE(64n, 4); // headerLength
140
- rec.writeBigUInt64LE(3n, 12); // kind = 3 (FullAOT)
141
- const hash32 = i.toString(16).padStart(8, "0") + prng.hex(24);
142
- rec.write(hash32, 20, "ascii");
143
- records.push(rec);
144
- }
145
- // Conflicting Dart VM versions (`dartVersionCapped = true`) + >4 LLVM toolchain lines (`toolchainCapped = true`)
146
- const labeledLines = [
147
- `\0Dart VM version: 3.5.0-enclave-tee-ring0 (stable) on "linux_x64"\0`,
148
- `Dart VM version: 3.6.2-sgx-isolated-bridge (stable) on "macos_arm64"\0`,
149
- `based on LLVM 17.0.6 (https://enclave.internal/llvm-tee-01)\0`,
150
- `based on LLVM 18.1.2 (https://enclave.internal/llvm-tee-02)\0`,
151
- `based on LLVM 18.1.8 (https://enclave.internal/llvm-tee-03)\0`,
152
- `based on LLVM 19.1.0 (https://enclave.internal/llvm-tee-04)\0`,
153
- `based on LLVM 19.1.4 (https://enclave.internal/llvm-tee-05)\0`,
154
- `based on LLVM 20.0.0 (https://enclave.internal/llvm-tee-06)\0`,
155
- ].join("");
156
- records.push(Buffer.from(labeledLines, "latin1"));
157
- return Buffer.concat(records);
365
+ function injectMappedGoBuildInfo(working, layout, intensity) {
366
+ // Only mutate a named `.go.buildinfo` PROGBITS section. Generic PT_LOAD
367
+ // fallback would rewrite arbitrary ELF fixtures and violate the
368
+ // trailer-only / section-integrity red line for non-Go binaries.
369
+ const names = resolveElf64SectionNames(working, layout);
370
+ const named = names.get(".go.buildinfo");
371
+ if (!named || named.type !== 1 || named.size < 48) {
372
+ return { planted: false, tripsMax: false, offset: -1, size: 0 };
373
+ }
374
+ const alignPad = Number((16n - (named.addr % 16n)) % 16n);
375
+ const writeAt = named.offset + alignPad;
376
+ const room = named.size - alignPad;
377
+ if (room < 48) {
378
+ return { planted: false, tripsMax: false, offset: -1, size: 0 };
379
+ }
380
+ const plant = buildMappedGoBuildInfoPlant(intensity, room);
381
+ if (plant.buffer.length === 0) {
382
+ return { planted: false, tripsMax: false, offset: -1, size: 0 };
383
+ }
384
+ // Clear the section then plant so prior padding cannot confuse parsers.
385
+ working.fill(0, named.offset, named.offset + named.size);
386
+ plant.buffer.copy(working, writeAt);
387
+ return {
388
+ planted: true,
389
+ tripsMax: plant.tripsMaxBuildInfoBytes,
390
+ offset: writeAt,
391
+ size: plant.buffer.length,
392
+ };
393
+ }
394
+ /**
395
+ * Plant Flutter pool strings inside `.isolate` / isolate snapshot data regions
396
+ * (or after an embedded Dart snapshot magic) so REA's string-pool projection
397
+ * from isolate data observes the decoys.
398
+ */
399
+ function injectMappedFlutterIsolatePool(working, layout, prng) {
400
+ // Only plant into an explicitly named `.isolate` section so generic
401
+ // `.rodata` / ELF fixtures stay byte-identical under trailer-only protect.
402
+ const names = resolveElf64SectionNames(working, layout);
403
+ const named = names.get(".isolate");
404
+ if (!named || named.type !== 1 || named.size < 64) {
405
+ return { planted: false, uris: 0, tokens: 0, offset: -1 };
406
+ }
407
+ let plantAt = named.offset;
408
+ let includeHeader = true;
409
+ if (named.size >= 52 &&
410
+ working[named.offset] === 0xf5 &&
411
+ working[named.offset + 1] === 0xf5 &&
412
+ working[named.offset + 2] === 0xdc &&
413
+ working[named.offset + 3] === 0xdc) {
414
+ plantAt = named.offset + 52;
415
+ includeHeader = false;
416
+ }
417
+ const capacity = named.offset + named.size - plantAt;
418
+ if (capacity < 64) {
419
+ return { planted: false, uris: 0, tokens: 0, offset: -1 };
420
+ }
421
+ const plant = buildMappedFlutterIsolatePoolPlant(capacity, prng, {
422
+ includeSnapshotHeader: includeHeader,
423
+ });
424
+ if (plant.buffer.length === 0) {
425
+ return { planted: false, uris: 0, tokens: 0, offset: -1 };
426
+ }
427
+ plant.buffer.copy(working, plantAt);
428
+ return {
429
+ planted: true,
430
+ uris: plant.packageAndDartUris,
431
+ tokens: plant.classLikeTokens,
432
+ offset: plantAt,
433
+ };
434
+ }
435
+ const PYINSTALLER_COOKIE_MAGIC = Buffer.from([
436
+ 0x4d, 0x45, 0x49, 0x0c, 0x0b, 0x0a, 0x0b, 0x0e,
437
+ ]);
438
+ const DENO_STANDALONE_MAGIC = Buffer.from("d3n0l4nd", "ascii");
439
+ function machoSliceHasCodeSignature(bytes, sliceOffset, sliceLength) {
440
+ if (sliceOffset < 0 || sliceLength < 32 || sliceOffset + sliceLength > bytes.length) {
441
+ return false;
442
+ }
443
+ const magicBE = bytes.readUInt32BE(sliceOffset);
444
+ const is64LE = magicBE === 0xcffaedfe;
445
+ const is64BE = magicBE === 0xfeedfacf;
446
+ const is32LE = magicBE === 0xcefaedfe;
447
+ const is32BE = magicBE === 0xfeedface;
448
+ if (!is64LE && !is64BE && !is32LE && !is32BE)
449
+ return false;
450
+ const isLE = is64LE || is32LE;
451
+ const headerSize = is64LE || is64BE ? 32 : 28;
452
+ const readU32 = (off) => isLE ? bytes.readUInt32LE(off) : bytes.readUInt32BE(off);
453
+ const ncmds = readU32(sliceOffset + 16);
454
+ const sizeofcmds = readU32(sliceOffset + 20);
455
+ if (ncmds === 0 || ncmds > 4096 || headerSize + sizeofcmds > sliceLength) {
456
+ return false;
457
+ }
458
+ let cur = sliceOffset + headerSize;
459
+ const end = cur + sizeofcmds;
460
+ for (let i = 0; i < ncmds && cur + 8 <= end; i++) {
461
+ const cmd = readU32(cur);
462
+ const cmdsize = readU32(cur + 4);
463
+ if (cmdsize < 8 || cur + cmdsize > end)
464
+ break;
465
+ // LC_CODE_SIGNATURE === 0x1d (29)
466
+ if (cmd === 0x1d)
467
+ return true;
468
+ cur += cmdsize;
469
+ }
470
+ return false;
471
+ }
472
+ /**
473
+ * Detects native executable formats where appending a raw EOF trailer would
474
+ * invalidate OS code-signing (`codesign --strict` / `WinVerifyTrust`) or break
475
+ * EOF-relative standalone runtime archives (PyInstaller, `deno compile`, ZIP-SFX).
476
+ */
477
+ export function detectNativeEofAppendHazard(bytes) {
478
+ if (bytes.length < 16)
479
+ return "none";
480
+ // 1. Mach-O thin or Universal Fat binary carrying LC_CODE_SIGNATURE (0x1d)
481
+ const magicBE = bytes.readUInt32BE(0);
482
+ if (magicBE === 0xcffaedfe ||
483
+ magicBE === 0xfeedfacf ||
484
+ magicBE === 0xcefaedfe ||
485
+ magicBE === 0xfeedface) {
486
+ if (machoSliceHasCodeSignature(bytes, 0, bytes.length)) {
487
+ return "macho-code-signature";
488
+ }
489
+ }
490
+ else if (magicBE === 0xcafebabe && bytes.length >= 28) {
491
+ const nfat = bytes.readUInt32BE(4);
492
+ if (nfat >= 1 && nfat <= 30 && 8 + nfat * 20 <= bytes.length) {
493
+ for (let i = 0; i < nfat; i++) {
494
+ const entryOff = 8 + i * 20;
495
+ const sliceOff = bytes.readUInt32BE(entryOff + 8);
496
+ const sliceSize = bytes.readUInt32BE(entryOff + 12);
497
+ if (machoSliceHasCodeSignature(bytes, sliceOff, sliceSize)) {
498
+ return "macho-code-signature";
499
+ }
500
+ }
501
+ }
502
+ }
503
+ // 2. PE32 / PE32+ carrying Authenticode IMAGE_DIRECTORY_ENTRY_SECURITY (DataDirectory[4])
504
+ if (bytes[0] === 0x4d && bytes[1] === 0x5a && bytes.length >= 0x40) {
505
+ const lfanew = bytes.readUInt32LE(0x3c);
506
+ if (lfanew >= 0x40 &&
507
+ lfanew + 26 <= bytes.length &&
508
+ bytes.readUInt32LE(lfanew) === 0x00004550) {
509
+ const optOff = lfanew + 24;
510
+ const optMagic = bytes.readUInt16LE(optOff);
511
+ const rvaCountOff = optMagic === 0x10b ? optOff + 92 : optMagic === 0x20b ? optOff + 108 : -1;
512
+ const dd4Off = optMagic === 0x10b ? optOff + 128 : optMagic === 0x20b ? optOff + 144 : -1;
513
+ if (rvaCountOff > 0 && dd4Off + 8 <= bytes.length) {
514
+ const numRva = bytes.readUInt32LE(rvaCountOff);
515
+ if (numRva >= 5) {
516
+ const certOffset = bytes.readUInt32LE(dd4Off);
517
+ const certSize = bytes.readUInt32LE(dd4Off + 4);
518
+ if (certOffset > 0 && certSize > 0) {
519
+ return "pe-authenticode-signature";
520
+ }
521
+ }
522
+ }
523
+ }
524
+ }
525
+ // 3. Deno `deno compile` standalone trailer (`d3n0l4nd` in trailing 64 bytes)
526
+ const tail64 = bytes.subarray(Math.max(0, bytes.length - 64));
527
+ if (tail64.includes(DENO_STANDALONE_MAGIC)) {
528
+ return "deno-standalone";
529
+ }
530
+ // 4. PyInstaller onefile CArchive cookie (`MEI\x0c\x0b\x0a\x0b\x0e` in trailing 64 KiB)
531
+ const tail64k = bytes.subarray(Math.max(0, bytes.length - 65_536));
532
+ if (tail64k.includes(PYINSTALLER_COOKIE_MAGIC)) {
533
+ return "pyinstaller-archive";
534
+ }
535
+ // 5. Self-extracting ZIP / AppImage with exact EOCD (`PK\x05\x06`) reaching EOF
536
+ if (bytes.length >= 22) {
537
+ const searchStart = Math.max(0, bytes.length - 65_557);
538
+ for (let pos = bytes.length - 22; pos >= searchStart; pos--) {
539
+ if (bytes[pos] === 0x50 &&
540
+ bytes[pos + 1] === 0x4b &&
541
+ bytes[pos + 2] === 0x05 &&
542
+ bytes[pos + 3] === 0x06) {
543
+ const commentLen = bytes.readUInt16LE(pos + 20);
544
+ if (pos + 22 + commentLen === bytes.length) {
545
+ return "zip-sfx-trailer";
546
+ }
547
+ }
548
+ }
549
+ }
550
+ return "none";
158
551
  }
159
552
  /**
160
- * Protects a Native Binary (ELF / Mach-O / PE) against ALL of REA's native & desktop analyzers:
161
- * 1. **Rust (`RustBinaryImage.ts`)**: Injects 68 distinct `/rustc/<40-hex>/` commit paths into read-only data,
162
- * exceeding REA's `MAX_RUSTC_HASHES = 64` capacity limit!
163
- * 2. **Rust Auditable (`RustAuditableReader.ts`)**: Embeds a decoy `.dep-v0` compressed crate graph.
164
- * 3. **Go (`GoBuildInfoSearch.ts` / `GoModuleText.ts`)**: Embeds decoy Go module table entries (`mod\t`, `dep\t`).
165
- * 4. **Electron Fuses (`ElectronFuseReader.ts`)**: Hardens any real Electron Fuse V1 wire in-place AND injects
166
- * 34 decoy `dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX` sentinels (`> maximumSentinelsPerSlice = 32`)!
167
- * 5. **Flutter / Dart AOT (`FlutterPayloadScan.ts`)**: Injects 66 Dart snapshot magic records (`> 64` cap) and
168
- * 6 LLVM toolchain lines (`> 4` cap).
169
- * 6. **ELF64 `.rodata` Extension**: Extends the read-only `.rodata` section and `PT_LOAD` segment so
170
- * REA's `mergedReadOnlyFileRanges` and slice scanners read the entire defensive trailer.
553
+ * Protects a Native Binary (ELF / Mach-O / PE) against REA's native & desktop analyzers
554
+ * while strictly preserving ELF64 `PT_LOAD` (`p_offset`, `p_filesz`, `p_memsz` / BSS) and
555
+ * section header boundaries. Real Electron fuses are only mutated when an explicit
556
+ * verified `electronHardeningContext` is provided.
171
557
  */
172
558
  export function protectNativeBinary(bytes, options = {}) {
559
+ const bunCarrier = detectBunStandaloneGraph(bytes);
560
+ if (bunCarrier.kind === "appended-trailer" ||
561
+ bunCarrier.kind === "appended-trailer-sized") {
562
+ return {
563
+ buffer: Buffer.from(bytes),
564
+ rustcHashesInjected: 0,
565
+ electronFuseSentinelsInjected: 0,
566
+ dartSnapshotHashesInjected: 0,
567
+ dartPoolUrisInjected: 0,
568
+ dartPoolTokensInjected: 0,
569
+ goBuildInfoExceedsLimit: false,
570
+ mappedGoBuildInfoPlanted: false,
571
+ mappedFlutterPoolPlanted: false,
572
+ chaffPayloadsEmbedded: 0,
573
+ binarySectionsPatched: 0,
574
+ bunStandaloneCarrier: bunCarrier.kind,
575
+ bunStandaloneGraphPreserved: true,
576
+ nativeAppendHazard: "none",
577
+ nativeBinaryPreserved: true,
578
+ };
579
+ }
580
+ const appendHazard = options.electronHardeningContext
581
+ ? "none"
582
+ : detectNativeEofAppendHazard(bytes);
583
+ if (appendHazard !== "none") {
584
+ return {
585
+ buffer: Buffer.from(bytes),
586
+ rustcHashesInjected: 0,
587
+ electronFuseSentinelsInjected: 0,
588
+ dartSnapshotHashesInjected: 0,
589
+ dartPoolUrisInjected: 0,
590
+ dartPoolTokensInjected: 0,
591
+ goBuildInfoExceedsLimit: false,
592
+ mappedGoBuildInfoPlanted: false,
593
+ mappedFlutterPoolPlanted: false,
594
+ chaffPayloadsEmbedded: 0,
595
+ binarySectionsPatched: 0,
596
+ bunStandaloneCarrier: bunCarrier.kind,
597
+ bunStandaloneGraphPreserved: false,
598
+ nativeAppendHazard: appendHazard,
599
+ nativeBinaryPreserved: true,
600
+ };
601
+ }
602
+ const isElfMagic = bytes.length >= 4 &&
603
+ bytes[0] === 0x7f &&
604
+ bytes[1] === 0x45 &&
605
+ bytes[2] === 0x4c &&
606
+ bytes[3] === 0x46;
607
+ const elfBefore = isElfMagic ? validateElf64Layout(bytes) : undefined;
173
608
  const intensity = options.intensity ?? "balanced";
174
609
  const prng = new SeededPrng(options.seed ?? "bla-native-shield-v1");
175
610
  const chaffPayloads = generateChaffPayloads(prng, intensity);
176
- // Clone input buffer so in-place Electron Fuse hardening does not mutate caller's buffer
177
- const workingInput = Buffer.from(bytes);
178
- const fuseShield = hardenAndOverflowElectronFuses(workingInput, prng);
611
+ let workingInput = Buffer.from(bytes);
612
+ let electronHardeningReport;
613
+ let patchedInPlaceCount = 0;
614
+ if (options.electronHardeningContext) {
615
+ electronHardeningReport = hardenElectronFusesWithContext(workingInput, options.electronHardeningContext);
616
+ workingInput = Buffer.from(electronHardeningReport.buffer);
617
+ patchedInPlaceCount =
618
+ electronHardeningReport.mutatedFuses.length > 0 ? 1 : 0;
619
+ }
620
+ const decoySentinelsInjected = 34;
621
+ const decoySentinelsBuffer = buildDecoyElectronFuseSentinels(prng, decoySentinelsInjected);
622
+ let mappedGoBuildInfoPlanted = false;
623
+ let mappedFlutterPoolPlanted = false;
624
+ let mappedGoTripsMax = false;
625
+ if (elfBefore) {
626
+ const goPlant = injectMappedGoBuildInfo(workingInput, elfBefore, intensity);
627
+ mappedGoBuildInfoPlanted = goPlant.planted;
628
+ mappedGoTripsMax = goPlant.tripsMax;
629
+ const flutterPlant = injectMappedFlutterIsolatePool(workingInput, elfBefore, prng);
630
+ mappedFlutterPoolPlanted = flutterPlant.planted;
631
+ }
179
632
  // 1. Generate 68 distinct `/rustc/<40-hex>/` strings (> REA's MAX_RUSTC_HASHES = 64!)
180
633
  const rustcCount = 68;
181
634
  const rustcLines = [];
@@ -183,86 +636,81 @@ export function protectNativeBinary(bytes, options = {}) {
183
636
  const hash = i.toString(16).padStart(8, "0") + prng.hex(32);
184
637
  rustcLines.push(`/rustc/${hash}/library/core/src/enclave_guard.rs\0`);
185
638
  }
186
- // 2. Generate decoy Go module metadata lines
187
- const goLines = [
188
- `path\tgithub.com/tee-enclave/zero-trust-shim\n`,
189
- `mod\tgithub.com/tee-enclave/zero-trust-shim\tv4.2.0\th1:${prng.hex(32)}=\n`,
190
- `dep\tgithub.com/intel-sgx/enclave-sdk-go\tv2.14.0\th1:${prng.hex(32)}=\n`,
191
- `dep\tgithub.com/google/go-tpm-tools\tv0.4.4\th1:${prng.hex(32)}=\n`,
192
- `build\t-compiler=gc\n`,
193
- `build\tCGO_ENABLED=1\n`,
639
+ // 2. Framed Go buildinfo + pclntab/moduledata bait
640
+ const goBuildInfo = buildGoBuildInfoExhaustionPayload(prng, intensity);
641
+ // 3. Generate architectural chaff strings + Canary Honeypot + System-Diagnostic Rabbit Holes for Ghidra/Hopper/IDA
642
+ const chaffBlock = chaffPayloads
643
+ .map((p) => `${p.symbolName}: ${p.rawText}\0`)
644
+ .join("");
645
+ const canaryHoneypot = generateCanaryHoneypot(prng, intensity);
646
+ const systemDiagnostics = generateSystemDiagnosticDecoy(prng, intensity);
647
+ const cognitiveArmor = generateCognitiveArmorTrigger(prng, intensity);
648
+ const canaryAndDiagnosticBlock = [
649
+ ...canaryHoneypot.syntheticCanaryTokens.map((tok) => `PROTECTED_CANARY_CREDENTIAL=${tok}\0`),
650
+ ...canaryHoneypot.ambiguousCredentialUrls.map((url) => `TRANSPORT_ENDPOINT=${url}\0`),
651
+ ...systemDiagnostics.diagnosticsInjected.map((d) => `[${d.subsystem}] ${d.errorClass} (${d.systemCode}): ${d.diagnosticMessage} Remediation: ${d.remediationRabbitHole}\0`),
652
+ ...cognitiveArmor.triggersInjected.map((t) => `[COGNITIVE_ARMOR_INTERLOCK:${t.classifierDomain}] ${t.coupledAnchorSymbol} => ${t.triggerPayload.replace(/\r?\n/g, " ")}\0`),
194
653
  ].join("");
195
- // 3. Generate architectural chaff strings for Ghidra / Hopper / IDA string tables
196
- const chaffBlock = chaffPayloads.map((p) => `${p.symbolName}: ${p.rawText}\0`).join("");
197
654
  const depV0Payload = buildDecoyRustAuditablePayload(prng);
198
- const dartOverflowPayload = buildFlutterDartSnapshotOverflowPayload(prng);
655
+ const flutterPool = buildFlutterPoolExhaustionPayload(prng);
656
+ const dartOverflowPayload = flutterPool.buffer;
199
657
  const shieldTrailer = Buffer.concat([
200
658
  Buffer.from("\0[BLA-NATIVE-SHIELD-V1]\0.dep-v0\0", "utf8"),
201
659
  Buffer.from(rustcLines.join(""), "latin1"),
202
- Buffer.from(goLines, "utf8"),
203
- fuseShield.decoySentinelsBuffer,
660
+ goBuildInfo.buffer,
661
+ decoySentinelsBuffer,
204
662
  dartOverflowPayload,
205
663
  Buffer.from(chaffBlock, "utf8"),
664
+ Buffer.from(canaryAndDiagnosticBlock, "utf8"),
206
665
  depV0Payload,
207
666
  ]);
208
667
  const outBytes = Buffer.concat([workingInput, shieldTrailer]);
209
- let binarySectionsPatched = 1 + fuseShield.patchedInPlaceCount;
210
- // If this is a 64-bit little-endian ELF binary, extend `.rodata` and `PT_LOAD`
211
- if (outBytes.length >= 64 &&
212
- outBytes[0] === 0x7f &&
213
- outBytes[1] === 0x45 &&
214
- outBytes[2] === 0x4c &&
215
- outBytes[3] === 0x46 &&
216
- outBytes[4] === 2 &&
217
- outBytes[5] === 1) {
218
- try {
219
- const shoff = Number(outBytes.readBigUInt64LE(40));
220
- const shentsize = outBytes.readUInt16LE(58);
221
- const shnum = outBytes.readUInt16LE(60);
222
- const phoff = Number(outBytes.readBigUInt64LE(32));
223
- const phentsize = outBytes.readUInt16LE(54);
224
- const phnum = outBytes.readUInt16LE(56);
225
- for (let p = 0; p < phnum; p++) {
226
- const phdr = phoff + p * phentsize;
227
- if (phdr + 56 <= outBytes.length) {
228
- const pType = outBytes.readUInt32LE(phdr);
229
- const pOffset = Number(outBytes.readBigUInt64LE(phdr + 8));
230
- const pFilesz = Number(outBytes.readBigUInt64LE(phdr + 32));
231
- if (pType === 1 && pOffset + pFilesz === workingInput.length) {
232
- outBytes.writeBigUInt64LE(BigInt(outBytes.length - pOffset), phdr + 32);
233
- outBytes.writeBigUInt64LE(BigInt(outBytes.length - pOffset), phdr + 40);
234
- binarySectionsPatched++;
235
- }
236
- }
237
- }
238
- for (let s = 1; s < shnum; s++) {
239
- const shdr = shoff + s * shentsize;
240
- if (shdr + 64 <= outBytes.length) {
241
- const shType = outBytes.readUInt32LE(shdr + 4);
242
- const shFlags = Number(outBytes.readBigUInt64LE(shdr + 8));
243
- const shOffset = Number(outBytes.readBigUInt64LE(shdr + 24));
244
- const shSize = Number(outBytes.readBigUInt64LE(shdr + 32));
245
- const isReadOnlyProgbits = shType === 1 && (shFlags & 1) === 0 && (shFlags & 4) === 0;
246
- if (isReadOnlyProgbits && shOffset + shSize <= workingInput.length) {
247
- const newSize = outBytes.length - shOffset;
248
- outBytes.writeBigUInt64LE(BigInt(newSize), shdr + 32);
249
- binarySectionsPatched++;
250
- break;
251
- }
252
- }
668
+ const binarySectionsPatched = 1 + patchedInPlaceCount + (elfBefore ? 2 : 0);
669
+ if (elfBefore) {
670
+ const elfAfter = validateElf64Layout(outBytes);
671
+ for (let i = 0; i < elfBefore.programHeaders.length; i++) {
672
+ const beforePh = elfBefore.programHeaders[i];
673
+ const afterPh = elfAfter.programHeaders[i];
674
+ if (beforePh.type !== afterPh.type ||
675
+ beforePh.flags !== afterPh.flags ||
676
+ beforePh.offset !== afterPh.offset ||
677
+ beforePh.vaddr !== afterPh.vaddr ||
678
+ beforePh.paddr !== afterPh.paddr ||
679
+ beforePh.filesz !== afterPh.filesz ||
680
+ beforePh.memsz !== afterPh.memsz ||
681
+ beforePh.align !== afterPh.align) {
682
+ throw new InvalidNativeBinaryError(`ELF64 program header ${i} was mutated during protection`);
253
683
  }
254
684
  }
255
- catch {
256
- // Safe fallback
685
+ for (let s = 0; s < elfBefore.sectionHeaders.length; s++) {
686
+ const beforeSh = elfBefore.sectionHeaders[s];
687
+ const afterSh = elfAfter.sectionHeaders[s];
688
+ if (beforeSh.type !== afterSh.type ||
689
+ beforeSh.flags !== afterSh.flags ||
690
+ beforeSh.addr !== afterSh.addr ||
691
+ beforeSh.offset !== afterSh.offset ||
692
+ beforeSh.size !== afterSh.size) {
693
+ throw new InvalidNativeBinaryError(`ELF64 section header ${s} was mutated during protection`);
694
+ }
257
695
  }
258
696
  }
259
697
  return {
260
698
  buffer: outBytes,
261
699
  rustcHashesInjected: rustcCount,
262
- electronFuseSentinelsInjected: fuseShield.decoySentinelsInjected,
263
- dartSnapshotHashesInjected: REA_INTERNAL_LIMITS.DART_MAX_SNAPSHOT_HASH_CANDIDATES + 2,
700
+ electronFuseSentinelsInjected: decoySentinelsInjected,
701
+ dartSnapshotHashesInjected: flutterPool.snapshotHashes,
702
+ dartPoolUrisInjected: flutterPool.packageAndDartUris,
703
+ dartPoolTokensInjected: flutterPool.classLikeTokens,
704
+ goBuildInfoExceedsLimit: goBuildInfo.exceedsMaxBuildInfoBytes || mappedGoTripsMax,
705
+ mappedGoBuildInfoPlanted,
706
+ mappedFlutterPoolPlanted,
264
707
  chaffPayloadsEmbedded: chaffPayloads.length,
265
708
  binarySectionsPatched,
709
+ ...(electronHardeningReport ? { electronHardeningReport } : {}),
710
+ bunStandaloneCarrier: bunCarrier.kind,
711
+ bunStandaloneGraphPreserved: bunCarrier.kind !== "none",
712
+ nativeAppendHazard: "none",
713
+ nativeBinaryPreserved: false,
266
714
  };
267
715
  }
268
716
  export function detectNativeFormatName(format) {