rea-agents 2.0.0 → 2.1.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 (246) hide show
  1. package/README.md +78 -32
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +24 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +1 -23
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +156 -238
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  26. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  27. package/dist/application/EnhancedToolPagination.js +22 -0
  28. package/dist/application/EnhancedToolTypes.js +4 -0
  29. package/dist/application/EnhancedTools.js +20 -37
  30. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  31. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  32. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  33. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  34. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  35. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  36. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  37. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  38. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  39. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  40. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  41. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  42. package/dist/application/JavaScriptJsonModules.js +39 -0
  43. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  44. package/dist/application/JavaScriptReplayPermission.js +16 -0
  45. package/dist/application/JavaScriptReplayService.js +182 -156
  46. package/dist/application/LinuxHopper.js +10 -0
  47. package/dist/application/MacHopper.js +22 -11
  48. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  49. package/dist/application/PermissionAuthority.js +106 -63
  50. package/dist/application/ProcessCaptureCapability.js +1 -1
  51. package/dist/application/ProcessCapturePermission.js +13 -0
  52. package/dist/application/ProcessCli.js +2 -12
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProjectPermissionStore.js +48 -9
  55. package/dist/application/RealHopperAssertions.js +76 -0
  56. package/dist/application/ReconstructionCoverageService.js +69 -0
  57. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  58. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  59. package/dist/application/Setup.js +147 -259
  60. package/dist/application/SetupClientConfiguration.js +220 -0
  61. package/dist/application/SetupClients.js +24 -2
  62. package/dist/application/SetupPlan.js +123 -12
  63. package/dist/application/SetupSkill.js +26 -12
  64. package/dist/application/SupportedClients.js +1 -0
  65. package/dist/application/Uninstall.js +6 -3
  66. package/dist/application/WindowsCapabilities.js +86 -0
  67. package/dist/artifacts/AsarArtifactReader.js +11 -0
  68. package/dist/browser/BrowserProcessStartup.js +88 -0
  69. package/dist/browser/CdpCaptureDocuments.js +12 -8
  70. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  71. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  72. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  73. package/dist/browser/CdpCaptureEventState.js +1 -0
  74. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  75. package/dist/browser/CdpCaptureEvents.js +29 -496
  76. package/dist/browser/CdpObservationSession.js +51 -8
  77. package/dist/browser/CdpPageCapture.js +12 -133
  78. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  79. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  80. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  81. package/dist/browser/PngVisualDiff.js +9 -2
  82. package/dist/catalogIdentity.js +4 -0
  83. package/dist/cli/artifactCommands.js +82 -0
  84. package/dist/cli/coreAnalysisCommands.js +232 -0
  85. package/dist/cli/managedCommands.js +397 -0
  86. package/dist/cli/managedProjectGraphCommand.js +24 -0
  87. package/dist/cli/options.js +9 -0
  88. package/dist/cli/setupCommands.js +108 -0
  89. package/dist/cli/types.js +1 -0
  90. package/dist/cli/utilityCommands.js +122 -0
  91. package/dist/cli.js +10 -768
  92. package/dist/cliApplicationCommands.js +118 -4
  93. package/dist/cliBrowserAdvancedCommands.js +73 -16
  94. package/dist/cliBrowserCommands.js +39 -115
  95. package/dist/cliCommandNames.js +4 -0
  96. package/dist/cliElectronCommands.js +33 -62
  97. package/dist/cliEvidenceCommands.js +13 -2
  98. package/dist/cliInvestigationCommands.js +53 -10
  99. package/dist/cliObservationOptions.js +137 -0
  100. package/dist/cliPolicyCommands.js +80 -46
  101. package/dist/cliSetup.js +289 -0
  102. package/dist/config/environment.js +107 -0
  103. package/dist/config/parseConfig.js +228 -0
  104. package/dist/config/parsers.js +68 -0
  105. package/dist/config/permissions.js +30 -0
  106. package/dist/config/types.js +1 -0
  107. package/dist/config.js +1 -375
  108. package/dist/contracts/applicationToolContracts.js +134 -0
  109. package/dist/contracts/managedToolContracts.js +1 -1
  110. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  111. package/dist/contracts/providerSelection.js +2 -0
  112. package/dist/contracts/toolContracts.js +2 -2
  113. package/dist/contracts/toolEffects.js +14 -0
  114. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  115. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  116. package/dist/contracts/toolOutputSchemas.js +2 -550
  117. package/dist/domain/analysisErrorPresentation.js +234 -0
  118. package/dist/domain/analysisErrorProjection.js +284 -0
  119. package/dist/domain/artifactComparison.js +34 -15
  120. package/dist/domain/binaryTarget.js +87 -37
  121. package/dist/domain/browserObservation.js +1 -285
  122. package/dist/domain/browserObservationSchemas.js +286 -0
  123. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  124. package/dist/domain/errors.js +4 -486
  125. package/dist/domain/functionComparison.js +4 -165
  126. package/dist/domain/functionComparisonDimensions.js +164 -0
  127. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  128. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  129. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  130. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  131. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  132. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  133. package/dist/domain/javascriptSemanticIr.js +30 -0
  134. package/dist/domain/javascriptSemanticProjection.js +366 -0
  135. package/dist/domain/javascriptSemanticState.js +40 -0
  136. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  137. package/dist/domain/javascriptSemanticValues.js +352 -0
  138. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  139. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  140. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  141. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  142. package/dist/domain/knownPageCoverage.js +21 -0
  143. package/dist/domain/managedApplicationGraph.js +14 -364
  144. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  145. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  146. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  147. package/dist/domain/managedArtifact.js +16 -8
  148. package/dist/domain/managedMemberComparison.js +37 -391
  149. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  150. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  151. package/dist/domain/managedNativeVerification.js +27 -389
  152. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  153. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  154. package/dist/domain/managedReconstruction.js +82 -69
  155. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  156. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  157. package/dist/domain/permissionPolicy.js +2 -0
  158. package/dist/domain/reconstructionCoverage.js +387 -0
  159. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  160. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  161. package/dist/domain/runtimeCharacterization.js +85 -0
  162. package/dist/domain/webBundleAnalyzer.js +3 -409
  163. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  164. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  165. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  166. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  167. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  168. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  169. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  170. package/dist/dotnet/ManagedMemberRows.js +120 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  172. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  173. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  174. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  175. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  176. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  177. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  178. package/dist/dotnet/ManagedPeReader.js +59 -28
  179. package/dist/generatedPackageMetadata.js +2 -2
  180. package/dist/ghidra/GhidraClient.js +76 -91
  181. package/dist/ghidra/GhidraClientStartup.js +29 -0
  182. package/dist/ghidra/GhidraClientWire.js +34 -0
  183. package/dist/ghidra/GhidraDefaults.js +1 -1
  184. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  185. package/dist/ghidra/GhidraInstallation.js +20 -15
  186. package/dist/ghidra/GhidraLauncher.js +93 -29
  187. package/dist/ghidra/GhidraProvider.js +61 -161
  188. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  189. package/dist/ghidra/GhidraSessionValues.js +2 -0
  190. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  191. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  192. package/dist/ghidra/GhidraTransport.js +71 -0
  193. package/dist/identity.js +3 -2
  194. package/dist/main/messages.js +5 -0
  195. package/dist/main/reload.js +49 -0
  196. package/dist/main/shutdown.js +25 -0
  197. package/dist/main/startup.js +14 -0
  198. package/dist/main/state.js +26 -0
  199. package/dist/main/transport.js +61 -0
  200. package/dist/main/types.js +1 -0
  201. package/dist/main.js +35 -146
  202. package/dist/process/PrivateRuntimeRoot.js +3 -2
  203. package/dist/process/ProcessOwnership.js +35 -0
  204. package/dist/process/ProviderProcess.js +2 -0
  205. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  206. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  207. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  208. package/dist/replay/ReplayOutcome.js +95 -0
  209. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  210. package/dist/server/ProcessCaptureElicitation.js +157 -0
  211. package/dist/server/createServer.js +119 -54
  212. package/dist/server/registerApplicationTools/characterization.js +57 -0
  213. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  214. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  215. package/dist/server/registerApplicationTools/coverage.js +84 -0
  216. package/dist/server/registerApplicationTools/helpers.js +42 -0
  217. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  218. package/dist/server/registerApplicationTools/types.js +1 -0
  219. package/dist/server/registerApplicationTools.js +10 -112
  220. package/dist/server/registerBrowserTools.js +59 -83
  221. package/dist/server/registerElectronTools.js +31 -46
  222. package/dist/server/registerEnhancedTools.js +34 -42
  223. package/dist/server/registerEvidenceResources.js +54 -0
  224. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  225. package/dist/server/registerInvestigationTools/types.js +1 -0
  226. package/dist/server/registerInvestigationTools.js +83 -116
  227. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  228. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  229. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  230. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  231. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  232. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  233. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  234. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  235. package/dist/server/registerManagedWorkflowTools.js +10 -274
  236. package/dist/server/registerOfficialTools.js +73 -59
  237. package/dist/server/registerSessionRecordTools.js +137 -0
  238. package/dist/server/registerSessionStatusTool.js +2 -1
  239. package/dist/server/registerSessionTools.js +60 -164
  240. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  241. package/dist/server/toolRegistrationOptions.js +101 -3
  242. package/dist/server/toolResult.js +5 -0
  243. package/package.json +10 -11
  244. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +20 -7
  245. package/scripts/prepare-node-pty.mjs +0 -35
  246. package/scripts/rebuild-native.mjs +0 -22
