bla-agents 1.1.0 → 1.5.3

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 (276) 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-plan.d.ts +68 -0
  40. package/dist/core/release-plan.d.ts.map +1 -0
  41. package/dist/core/release-plan.js +235 -0
  42. package/dist/core/release-plan.js.map +1 -0
  43. package/dist/core/sarif.d.ts +53 -0
  44. package/dist/core/sarif.d.ts.map +1 -0
  45. package/dist/core/sarif.js +91 -0
  46. package/dist/core/sarif.js.map +1 -0
  47. package/dist/core/sqlite-runtime.d.ts +13 -0
  48. package/dist/core/sqlite-runtime.d.ts.map +1 -1
  49. package/dist/core/sqlite-runtime.js +38 -8
  50. package/dist/core/sqlite-runtime.js.map +1 -1
  51. package/dist/core/types.d.ts +7 -2
  52. package/dist/core/types.d.ts.map +1 -1
  53. package/dist/engine/auditor.d.ts.map +1 -1
  54. package/dist/engine/auditor.js +251 -8
  55. package/dist/engine/auditor.js.map +1 -1
  56. package/dist/engine/benchmark.d.ts +1 -1
  57. package/dist/engine/benchmark.d.ts.map +1 -1
  58. package/dist/engine/benchmark.js +121 -41
  59. package/dist/engine/benchmark.js.map +1 -1
  60. package/dist/engine/defender.d.ts +1 -0
  61. package/dist/engine/defender.d.ts.map +1 -1
  62. package/dist/engine/defender.js +7 -1
  63. package/dist/engine/defender.js.map +1 -1
  64. package/dist/engine/harden.d.ts +61 -0
  65. package/dist/engine/harden.d.ts.map +1 -0
  66. package/dist/engine/harden.js +292 -0
  67. package/dist/engine/harden.js.map +1 -0
  68. package/dist/engine/protector.d.ts.map +1 -1
  69. package/dist/engine/protector.js +162 -21
  70. package/dist/engine/protector.js.map +1 -1
  71. package/dist/identity.d.ts +112 -2
  72. package/dist/identity.d.ts.map +1 -1
  73. package/dist/identity.js +112 -2
  74. package/dist/identity.js.map +1 -1
  75. package/dist/index.d.ts +26 -9
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +26 -9
  78. package/dist/index.js.map +1 -1
  79. package/dist/mcp/server.d.ts +59 -152
  80. package/dist/mcp/server.d.ts.map +1 -1
  81. package/dist/mcp/server.js +466 -50
  82. package/dist/mcp/server.js.map +1 -1
  83. package/dist/setup/clients.d.ts +49 -1
  84. package/dist/setup/clients.d.ts.map +1 -1
  85. package/dist/setup/clients.js +1193 -20
  86. package/dist/setup/clients.js.map +1 -1
  87. package/dist/setup/doctor.d.ts +58 -14
  88. package/dist/setup/doctor.d.ts.map +1 -1
  89. package/dist/setup/doctor.js +316 -22
  90. package/dist/setup/doctor.js.map +1 -1
  91. package/dist/setup/setup.d.ts +77 -7
  92. package/dist/setup/setup.d.ts.map +1 -1
  93. package/dist/setup/setup.js +591 -62
  94. package/dist/setup/setup.js.map +1 -1
  95. package/dist/shields/chaff/chaff-generator.d.ts.map +1 -1
  96. package/dist/shields/chaff/chaff-generator.js +12 -3
  97. package/dist/shields/chaff/chaff-generator.js.map +1 -1
  98. package/dist/shields/deception/architecture-mirage.js +1 -1
  99. package/dist/shields/deception/architecture-mirage.js.map +1 -1
  100. package/dist/shields/deception/canary-honeypot.d.ts +33 -0
  101. package/dist/shields/deception/canary-honeypot.d.ts.map +1 -0
  102. package/dist/shields/deception/canary-honeypot.js +95 -0
  103. package/dist/shields/deception/canary-honeypot.js.map +1 -0
  104. package/dist/shields/deception/cognitive-armor-trigger.d.ts +43 -0
  105. package/dist/shields/deception/cognitive-armor-trigger.d.ts.map +1 -0
  106. package/dist/shields/deception/cognitive-armor-trigger.js +204 -0
  107. package/dist/shields/deception/cognitive-armor-trigger.js.map +1 -0
  108. package/dist/shields/deception/crash-trace-decoy.js +1 -1
  109. package/dist/shields/deception/crash-trace-decoy.js.map +1 -1
  110. package/dist/shields/deception/decompiler-illusion.js +1 -1
  111. package/dist/shields/deception/decompiler-illusion.js.map +1 -1
  112. package/dist/shields/deception/diff-noise-injector.js +1 -1
  113. package/dist/shields/deception/diff-noise-injector.js.map +1 -1
  114. package/dist/shields/deception/evidence-contract-poison.js +1 -1
  115. package/dist/shields/deception/evidence-contract-poison.js.map +1 -1
  116. package/dist/shields/deception/format-payloads.d.ts +21 -0
  117. package/dist/shields/deception/format-payloads.d.ts.map +1 -0
  118. package/dist/shields/deception/format-payloads.js +24 -0
  119. package/dist/shields/deception/format-payloads.js.map +1 -0
  120. package/dist/shields/deception/index.d.ts +10 -2
  121. package/dist/shields/deception/index.d.ts.map +1 -1
  122. package/dist/shields/deception/index.js +20 -3
  123. package/dist/shields/deception/index.js.map +1 -1
  124. package/dist/shields/deception/prompt-completion-poison.d.ts +3 -2
  125. package/dist/shields/deception/prompt-completion-poison.d.ts.map +1 -1
  126. package/dist/shields/deception/prompt-completion-poison.js +6 -3
  127. package/dist/shields/deception/prompt-completion-poison.js.map +1 -1
  128. package/dist/shields/deception/shadow-business-logic.js +4 -4
  129. package/dist/shields/deception/shadow-business-logic.js.map +1 -1
  130. package/dist/shields/deception/system-diagnostic-decoy.d.ts +36 -0
  131. package/dist/shields/deception/system-diagnostic-decoy.d.ts.map +1 -0
  132. package/dist/shields/deception/system-diagnostic-decoy.js +101 -0
  133. package/dist/shields/deception/system-diagnostic-decoy.js.map +1 -0
  134. package/dist/shields/exhaustion/asar-header-amplifier.d.ts +12 -3
  135. package/dist/shields/exhaustion/asar-header-amplifier.d.ts.map +1 -1
  136. package/dist/shields/exhaustion/asar-header-amplifier.js +30 -8
  137. package/dist/shields/exhaustion/asar-header-amplifier.js.map +1 -1
  138. package/dist/shields/exhaustion/bpe-token-amplifier.js +2 -2
  139. package/dist/shields/exhaustion/bpe-token-amplifier.js.map +1 -1
  140. package/dist/shields/exhaustion/callgraph-labyrinth.js +2 -2
  141. package/dist/shields/exhaustion/callgraph-labyrinth.js.map +1 -1
  142. package/dist/shields/exhaustion/cdp-shape-budget-breaker.js +1 -1
  143. package/dist/shields/exhaustion/cdp-shape-budget-breaker.js.map +1 -1
  144. package/dist/shields/exhaustion/frida-capture-saturation.d.ts +10 -5
  145. package/dist/shields/exhaustion/frida-capture-saturation.d.ts.map +1 -1
  146. package/dist/shields/exhaustion/frida-capture-saturation.js +21 -8
  147. package/dist/shields/exhaustion/frida-capture-saturation.js.map +1 -1
  148. package/dist/shields/exhaustion/index.d.ts +2 -2
  149. package/dist/shields/exhaustion/index.d.ts.map +1 -1
  150. package/dist/shields/exhaustion/index.js +2 -2
  151. package/dist/shields/exhaustion/index.js.map +1 -1
  152. package/dist/shields/exhaustion/obligation-flooder.d.ts +17 -5
  153. package/dist/shields/exhaustion/obligation-flooder.d.ts.map +1 -1
  154. package/dist/shields/exhaustion/obligation-flooder.js +20 -8
  155. package/dist/shields/exhaustion/obligation-flooder.js.map +1 -1
  156. package/dist/shields/exhaustion/rea-budget-matrix.d.ts +8 -2
  157. package/dist/shields/exhaustion/rea-budget-matrix.d.ts.map +1 -1
  158. package/dist/shields/exhaustion/rea-budget-matrix.js +139 -16
  159. package/dist/shields/exhaustion/rea-budget-matrix.js.map +1 -1
  160. package/dist/shields/exhaustion/regex-worker-tarpit.d.ts.map +1 -1
  161. package/dist/shields/exhaustion/regex-worker-tarpit.js +2 -1
  162. package/dist/shields/exhaustion/regex-worker-tarpit.js.map +1 -1
  163. package/dist/shields/exhaustion/wasm-interface-exhaustion.d.ts +7 -4
  164. package/dist/shields/exhaustion/wasm-interface-exhaustion.d.ts.map +1 -1
  165. package/dist/shields/exhaustion/wasm-interface-exhaustion.js +16 -7
  166. package/dist/shields/exhaustion/wasm-interface-exhaustion.js.map +1 -1
  167. package/dist/shields/formats/android-dex-xref.d.ts +19 -0
  168. package/dist/shields/formats/android-dex-xref.d.ts.map +1 -0
  169. package/dist/shields/formats/android-dex-xref.js +427 -0
  170. package/dist/shields/formats/android-dex-xref.js.map +1 -0
  171. package/dist/shields/formats/android-manifest.d.ts +44 -0
  172. package/dist/shields/formats/android-manifest.d.ts.map +1 -0
  173. package/dist/shields/formats/android-manifest.js +240 -0
  174. package/dist/shields/formats/android-manifest.js.map +1 -0
  175. package/dist/shields/formats/android-r8.d.ts +44 -0
  176. package/dist/shields/formats/android-r8.d.ts.map +1 -0
  177. package/dist/shields/formats/android-r8.js +246 -0
  178. package/dist/shields/formats/android-r8.js.map +1 -0
  179. package/dist/shields/formats/apple-plist.d.ts +15 -0
  180. package/dist/shields/formats/apple-plist.d.ts.map +1 -1
  181. package/dist/shields/formats/apple-plist.js +59 -1
  182. package/dist/shields/formats/apple-plist.js.map +1 -1
  183. package/dist/shields/formats/archive.d.ts +27 -6
  184. package/dist/shields/formats/archive.d.ts.map +1 -1
  185. package/dist/shields/formats/archive.js +247 -45
  186. package/dist/shields/formats/archive.js.map +1 -1
  187. package/dist/shields/formats/asar.d.ts +50 -10
  188. package/dist/shields/formats/asar.d.ts.map +1 -1
  189. package/dist/shields/formats/asar.js +265 -39
  190. package/dist/shields/formats/asar.js.map +1 -1
  191. package/dist/shields/formats/bun-standalone.d.ts +78 -0
  192. package/dist/shields/formats/bun-standalone.d.ts.map +1 -0
  193. package/dist/shields/formats/bun-standalone.js +272 -0
  194. package/dist/shields/formats/bun-standalone.js.map +1 -0
  195. package/dist/shields/formats/dotnet-managed.d.ts +9 -0
  196. package/dist/shields/formats/dotnet-managed.d.ts.map +1 -1
  197. package/dist/shields/formats/dotnet-managed.js +26 -1
  198. package/dist/shields/formats/dotnet-managed.js.map +1 -1
  199. package/dist/shields/formats/electron-fuses.d.ts +63 -8
  200. package/dist/shields/formats/electron-fuses.d.ts.map +1 -1
  201. package/dist/shields/formats/electron-fuses.js +297 -65
  202. package/dist/shields/formats/electron-fuses.js.map +1 -1
  203. package/dist/shields/formats/erlang-beam.d.ts +34 -0
  204. package/dist/shields/formats/erlang-beam.d.ts.map +1 -0
  205. package/dist/shields/formats/erlang-beam.js +319 -0
  206. package/dist/shields/formats/erlang-beam.js.map +1 -0
  207. package/dist/shields/formats/evm-bytecode.d.ts +28 -0
  208. package/dist/shields/formats/evm-bytecode.d.ts.map +1 -0
  209. package/dist/shields/formats/evm-bytecode.js +124 -0
  210. package/dist/shields/formats/evm-bytecode.js.map +1 -0
  211. package/dist/shields/formats/go-flutter-exhaustion.d.ts +55 -0
  212. package/dist/shields/formats/go-flutter-exhaustion.d.ts.map +1 -0
  213. package/dist/shields/formats/go-flutter-exhaustion.js +346 -0
  214. package/dist/shields/formats/go-flutter-exhaustion.js.map +1 -0
  215. package/dist/shields/formats/gpu-ptx.d.ts +40 -0
  216. package/dist/shields/formats/gpu-ptx.d.ts.map +1 -0
  217. package/dist/shields/formats/gpu-ptx.js +62 -0
  218. package/dist/shields/formats/gpu-ptx.js.map +1 -0
  219. package/dist/shields/formats/headers.d.ts.map +1 -1
  220. package/dist/shields/formats/headers.js +54 -14
  221. package/dist/shields/formats/headers.js.map +1 -1
  222. package/dist/shields/formats/jvm-bytecode.d.ts +20 -0
  223. package/dist/shields/formats/jvm-bytecode.d.ts.map +1 -0
  224. package/dist/shields/formats/jvm-bytecode.js +134 -0
  225. package/dist/shields/formats/jvm-bytecode.js.map +1 -0
  226. package/dist/shields/formats/mobile-game.d.ts +4 -0
  227. package/dist/shields/formats/mobile-game.d.ts.map +1 -1
  228. package/dist/shields/formats/mobile-game.js +16 -0
  229. package/dist/shields/formats/mobile-game.js.map +1 -1
  230. package/dist/shields/formats/model.d.ts +22 -8
  231. package/dist/shields/formats/model.d.ts.map +1 -1
  232. package/dist/shields/formats/model.js +231 -59
  233. package/dist/shields/formats/model.js.map +1 -1
  234. package/dist/shields/formats/native.d.ts +65 -11
  235. package/dist/shields/formats/native.d.ts.map +1 -1
  236. package/dist/shields/formats/native.js +413 -108
  237. package/dist/shields/formats/native.js.map +1 -1
  238. package/dist/shields/formats/pcap-capture.d.ts +27 -0
  239. package/dist/shields/formats/pcap-capture.d.ts.map +1 -0
  240. package/dist/shields/formats/pcap-capture.js +201 -0
  241. package/dist/shields/formats/pcap-capture.js.map +1 -0
  242. package/dist/shields/formats/python.d.ts +22 -1
  243. package/dist/shields/formats/python.d.ts.map +1 -1
  244. package/dist/shields/formats/python.js +568 -27
  245. package/dist/shields/formats/python.js.map +1 -1
  246. package/dist/shields/formats/sourcemap.d.ts.map +1 -1
  247. package/dist/shields/formats/sourcemap.js +2 -0
  248. package/dist/shields/formats/sourcemap.js.map +1 -1
  249. package/dist/shields/formats/sqlite.d.ts +87 -15
  250. package/dist/shields/formats/sqlite.d.ts.map +1 -1
  251. package/dist/shields/formats/sqlite.js +377 -42
  252. package/dist/shields/formats/sqlite.js.map +1 -1
  253. package/dist/shields/formats/wasm.d.ts +6 -0
  254. package/dist/shields/formats/wasm.d.ts.map +1 -1
  255. package/dist/shields/formats/wasm.js +118 -3
  256. package/dist/shields/formats/wasm.js.map +1 -1
  257. package/dist/shields/javascript/ast-shield.d.ts +25 -5
  258. package/dist/shields/javascript/ast-shield.d.ts.map +1 -1
  259. package/dist/shields/javascript/ast-shield.js +428 -58
  260. package/dist/shields/javascript/ast-shield.js.map +1 -1
  261. package/dist/shields/runtime/memory-diff-shield.d.ts +56 -0
  262. package/dist/shields/runtime/memory-diff-shield.d.ts.map +1 -0
  263. package/dist/shields/runtime/memory-diff-shield.js +170 -0
  264. package/dist/shields/runtime/memory-diff-shield.js.map +1 -0
  265. package/dist/shields/runtime/runtime-shield.d.ts +12 -16
  266. package/dist/shields/runtime/runtime-shield.d.ts.map +1 -1
  267. package/dist/shields/runtime/runtime-shield.js +30 -24
  268. package/dist/shields/runtime/runtime-shield.js.map +1 -1
  269. package/dist/shields/tarpit/opaque-predicates.d.ts.map +1 -1
  270. package/dist/shields/tarpit/opaque-predicates.js +3 -3
  271. package/dist/shields/tarpit/opaque-predicates.js.map +1 -1
  272. package/dist/shields/tarpit/tarpit-generator.d.ts +9 -4
  273. package/dist/shields/tarpit/tarpit-generator.d.ts.map +1 -1
  274. package/dist/shields/tarpit/tarpit-generator.js +30 -23
  275. package/dist/shields/tarpit/tarpit-generator.js.map +1 -1
  276. 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,164 @@ 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);
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 };
144
373
  }
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);
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
+ };
158
434
  }