@@ -0,0 +1,107 @@
1
+ import { z } from "zod";
2
+ import { isAbsolute } from "node:path";
3
+ import { ConfigurationError } from "../domain/errors.js";
4
+ import { err, ok } from "../domain/result.js";
5
+ import { analysisProviderSelectorSchema } from "../contracts/providerSelection.js";
6
+ const environmentSchema = z
7
+ .object({
8
+ REA_ANALYSIS_PROVIDER: analysisProviderSelectorSchema.default("auto"),
9
+ GHIDRA_INSTALL_DIR: z
10
+ .string()
11
+ .min(1)
12
+ .refine(isAbsolute, "GHIDRA_INSTALL_DIR must be absolute")
13
+ .optional(),
14
+ JAVA_HOME: z
15
+ .string()
16
+ .min(1)
17
+ .refine(isAbsolute, "JAVA_HOME must be absolute")
18
+ .optional(),
19
+ REA_ILSPY_CMD_PATH: z
20
+ .string()
21
+ .min(1)
22
+ .refine(isAbsolute, "REA_ILSPY_CMD_PATH must be absolute")
23
+ .optional(),
24
+ HOPPER_LAUNCHER_PATH: z.string().min(1).optional(),
25
+ HOPPER_TARGET_PATH: z.string().min(1).optional(),
26
+ HOPPER_TARGET_KIND: z
27
+ .enum(["executable", "database"])
28
+ .default("executable"),
29
+ HOPPER_LOADER_ARGS_JSON: z.string().optional(),
30
+ REA_LOG_LEVEL: z
31
+ .enum(["trace", "debug", "info", "warn", "error", "fatal", "silent"])
32
+ .default("info"),
33
+ REA_PROCESS_CAPTURE_ENABLED: z.enum(["true", "false"]).default("false"),
34
+ REA_PROCESS_CAPTURE_AUTO_GRANT: z.enum(["true", "false"]).default("true"),
35
+ REA_ARTIFACT_NATIVE_MOUNT_ENABLED: z
36
+ .enum(["true", "false"])
37
+ .default("false"),
38
+ REA_ARTIFACT_INTEGRITY_CONTINUE_ENABLED: z
39
+ .enum(["true", "false"])
40
+ .default("false"),
41
+ REA_PROCESS_ALLOW_EXTERNAL_NETWORK: z
42
+ .enum(["true", "false"])
43
+ .default("false"),
44
+ REA_PROCESS_EXECUTABLE_ROOTS_JSON: z.string().default("[]"),
45
+ REA_PROCESS_WORKING_ROOTS_JSON: z.string().default("[]"),
46
+ REA_PROCESS_ALLOWED_ENV_JSON: z.string().default("[]"),
47
+ REA_EVIDENCE_ROOTS_JSON: z.string().default("[]"),
48
+ REA_INVESTIGATION_INPUT_ROOTS_JSON: z.string().default("[]"),
49
+ REA_ANALYSIS_SNAPSHOT_ROOTS_JSON: z.string().default("[]"),
50
+ REA_REFERENCE_ROOTS_JSON: z.string().default("[]"),
51
+ REA_REFERENCE_SECRET_PATTERNS_JSON: z.string().default("[]"),
52
+ REA_BROWSER_OBSERVE_ENABLED: z.enum(["true", "false"]).default("false"),
53
+ REA_BROWSER_CDP_ENDPOINTS_JSON: z.string().default("[]"),
54
+ REA_BROWSER_ALLOWED_ORIGINS_JSON: z.string().default("[]"),
55
+ REA_ELECTRON_OBSERVE_ENABLED: z.enum(["true", "false"]).default("false"),
56
+ REA_ELECTRON_CDP_ENDPOINTS_JSON: z.string().default("[]"),
57
+ REA_ELECTRON_FILE_ROOTS_JSON: z.string().default("[]"),
58
+ REA_JAVASCRIPT_REPLAY_ENABLED: z.enum(["true", "false"]).default("false"),
59
+ REA_JAVASCRIPT_REPLAY_ROOTS_JSON: z.string().default("[]"),
60
+ REA_JAVASCRIPT_REPLAY_NODE_PATH: z
61
+ .string()
62
+ .min(1)
63
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_NODE_PATH must be absolute")
64
+ .default(process.execPath),
65
+ REA_JAVASCRIPT_REPLAY_BWRAP_PATH: z
66
+ .string()
67
+ .min(1)
68
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_BWRAP_PATH must be absolute")
69
+ .default("/usr/bin/bwrap"),
70
+ REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH: z
71
+ .string()
72
+ .min(1)
73
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH must be absolute")
74
+ .default("/usr/bin/systemd-run"),
75
+ REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH: z
76
+ .string()
77
+ .min(1)
78
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH must be absolute")
79
+ .default("/usr/bin/systemctl"),
80
+ REA_JAVASCRIPT_REPLAY_SHELL_PATH: z
81
+ .string()
82
+ .min(1)
83
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SHELL_PATH must be absolute")
84
+ .default("/usr/bin/bash"),
85
+ REA_MANAGED_RUNTIME_ENABLED: z.enum(["true", "false"]).default("false"),
86
+ REA_MANAGED_RUNTIME_ROOTS_JSON: z.string().default("[]"),
87
+ REA_MANAGED_RUNTIME_EXECUTABLE_PATH: z
88
+ .string()
89
+ .min(1)
90
+ .refine(isAbsolute, "REA_MANAGED_RUNTIME_EXECUTABLE_PATH must be absolute")
91
+ .default("/usr/bin/dotnet"),
92
+ REA_PERMISSION_PROJECT_ROOT: z.string().min(1).optional(),
93
+ REA_PERMISSION_PROJECT_STORE: z.string().min(1).optional(),
94
+ })
95
+ .refine((value) => (value.REA_PERMISSION_PROJECT_ROOT === undefined) ===
96
+ (value.REA_PERMISSION_PROJECT_STORE === undefined), {
97
+ message: "REA_PERMISSION_PROJECT_ROOT and REA_PERMISSION_PROJECT_STORE must be configured together",
98
+ });
99
+ export const parseEnvironment = (environment) => {
100
+ const parsed = environmentSchema.safeParse(environment);
101
+ if (!parsed.success) {
102
+ return err(new ConfigurationError("Invalid REA environment configuration", {
103
+ cause: parsed.error,
104
+ }));
105
+ }
106
+ return ok(parsed.data);
107
+ };
@@ -0,0 +1,228 @@
1
+ import { isAbsolute } from "node:path";
2
+ import { ConfigurationError } from "../domain/errors.js";
3
+ import { err, ok } from "../domain/result.js";
4
+ import { parseEnvironment } from "./environment.js";
5
+ import { parseStringArray, parseBrowserArray, parseElectronFileRoots, parseLoaderArgs, } from "./parsers.js";
6
+ import { filePolicy, permissionScope, administratorGrants, browserNetworkScope, } from "./permissions.js";
7
+ import { browserEndpointSchema, browserOriginSchema, } from "../domain/browserObservation.js";
8
+ const DEFAULT_HOPPER_LAUNCHER_PATH = "/Applications/Hopper Disassembler.app/Contents/MacOS/hopper";
9
+ const defaultHopperLauncherPath = () => process.platform === "linux"
10
+ ? "/opt/hopper/bin/Hopper"
11
+ : DEFAULT_HOPPER_LAUNCHER_PATH;
12
+ const parseAllArrays = (env) => {
13
+ const loaderArgs = parseLoaderArgs(env.HOPPER_LOADER_ARGS_JSON);
14
+ if (!loaderArgs.ok)
15
+ return loaderArgs;
16
+ const executableRoots = parseStringArray(env.REA_PROCESS_EXECUTABLE_ROOTS_JSON, "REA_PROCESS_EXECUTABLE_ROOTS_JSON");
17
+ if (!executableRoots.ok)
18
+ return executableRoots;
19
+ const workingRoots = parseStringArray(env.REA_PROCESS_WORKING_ROOTS_JSON, "REA_PROCESS_WORKING_ROOTS_JSON");
20
+ if (!workingRoots.ok)
21
+ return workingRoots;
22
+ const allowedEnvironment = parseStringArray(env.REA_PROCESS_ALLOWED_ENV_JSON, "REA_PROCESS_ALLOWED_ENV_JSON");
23
+ if (!allowedEnvironment.ok)
24
+ return allowedEnvironment;
25
+ const evidenceRoots = parseStringArray(env.REA_EVIDENCE_ROOTS_JSON, "REA_EVIDENCE_ROOTS_JSON");
26
+ if (!evidenceRoots.ok)
27
+ return evidenceRoots;
28
+ const investigationInputRoots = parseStringArray(env.REA_INVESTIGATION_INPUT_ROOTS_JSON, "REA_INVESTIGATION_INPUT_ROOTS_JSON");
29
+ if (!investigationInputRoots.ok)
30
+ return investigationInputRoots;
31
+ const analysisSnapshotRoots = parseStringArray(env.REA_ANALYSIS_SNAPSHOT_ROOTS_JSON, "REA_ANALYSIS_SNAPSHOT_ROOTS_JSON");
32
+ if (!analysisSnapshotRoots.ok)
33
+ return analysisSnapshotRoots;
34
+ const referenceRoots = parseStringArray(env.REA_REFERENCE_ROOTS_JSON, "REA_REFERENCE_ROOTS_JSON");
35
+ if (!referenceRoots.ok)
36
+ return referenceRoots;
37
+ const secretPatterns = parseStringArray(env.REA_REFERENCE_SECRET_PATTERNS_JSON, "REA_REFERENCE_SECRET_PATTERNS_JSON");
38
+ if (!secretPatterns.ok)
39
+ return secretPatterns;
40
+ const browserEndpoints = parseBrowserArray(env.REA_BROWSER_CDP_ENDPOINTS_JSON, "REA_BROWSER_CDP_ENDPOINTS_JSON", browserEndpointSchema, 16);
41
+ if (!browserEndpoints.ok)
42
+ return browserEndpoints;
43
+ const browserOrigins = parseBrowserArray(env.REA_BROWSER_ALLOWED_ORIGINS_JSON, "REA_BROWSER_ALLOWED_ORIGINS_JSON", browserOriginSchema, 32);
44
+ if (!browserOrigins.ok)
45
+ return browserOrigins;
46
+ const electronEndpoints = parseBrowserArray(env.REA_ELECTRON_CDP_ENDPOINTS_JSON, "REA_ELECTRON_CDP_ENDPOINTS_JSON", browserEndpointSchema, 16);
47
+ if (!electronEndpoints.ok)
48
+ return electronEndpoints;
49
+ const electronFileRoots = parseElectronFileRoots(env.REA_ELECTRON_FILE_ROOTS_JSON);
50
+ if (!electronFileRoots.ok)
51
+ return electronFileRoots;
52
+ const javascriptReplayRoots = parseAbsoluteRoots(env.REA_JAVASCRIPT_REPLAY_ROOTS_JSON, "REA_JAVASCRIPT_REPLAY_ROOTS_JSON");
53
+ if (!javascriptReplayRoots.ok)
54
+ return javascriptReplayRoots;
55
+ const managedRuntimeRoots = parseAbsoluteRoots(env.REA_MANAGED_RUNTIME_ROOTS_JSON, "REA_MANAGED_RUNTIME_ROOTS_JSON");
56
+ if (!managedRuntimeRoots.ok)
57
+ return managedRuntimeRoots;
58
+ return ok({
59
+ loaderArgs: loaderArgs.value,
60
+ executableRoots: executableRoots.value,
61
+ workingRoots: workingRoots.value,
62
+ allowedEnvironment: allowedEnvironment.value,
63
+ evidenceRoots: evidenceRoots.value,
64
+ investigationInputRoots: investigationInputRoots.value,
65
+ analysisSnapshotRoots: analysisSnapshotRoots.value,
66
+ referenceRoots: referenceRoots.value,
67
+ secretPatterns: secretPatterns.value,
68
+ browserEndpoints: browserEndpoints.value,
69
+ browserOrigins: browserOrigins.value,
70
+ electronEndpoints: electronEndpoints.value,
71
+ electronFileRoots: electronFileRoots.value,
72
+ javascriptReplayRoots: javascriptReplayRoots.value,
73
+ managedRuntimeRoots: managedRuntimeRoots.value,
74
+ });
75
+ };
76
+ const parseAbsoluteRoots = (value, name) => {
77
+ const parsed = parseStringArray(value, name);
78
+ if (!parsed.ok)
79
+ return parsed;
80
+ return parsed.value.some((root) => !isAbsolute(root))
81
+ ? err(new ConfigurationError(`${name} must encode absolute roots`))
82
+ : parsed;
83
+ };
84
+ const appendProcessCaptureCeiling = (ceilings, env, arrays) => {
85
+ if (env.REA_PROCESS_CAPTURE_ENABLED !== "true")
86
+ return;
87
+ ceilings.push(permissionScope("process_capture", arrays.workingRoots, {
88
+ executables: arrays.executableRoots,
89
+ environment_names: arrays.allowedEnvironment,
90
+ network: env.REA_PROCESS_ALLOW_EXTERNAL_NETWORK === "true" ? "external" : "none",
91
+ }));
92
+ };
93
+ const appendBrowserObservationCeiling = (ceilings, env, arrays) => {
94
+ if (env.REA_BROWSER_OBSERVE_ENABLED !== "true")
95
+ return;
96
+ ceilings.push(permissionScope("browser_observe", [], {
97
+ origins: [...arrays.browserEndpoints, ...arrays.browserOrigins],
98
+ network: browserNetworkScope(arrays.browserOrigins),
99
+ }));
100
+ };
101
+ const appendElectronObservationCeiling = (ceilings, env, arrays) => {
102
+ if (env.REA_ELECTRON_OBSERVE_ENABLED !== "true")
103
+ return;
104
+ ceilings.push(permissionScope("electron_observe", arrays.electronFileRoots, {
105
+ origins: arrays.electronEndpoints,
106
+ network: "loopback",
107
+ }));
108
+ };
109
+ const appendNativeMountCeiling = (ceilings, env) => {
110
+ if (env.REA_ARTIFACT_NATIVE_MOUNT_ENABLED === "true")
111
+ ceilings.push(permissionScope("native_mount", [], { mount: true }));
112
+ };
113
+ const appendJavaScriptReplayCeiling = (ceilings, env, arrays) => {
114
+ if (env.REA_JAVASCRIPT_REPLAY_ENABLED !== "true")
115
+ return;
116
+ ceilings.push(permissionScope("javascript_replay", arrays.javascriptReplayRoots, {
117
+ executables: [
118
+ env.REA_JAVASCRIPT_REPLAY_NODE_PATH,
119
+ env.REA_JAVASCRIPT_REPLAY_BWRAP_PATH,
120
+ env.REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH,
121
+ env.REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH,
122
+ env.REA_JAVASCRIPT_REPLAY_SHELL_PATH,
123
+ ],
124
+ network: "none",
125
+ mount: true,
126
+ }));
127
+ };
128
+ const appendManagedRuntimeCeiling = (ceilings, env, arrays) => {
129
+ if (env.REA_MANAGED_RUNTIME_ENABLED !== "true")
130
+ return;
131
+ ceilings.push(permissionScope("managed_runtime", arrays.managedRuntimeRoots, {
132
+ executables: [env.REA_MANAGED_RUNTIME_EXECUTABLE_PATH],
133
+ network: "none",
134
+ }));
135
+ };
136
+ const buildPermissionCeilings = (env, arrays) => {
137
+ const ceilings = [
138
+ permissionScope("evidence_read", arrays.evidenceRoots),
139
+ permissionScope("evidence_write", arrays.evidenceRoots),
140
+ permissionScope("investigation_input", arrays.investigationInputRoots),
141
+ permissionScope("investigation_workspace_read", arrays.evidenceRoots),
142
+ permissionScope("investigation_workspace_write", arrays.evidenceRoots),
143
+ permissionScope("snapshot_read", arrays.analysisSnapshotRoots),
144
+ permissionScope("snapshot_write", arrays.analysisSnapshotRoots),
145
+ permissionScope("artifact_extract", ["/"]),
146
+ permissionScope("reference_read", arrays.referenceRoots),
147
+ ];
148
+ appendProcessCaptureCeiling(ceilings, env, arrays);
149
+ appendBrowserObservationCeiling(ceilings, env, arrays);
150
+ appendElectronObservationCeiling(ceilings, env, arrays);
151
+ appendNativeMountCeiling(ceilings, env);
152
+ appendJavaScriptReplayCeiling(ceilings, env, arrays);
153
+ appendManagedRuntimeCeiling(ceilings, env, arrays);
154
+ return ceilings;
155
+ };
156
+ const buildAppConfig = (env, arrays, permissionCeilings) => ({
157
+ analysisProvider: env.REA_ANALYSIS_PROVIDER,
158
+ ghidraInstallDir: env.GHIDRA_INSTALL_DIR,
159
+ ghidraJavaHome: env.JAVA_HOME,
160
+ ilspyCmdPath: env.REA_ILSPY_CMD_PATH,
161
+ hopperLauncherPath: env.HOPPER_LAUNCHER_PATH ?? defaultHopperLauncherPath(),
162
+ hopperTargetPath: env.HOPPER_TARGET_PATH,
163
+ hopperTargetKind: env.HOPPER_TARGET_KIND,
164
+ hopperLoaderArgs: arrays.loaderArgs,
165
+ logLevel: env.REA_LOG_LEVEL,
166
+ processExecutionPolicy: {
167
+ enabled: env.REA_PROCESS_CAPTURE_ENABLED === "true",
168
+ executableRoots: arrays.executableRoots,
169
+ workingRoots: arrays.workingRoots,
170
+ allowedEnvironment: arrays.allowedEnvironment,
171
+ allowExternalNetwork: env.REA_PROCESS_ALLOW_EXTERNAL_NETWORK === "true",
172
+ },
173
+ artifactNativeMountEnabled: env.REA_ARTIFACT_NATIVE_MOUNT_ENABLED === "true",
174
+ artifactIntegrityContinueEnabled: env.REA_ARTIFACT_INTEGRITY_CONTINUE_ENABLED === "true",
175
+ evidenceFilePolicy: filePolicy(arrays.evidenceRoots),
176
+ investigationInputRoots: arrays.investigationInputRoots,
177
+ analysisSnapshotFilePolicy: filePolicy(arrays.analysisSnapshotRoots),
178
+ referenceSourcePolicy: {
179
+ roots: arrays.referenceRoots,
180
+ secretPatterns: arrays.secretPatterns,
181
+ maxBytes: 16 * 1024 * 1024,
182
+ maxEntries: 10_000,
183
+ maxDepth: 32,
184
+ maxPathBytes: 4_096,
185
+ },
186
+ browserObservationEnabled: env.REA_BROWSER_OBSERVE_ENABLED === "true",
187
+ browserCdpEndpoints: arrays.browserEndpoints,
188
+ browserAllowedOrigins: arrays.browserOrigins,
189
+ electronObservationEnabled: env.REA_ELECTRON_OBSERVE_ENABLED === "true",
190
+ electronCdpEndpoints: arrays.electronEndpoints,
191
+ electronFileRoots: arrays.electronFileRoots,
192
+ javascriptReplayPolicy: {
193
+ enabled: env.REA_JAVASCRIPT_REPLAY_ENABLED === "true",
194
+ roots: arrays.javascriptReplayRoots,
195
+ nodePath: env.REA_JAVASCRIPT_REPLAY_NODE_PATH,
196
+ bubblewrapPath: env.REA_JAVASCRIPT_REPLAY_BWRAP_PATH,
197
+ systemdRunPath: env.REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH,
198
+ systemctlPath: env.REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH,
199
+ shellPath: env.REA_JAVASCRIPT_REPLAY_SHELL_PATH,
200
+ },
201
+ managedRuntimePolicy: {
202
+ enabled: env.REA_MANAGED_RUNTIME_ENABLED === "true",
203
+ roots: arrays.managedRuntimeRoots,
204
+ executablePath: env.REA_MANAGED_RUNTIME_EXECUTABLE_PATH,
205
+ },
206
+ permissionCeilings,
207
+ administratorPermissionGrants: administratorGrants(env.REA_PROCESS_CAPTURE_AUTO_GRANT === "true"
208
+ ? permissionCeilings
209
+ : permissionCeilings.filter(({ capability }) => capability !== "process_capture")),
210
+ permissionProjectRoot: env.REA_PERMISSION_PROJECT_ROOT,
211
+ permissionProjectStore: env.REA_PERMISSION_PROJECT_STORE,
212
+ });
213
+ /**
214
+ * Parse provider and authority configuration once at the composition root.
215
+ * Explicit loader arguments override REA's header-derived defaults for a
216
+ * supported target, allowing callers to refine Hopper's loader behavior without
217
+ * bypassing REA's path and executable-header checks.
218
+ */
219
+ export const parseConfig = (environment) => {
220
+ const envResult = parseEnvironment(environment);
221
+ if (!envResult.ok)
222
+ return envResult;
223
+ const arraysResult = parseAllArrays(envResult.value);
224
+ if (!arraysResult.ok)
225
+ return arraysResult;
226
+ const permissionCeilings = buildPermissionCeilings(envResult.value, arraysResult.value);
227
+ return ok(buildAppConfig(envResult.value, arraysResult.value, permissionCeilings));
228
+ };
@@ -0,0 +1,68 @@
1
+ import { z } from "zod";
2
+ import { ConfigurationError } from "../domain/errors.js";
3
+ import { err, ok } from "../domain/result.js";
4
+ import {} from "../domain/browserObservation.js";
5
+ import { electronFileRootsSchema } from "../domain/electronObservation.js";
6
+ export const parseStringArray = (encoded, name) => {
7
+ try {
8
+ const parsed = z
9
+ .array(z.string().min(1))
10
+ .max(128)
11
+ .safeParse(JSON.parse(encoded));
12
+ return parsed.success
13
+ ? ok(parsed.data)
14
+ : err(new ConfigurationError(parsed.error.issues.some(({ code }) => code === "too_big")
15
+ ? `${name} must encode at most 128 strings`
16
+ : `${name} must encode an array of strings`, { cause: parsed.error }));
17
+ }
18
+ catch (cause) {
19
+ return err(new ConfigurationError(`${name} must be valid JSON`, { cause }));
20
+ }
21
+ };
22
+ export const parseBrowserArray = (encoded, name, itemSchema, maximum) => {
23
+ try {
24
+ const parsed = z
25
+ .array(itemSchema)
26
+ .max(maximum)
27
+ .safeParse(JSON.parse(encoded));
28
+ return parsed.success
29
+ ? ok([...new Set(parsed.data)].sort())
30
+ : err(new ConfigurationError(`${name} must encode valid browser scopes`, {
31
+ cause: parsed.error,
32
+ }));
33
+ }
34
+ catch (cause) {
35
+ return err(new ConfigurationError(`${name} must be valid JSON`, { cause }));
36
+ }
37
+ };
38
+ export const parseElectronFileRoots = (encoded) => {
39
+ try {
40
+ const decoded = JSON.parse(encoded);
41
+ if (Array.isArray(decoded) && decoded.length === 0)
42
+ return ok([]);
43
+ const parsed = electronFileRootsSchema.safeParse(decoded);
44
+ return parsed.success
45
+ ? ok(parsed.data)
46
+ : err(new ConfigurationError("REA_ELECTRON_FILE_ROOTS_JSON must encode absolute roots", { cause: parsed.error }));
47
+ }
48
+ catch (cause) {
49
+ return err(new ConfigurationError("REA_ELECTRON_FILE_ROOTS_JSON must be valid JSON", { cause }));
50
+ }
51
+ };
52
+ export const parseLoaderArgs = (encoded) => {
53
+ if (encoded === undefined)
54
+ return ok([]);
55
+ let decoded;
56
+ try {
57
+ decoded = JSON.parse(encoded);
58
+ }
59
+ catch (cause) {
60
+ return err(new ConfigurationError("HOPPER_LOADER_ARGS_JSON must be valid JSON", {
61
+ cause,
62
+ }));
63
+ }
64
+ const parsed = z.array(z.string()).safeParse(decoded);
65
+ return parsed.success
66
+ ? ok(parsed.data)
67
+ : err(new ConfigurationError("HOPPER_LOADER_ARGS_JSON must encode an array of strings", { cause: parsed.error }));
68
+ };
@@ -0,0 +1,30 @@
1
+ import { isLiteralLoopbackHostname } from "../domain/browserObservation.js";
2
+ export const filePolicy = (roots) => ({
3
+ roots,
4
+ maxBytes: 64 * 1024 * 1024,
5
+ maxDepth: 64,
6
+ maxStringLength: 1024 * 1024,
7
+ maxNodes: 1_000_000,
8
+ });
9
+ export const permissionScope = (capability, roots, options = {}) => ({
10
+ capability,
11
+ roots,
12
+ executables: options.executables ?? [],
13
+ environment_names: options.environment_names ?? [],
14
+ ...(options.origins === undefined ? {} : { origins: options.origins }),
15
+ network: options.network ?? "none",
16
+ mount: options.mount ?? false,
17
+ });
18
+ export const administratorGrants = (ceilings) => ceilings.map((ceiling) => ({
19
+ ...ceiling,
20
+ grant_id: `administrator:${ceiling.capability}`,
21
+ lifetime: "administrator",
22
+ operation_identity: null,
23
+ expires_at: null,
24
+ }));
25
+ export const browserNetworkScope = (origins) => origins.every((origin) => {
26
+ const hostname = new URL(origin).hostname;
27
+ return isLiteralLoopbackHostname(hostname);
28
+ })
29
+ ? "loopback"
30
+ : "external";
@@ -0,0 +1 @@
1
+ export {};