159
435
  /**
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.
436
+ * Protects a Native Binary (ELF / Mach-O / PE) against REA's native & desktop analyzers
437
+ * while strictly preserving ELF64 `PT_LOAD` (`p_offset`, `p_filesz`, `p_memsz` / BSS) and
438
+ * section header boundaries. Real Electron fuses are only mutated when an explicit
439
+ * verified `electronHardeningContext` is provided.
171
440
  */
172
441
  export function protectNativeBinary(bytes, options = {}) {
442
+ const bunCarrier = detectBunStandaloneGraph(bytes);
443
+ if (bunCarrier.kind === "appended-trailer" ||
444
+ bunCarrier.kind === "appended-trailer-sized") {
445
+ return {
446
+ buffer: Buffer.from(bytes),
447
+ rustcHashesInjected: 0,
448
+ electronFuseSentinelsInjected: 0,
449
+ dartSnapshotHashesInjected: 0,
450
+ dartPoolUrisInjected: 0,
451
+ dartPoolTokensInjected: 0,
452
+ goBuildInfoExceedsLimit: false,
453
+ mappedGoBuildInfoPlanted: false,
454
+ mappedFlutterPoolPlanted: false,
455
+ chaffPayloadsEmbedded: 0,
456
+ binarySectionsPatched: 0,
457
+ bunStandaloneCarrier: bunCarrier.kind,
458
+ bunStandaloneGraphPreserved: true,
459
+ };
460
+ }
461
+ const isElfMagic = bytes.length >= 4 &&
462
+ bytes[0] === 0x7f &&
463
+ bytes[1] === 0x45 &&
464
+ bytes[2] === 0x4c &&
465
+ bytes[3] === 0x46;
466
+ const elfBefore = isElfMagic ? validateElf64Layout(bytes) : undefined;
173
467
  const intensity = options.intensity ?? "balanced";
174
468
  const prng = new SeededPrng(options.seed ?? "bla-native-shield-v1");
175
469
  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);
470
+ let workingInput = Buffer.from(bytes);
471
+ let electronHardeningReport;
472
+ let patchedInPlaceCount = 0;
473
+ if (options.electronHardeningContext) {
474
+ electronHardeningReport = hardenElectronFusesWithContext(workingInput, options.electronHardeningContext);
475
+ workingInput = Buffer.from(electronHardeningReport.buffer);
476
+ patchedInPlaceCount =
477
+ electronHardeningReport.mutatedFuses.length > 0 ? 1 : 0;
478
+ }
479
+ const decoySentinelsInjected = 34;
480
+ const decoySentinelsBuffer = buildDecoyElectronFuseSentinels(prng, decoySentinelsInjected);
481
+ let mappedGoBuildInfoPlanted = false;
482
+ let mappedFlutterPoolPlanted = false;
483
+ let mappedGoTripsMax = false;
484
+ if (elfBefore) {
485
+ const goPlant = injectMappedGoBuildInfo(workingInput, elfBefore, intensity);
486
+ mappedGoBuildInfoPlanted = goPlant.planted;
487
+ mappedGoTripsMax = goPlant.tripsMax;
488
+ const flutterPlant = injectMappedFlutterIsolatePool(workingInput, elfBefore, prng);
489
+ mappedFlutterPoolPlanted = flutterPlant.planted;
490
+ }
179
491
  // 1. Generate 68 distinct `/rustc/<40-hex>/` strings (> REA's MAX_RUSTC_HASHES = 64!)
180
492
  const rustcCount = 68;
181
493
  const rustcLines = [];
@@ -183,86 +495,79 @@ export function protectNativeBinary(bytes, options = {}) {
183
495
  const hash = i.toString(16).padStart(8, "0") + prng.hex(32);
184
496
  rustcLines.push(`/rustc/${hash}/library/core/src/enclave_guard.rs\0`);
185
497
  }
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`,
498
+ // 2. Framed Go buildinfo + pclntab/moduledata bait
499
+ const goBuildInfo = buildGoBuildInfoExhaustionPayload(prng, intensity);
500
+ // 3. Generate architectural chaff strings + Canary Honeypot + System-Diagnostic Rabbit Holes for Ghidra/Hopper/IDA
501
+ const chaffBlock = chaffPayloads
502
+ .map((p) => `${p.symbolName}: ${p.rawText}\0`)
503
+ .join("");
504
+ const canaryHoneypot = generateCanaryHoneypot(prng, intensity);
505
+ const systemDiagnostics = generateSystemDiagnosticDecoy(prng, intensity);
506
+ const cognitiveArmor = generateCognitiveArmorTrigger(prng, intensity);
507
+ const canaryAndDiagnosticBlock = [
508
+ ...canaryHoneypot.syntheticCanaryTokens.map((tok) => `PROTECTED_CANARY_CREDENTIAL=${tok}\0`),
509
+ ...canaryHoneypot.ambiguousCredentialUrls.map((url) => `TRANSPORT_ENDPOINT=${url}\0`),
510
+ ...systemDiagnostics.diagnosticsInjected.map((d) => `[${d.subsystem}] ${d.errorClass} (${d.systemCode}): ${d.diagnosticMessage} Remediation: ${d.remediationRabbitHole}\0`),
511
+ ...cognitiveArmor.triggersInjected.map((t) => `[COGNITIVE_ARMOR_INTERLOCK:${t.classifierDomain}] ${t.coupledAnchorSymbol} => ${t.triggerPayload.replace(/\r?\n/g, " ")}\0`),
194
512
  ].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
513
  const depV0Payload = buildDecoyRustAuditablePayload(prng);
198
- const dartOverflowPayload = buildFlutterDartSnapshotOverflowPayload(prng);
514
+ const flutterPool = buildFlutterPoolExhaustionPayload(prng);
515
+ const dartOverflowPayload = flutterPool.buffer;
199
516
  const shieldTrailer = Buffer.concat([
200
517
  Buffer.from("\0[BLA-NATIVE-SHIELD-V1]\0.dep-v0\0", "utf8"),
201
518
  Buffer.from(rustcLines.join(""), "latin1"),
202
- Buffer.from(goLines, "utf8"),
203
- fuseShield.decoySentinelsBuffer,
519
+ goBuildInfo.buffer,
520
+ decoySentinelsBuffer,
204
521
  dartOverflowPayload,
205
522
  Buffer.from(chaffBlock, "utf8"),
523
+ Buffer.from(canaryAndDiagnosticBlock, "utf8"),
206
524
  depV0Payload,
207
525
  ]);
208
526
  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
- }
527
+ const binarySectionsPatched = 1 + patchedInPlaceCount + (elfBefore ? 2 : 0);
528
+ if (elfBefore) {
529
+ const elfAfter = validateElf64Layout(outBytes);
530
+ for (let i = 0; i < elfBefore.programHeaders.length; i++) {
531
+ const beforePh = elfBefore.programHeaders[i];
532
+ const afterPh = elfAfter.programHeaders[i];
533
+ if (beforePh.type !== afterPh.type ||
534
+ beforePh.flags !== afterPh.flags ||
535
+ beforePh.offset !== afterPh.offset ||
536
+ beforePh.vaddr !== afterPh.vaddr ||
537
+ beforePh.paddr !== afterPh.paddr ||
538
+ beforePh.filesz !== afterPh.filesz ||
539
+ beforePh.memsz !== afterPh.memsz ||
540
+ beforePh.align !== afterPh.align) {
541
+ throw new InvalidNativeBinaryError(`ELF64 program header ${i} was mutated during protection`);
253
542
  }
254
543
  }
255
- catch {
256
- // Safe fallback
544
+ for (let s = 0; s < elfBefore.sectionHeaders.length; s++) {
545
+ const beforeSh = elfBefore.sectionHeaders[s];
546
+ const afterSh = elfAfter.sectionHeaders[s];
547
+ if (beforeSh.type !== afterSh.type ||
548
+ beforeSh.flags !== afterSh.flags ||
549
+ beforeSh.addr !== afterSh.addr ||
550
+ beforeSh.offset !== afterSh.offset ||
551
+ beforeSh.size !== afterSh.size) {
552
+ throw new InvalidNativeBinaryError(`ELF64 section header ${s} was mutated during protection`);
553
+ }
257
554
  }
258
555
  }
259
556
  return {
260
557
  buffer: outBytes,
261
558
  rustcHashesInjected: rustcCount,
262
- electronFuseSentinelsInjected: fuseShield.decoySentinelsInjected,
263
- dartSnapshotHashesInjected: REA_INTERNAL_LIMITS.DART_MAX_SNAPSHOT_HASH_CANDIDATES + 2,
559
+ electronFuseSentinelsInjected: decoySentinelsInjected,
560
+ dartSnapshotHashesInjected: flutterPool.snapshotHashes,
561
+ dartPoolUrisInjected: flutterPool.packageAndDartUris,
562
+ dartPoolTokensInjected: flutterPool.classLikeTokens,
563
+ goBuildInfoExceedsLimit: goBuildInfo.exceedsMaxBuildInfoBytes || mappedGoTripsMax,
564
+ mappedGoBuildInfoPlanted,
565
+ mappedFlutterPoolPlanted,
264
566
  chaffPayloadsEmbedded: chaffPayloads.length,
265
567
  binarySectionsPatched,
568
+ ...(electronHardeningReport ? { electronHardeningReport } : {}),
569
+ bunStandaloneCarrier: bunCarrier.kind,
570
+ bunStandaloneGraphPreserved: bunCarrier.kind !== "none",
266
571
  };
267
572
  }
268
573
  export function detectNativeFormatName(format) {