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
@@ -1,408 +1,46 @@
1
1
  import { createHash } from "node:crypto";
2
- import { basename } from "node:path";
3
2
  import canonicalize from "canonicalize";
4
- import { z } from "zod";
5
- import { evidenceSchema, parseEvidence } from "./evidence.js";
6
- import { functionDossierSchema } from "./hopperValues.js";
3
+ import { parseEvidence } from "./evidence.js";
7
4
  import { managedNativeBoundaryInspectionSchema, } from "./managedArtifact.js";
8
- import { inspectMachoSchema } from "./nativeInspection.js";
9
- const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
10
- const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
11
- const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
12
- const boundedTextSchema = z.string().min(1).max(4_096);
13
- const nativeVerificationLimitsSchema = z.strictObject({
14
- max_native_observations: z.number().int().min(1).max(50).default(20),
15
- max_candidates_per_import: z.number().int().min(1).max(100).default(25),
16
- });
17
- /** Authenticated managed boundary Evidence plus native observations. */
18
- export const managedNativeVerificationInputSchema = z
19
- .strictObject({
20
- managed_boundaries: evidenceSchema,
21
- native_observations: z.array(evidenceSchema).min(1).max(50),
22
- limits: nativeVerificationLimitsSchema.default({
23
- max_native_observations: 20,
24
- max_candidates_per_import: 25,
25
- }),
26
- unknown_registry_approved: z.literal(true).optional(),
27
- })
28
- .superRefine((input, context) => {
29
- const ids = new Set();
30
- for (const [index, evidence] of input.native_observations.entries()) {
31
- if (evidence.evidence_id === input.managed_boundaries.evidence_id) {
32
- context.addIssue({
33
- code: "custom",
34
- path: ["native_observations", index],
35
- message: "Native observation Evidence must be distinct from managed boundary Evidence",
36
- });
37
- }
38
- if (ids.has(evidence.evidence_id)) {
39
- context.addIssue({
40
- code: "custom",
41
- path: ["native_observations", index],
42
- message: "Native observation Evidence IDs must be unique",
43
- });
44
- }
45
- ids.add(evidence.evidence_id);
46
- }
47
- });
48
- const nativeSymbolSchema = z.strictObject({
49
- evidence_id: evidenceIdSchema,
50
- operation: z.string().min(1),
51
- name: z.string().min(1),
52
- address: z.string().nullable(),
53
- module_name: z.string().nullable(),
54
- module_path: z.string().nullable(),
55
- source: z.enum(["macho-export", "function-dossier"]),
56
- });
57
- const matchStatusSchema = z.enum([
58
- "verified",
59
- "inferred",
60
- "unresolved",
61
- "contradicted",
62
- ]);
63
- const matchBasisSchema = z.enum([
64
- "exact-export-name",
65
- "exact-function-name",
66
- "decorated-name-candidate",
67
- "module-mismatch",
68
- "no-native-candidate",
69
- "unsupported-native-evidence",
70
- ]);
71
- const pinvokeVerificationSchema = z.strictObject({
72
- item_id: z.string().regex(/^mnv_pinvoke_[a-f0-9]{64}$/u),
73
- managed: z.strictObject({
74
- token: tokenSchema,
75
- member_token: tokenSchema.nullable(),
76
- member_name: z.string().nullable(),
77
- import_name: z.string().min(1),
78
- import_scope_name: z.string().nullable(),
79
- no_mangle: z.boolean(),
80
- char_set: z.enum(["not-specified", "ansi", "unicode", "auto", "unknown"]),
81
- call_convention: z.enum([
82
- "not-specified",
83
- "winapi",
84
- "cdecl",
85
- "stdcall",
86
- "thiscall",
87
- "fastcall",
88
- "unknown",
89
- ]),
90
- declaration_verification: z.literal("managed-declaration-only"),
91
- }),
92
- status: matchStatusSchema,
93
- basis: matchBasisSchema,
94
- confidence: z.enum(["observed", "inferred", "unknown"]),
95
- matched_native: nativeSymbolSchema.nullable(),
96
- candidates: z.array(nativeSymbolSchema).max(100),
97
- evidence_links: z.array(evidenceIdSchema).min(1).max(51),
98
- limitations: z.array(boundedTextSchema).max(100),
99
- });
100
- /** Provider-neutral managed/native verification result. */
101
- export const managedNativeVerificationResultSchema = z.strictObject({
102
- schema_version: z.literal(1),
103
- verification_id: z.string().regex(/^mnv_[a-f0-9]{64}$/u),
104
- algorithm: z.strictObject({
105
- name: z.literal("rea-managed-native-verification"),
106
- version: z.literal(1),
107
- token_identity: z.literal("build-local"),
108
- token_to_address_mapping: z.literal("not-inferred"),
109
- }),
110
- managed_boundary: z.strictObject({
111
- evidence_id: evidenceIdSchema,
112
- artifact_sha256: digestSchema,
113
- artifact_path: z.string().min(1),
114
- mvid: z.string().uuid().nullable(),
115
- metadata_status: z.enum(["absent", "complete", "partial", "malformed"]),
116
- pinvoke_imports_total: z.number().int().min(0),
117
- native_implementations_total: z.number().int().min(0),
118
- coverage_state: z.enum(["complete", "partial", "unavailable"]),
119
- }),
120
- native_observations: z.strictObject({
121
- total: z.number().int().min(1),
122
- accepted: z.number().int().min(0),
123
- unsupported: z.number().int().min(0),
124
- symbols: z.number().int().min(0),
125
- truncated: z.boolean(),
126
- }),
127
- summary: z.strictObject({
128
- verified: z.number().int().min(0),
129
- inferred: z.number().int().min(0),
130
- unresolved: z.number().int().min(0),
131
- contradicted: z.number().int().min(0),
132
- native_body_unresolved: z.number().int().min(0),
133
- }),
134
- pinvoke_imports: z.array(pinvokeVerificationSchema).max(50_000),
135
- native_implementations: z.strictObject({
136
- unresolved: z.number().int().min(0),
137
- reason: boundedTextSchema,
138
- }),
139
- coverage: z.strictObject({
140
- status: z.enum(["complete-within-inputs", "partial", "truncated"]),
141
- omitted_native_observations: z.number().int().min(0),
142
- omitted_candidates: z.number().int().min(0),
143
- }),
144
- evidence_links: z.array(evidenceIdSchema).min(2).max(51),
145
- limitations: z.array(boundedTextSchema).max(1_000),
146
- });
5
+ import { managedNativeVerificationResultSchema, } from "./managedNativeVerificationSchemas.js";
6
+ import { buildVerificationResult, collectNativeSymbols, verifyPinvoke, } from "./managedNativeVerificationMatch.js";
7
+ export { managedNativeVerificationInputSchema, } from "./managedNativeVerificationSchemas.js";
8
+ export { managedNativeVerificationResultSchema };
147
9
  const sha256 = (value) => {
148
10
  const serialized = canonicalize(value);
149
11
  if (serialized === undefined)
150
12
  throw new TypeError("Managed/native verification canonicalization failed");
151
13
  return createHash("sha256").update(serialized).digest("hex");
152
14
  };
153
- /** Verify managed P/Invoke declarations against authenticated native Evidence. */
154
- export const verifyManagedNativeBoundaries = (input) => {
15
+ const managedBoundaryFromInput = (input) => {
155
16
  const managedEvidence = parseEvidence(input.managed_boundaries);
156
17
  if (managedEvidence.operation !== "inspect_managed_native_boundaries")
157
18
  throw new TypeError("Evidence operation is not inspect_managed_native_boundaries");
158
- const managed = managedNativeBoundaryInspectionSchema.parse(managedEvidence.normalized_result);
19
+ return managedNativeBoundaryInspectionSchema.parse(managedEvidence.normalized_result);
20
+ };
21
+ /** Verify managed P/Invoke declarations against authenticated native Evidence. */
22
+ export const verifyManagedNativeBoundaries = (input) => {
23
+ const managed = managedBoundaryFromInput(input);
24
+ const managedEvidence = parseEvidence(input.managed_boundaries);
159
25
  const native = collectNativeSymbols(input.native_observations.slice(0, input.limits.max_native_observations));
160
- const verifiedPinvokes = managed.pinvoke_imports.items.map((item) => verifyPinvoke(item, managedEvidence.evidence_id, native.symbols, native.accepted > 0, input));
26
+ const verifiedPinvokes = managed.pinvoke_imports.items.map((item) => verifyPinvoke({
27
+ item,
28
+ managedEvidenceId: managedEvidence.evidence_id,
29
+ symbols: native.symbols,
30
+ hasSupportedNativeEvidence: native.accepted > 0,
31
+ input,
32
+ }));
161
33
  const pinvokeImports = verifiedPinvokes.map(({ verification }) => verification);
162
- const counts = countStatuses(pinvokeImports);
163
- const omittedNativeObservations = Math.max(0, input.native_observations.length - input.limits.max_native_observations);
164
- const omittedCandidates = verifiedPinvokes.reduce((sum, item) => sum + item.omittedCandidates, 0);
165
- const coverageStatus = omittedNativeObservations > 0 || omittedCandidates > 0
166
- ? "truncated"
167
- : managed.coverage.state === "complete" && native.unsupported === 0
168
- ? "complete-within-inputs"
169
- : "partial";
170
- const withoutId = {
171
- schema_version: 1,
172
- algorithm: {
173
- name: "rea-managed-native-verification",
174
- version: 1,
175
- token_identity: "build-local",
176
- token_to_address_mapping: "not-inferred",
177
- },
178
- managed_boundary: {
179
- evidence_id: managedEvidence.evidence_id,
180
- artifact_sha256: managed.artifact.sha256,
181
- artifact_path: managed.artifact.path,
182
- mvid: managed.module?.mvid ?? null,
183
- metadata_status: managed.metadata.status,
184
- pinvoke_imports_total: managed.pinvoke_imports.total,
185
- native_implementations_total: managed.native_implementations.total,
186
- coverage_state: managed.coverage.state,
187
- },
188
- native_observations: {
189
- total: input.native_observations.length,
190
- accepted: native.accepted,
191
- unsupported: native.unsupported,
192
- symbols: native.symbols.length,
193
- truncated: omittedNativeObservations > 0,
194
- },
195
- summary: {
196
- ...counts,
197
- native_body_unresolved: managed.native_implementations.items.filter(({ boundary_kind: kind }) => kind !== "pinvoke").length,
198
- },
199
- pinvoke_imports: pinvokeImports,
200
- native_implementations: {
201
- unresolved: managed.native_implementations.items.filter(({ boundary_kind: kind }) => kind !== "pinvoke").length,
202
- reason: "Managed metadata tokens and RVAs are not translated to native provider addresses by this workflow; C++/CLI, ReadyToRun, and native-body mappings require explicit provider-supported bridge evidence.",
203
- },
204
- coverage: {
205
- status: coverageStatus,
206
- omitted_native_observations: omittedNativeObservations,
207
- omitted_candidates: omittedCandidates,
208
- },
209
- evidence_links: [
210
- managedEvidence.evidence_id,
211
- ...input.native_observations
212
- .slice(0, input.limits.max_native_observations)
213
- .map(({ evidence_id: id }) => id),
214
- ],
215
- limitations: [
216
- "P/Invoke verification checks declared import names against supplied native export or function-name Evidence only.",
217
- "A matching native symbol verifies that a candidate export/function was observed; it does not prove CLR binding, marshaling behavior, call reachability, or runtime loading.",
218
- "Missing supplied native symbols are reported as unresolved, not proof that a dependency cannot exist.",
219
- "Managed metadata tokens and method RVAs are not interpreted as native addresses.",
220
- ...(managed.coverage.state === "complete"
221
- ? []
222
- : ["Managed boundary input is partial or unavailable."]),
223
- ...(native.unsupported === 0
224
- ? []
225
- : [
226
- "Some native Evidence operations were unsupported by this workflow.",
227
- ]),
228
- ],
229
- };
34
+ const withoutId = buildVerificationResult({
35
+ managedEvidence,
36
+ managed,
37
+ native,
38
+ pinvokeImports,
39
+ verifiedPinvokes,
40
+ input,
41
+ });
230
42
  return managedNativeVerificationResultSchema.parse({
231
43
  ...withoutId,
232
44
  verification_id: `mnv_${sha256(withoutId)}`,
233
45
  });
234
46
  };
235
- const collectNativeSymbols = (observations) => {
236
- const symbols = [];
237
- let accepted = 0;
238
- let unsupported = 0;
239
- for (const raw of observations) {
240
- const evidence = parseEvidence(raw);
241
- const extracted = symbolsForEvidence(evidence);
242
- if (!extracted.supported) {
243
- unsupported += 1;
244
- }
245
- else {
246
- accepted += 1;
247
- symbols.push(...extracted.symbols);
248
- }
249
- }
250
- return { symbols, accepted, unsupported };
251
- };
252
- const symbolsForEvidence = (evidence) => {
253
- if (evidence.operation === "inspect_macho") {
254
- const result = inspectMachoSchema.parse(evidence.normalized_result);
255
- return {
256
- supported: true,
257
- symbols: result.exports.items.map((symbol) => ({
258
- evidence_id: evidence.evidence_id,
259
- operation: evidence.operation,
260
- name: symbol.name,
261
- address: symbol.address,
262
- module_name: moduleName(evidence),
263
- module_path: modulePath(evidence),
264
- source: "macho-export",
265
- })),
266
- };
267
- }
268
- if (evidence.operation === "analyze_function") {
269
- const dossier = functionDossierSchema.parse(evidence.normalized_result);
270
- return {
271
- supported: true,
272
- symbols: [
273
- {
274
- evidence_id: evidence.evidence_id,
275
- operation: evidence.operation,
276
- name: dossier.procedure.name,
277
- address: dossier.procedure.address,
278
- module_name: moduleName(evidence),
279
- module_path: modulePath(evidence),
280
- source: "function-dossier",
281
- },
282
- ],
283
- };
284
- }
285
- return { supported: false, symbols: [] };
286
- };
287
- const verifyPinvoke = (item, managedEvidenceId, symbols, hasSupportedNativeEvidence, input) => {
288
- const managed = {
289
- token: item.token,
290
- member_token: item.member_token,
291
- member_name: item.member_name,
292
- import_name: item.import_name,
293
- import_scope_name: item.import_scope_name,
294
- no_mangle: item.no_mangle,
295
- char_set: item.char_set,
296
- call_convention: item.call_convention,
297
- declaration_verification: item.verification,
298
- };
299
- const names = candidateNames(managed);
300
- const allCandidates = symbols.filter((symbol) => names.some((name) => sameSymbolName(name, symbol.name)));
301
- const candidates = allCandidates.slice(0, input.limits.max_candidates_per_import);
302
- const exact = candidates.find((symbol) => sameSymbolName(item.import_name, symbol.name) &&
303
- moduleCompatible(item.import_scope_name, symbol));
304
- const decorated = candidates.find((symbol) => moduleCompatible(item.import_scope_name, symbol));
305
- const selected = exact ?? decorated ?? candidates[0] ?? null;
306
- const basis = selected === null
307
- ? hasSupportedNativeEvidence
308
- ? "no-native-candidate"
309
- : "unsupported-native-evidence"
310
- : !moduleCompatible(item.import_scope_name, selected)
311
- ? "module-mismatch"
312
- : exact !== undefined
313
- ? selected.source === "macho-export"
314
- ? "exact-export-name"
315
- : "exact-function-name"
316
- : "decorated-name-candidate";
317
- const status = selected === null
318
- ? "unresolved"
319
- : basis === "module-mismatch"
320
- ? "contradicted"
321
- : basis === "decorated-name-candidate"
322
- ? "inferred"
323
- : "verified";
324
- const limitations = [
325
- ...(item.import_scope_name === null
326
- ? ["Managed declaration does not name an import scope/module."]
327
- : []),
328
- ...(status === "inferred"
329
- ? [
330
- "Native symbol matched a decorated candidate rather than the exact declared import name.",
331
- ]
332
- : []),
333
- ...(status === "contradicted"
334
- ? [
335
- "A symbol name candidate exists, but the supplied native Evidence module identity does not match the managed import scope.",
336
- ]
337
- : []),
338
- ...(status === "unresolved"
339
- ? [
340
- "No supplied native export/function Evidence matched this declared import.",
341
- ]
342
- : []),
343
- ];
344
- return {
345
- verification: pinvokeVerificationSchema.parse({
346
- item_id: `mnv_pinvoke_${sha256({
347
- managedEvidenceId,
348
- token: item.token,
349
- importName: item.import_name,
350
- importScope: item.import_scope_name,
351
- candidates,
352
- })}`,
353
- managed,
354
- status,
355
- basis,
356
- confidence: status === "verified"
357
- ? "observed"
358
- : status === "inferred"
359
- ? "inferred"
360
- : "unknown",
361
- matched_native: selected,
362
- candidates,
363
- evidence_links: [
364
- managedEvidenceId,
365
- ...new Set(candidates.map(({ evidence_id: id }) => id)),
366
- ],
367
- limitations,
368
- }),
369
- omittedCandidates: Math.max(0, allCandidates.length - candidates.length),
370
- };
371
- };
372
- const candidateNames = (managed) => {
373
- const names = new Set([managed.import_name]);
374
- if (!managed.no_mangle) {
375
- if (managed.char_set === "unicode")
376
- names.add(`${managed.import_name}W`);
377
- if (managed.char_set === "ansi")
378
- names.add(`${managed.import_name}A`);
379
- if (managed.call_convention === "stdcall") {
380
- names.add(`_${managed.import_name}`);
381
- names.add(`_${managed.import_name}@0`);
382
- }
383
- }
384
- return [...names];
385
- };
386
- const sameSymbolName = (left, right) => normalizeSymbol(left) === normalizeSymbol(right);
387
- const normalizeSymbol = (value) => value.replace(/^_+/u, "").replace(/@\d+$/u, "").toLowerCase();
388
- const moduleCompatible = (scope, symbol) => {
389
- if (scope === null)
390
- return true;
391
- const expected = normalizeModule(scope);
392
- return [symbol.module_name, symbol.module_path]
393
- .filter((value) => value !== null)
394
- .map(normalizeModule)
395
- .some((value) => value === expected);
396
- };
397
- const normalizeModule = (value) => basename(value)
398
- .toLowerCase()
399
- .replace(/^lib/u, "")
400
- .replace(/\.(dll|dylib|so|node|exe)$/u, "");
401
- const moduleName = (evidence) => evidence.subject?.name ?? null;
402
- const modulePath = (evidence) => evidence.subject?.local_path ?? null;
403
- const countStatuses = (items) => ({
404
- verified: items.filter(({ status }) => status === "verified").length,
405
- inferred: items.filter(({ status }) => status === "inferred").length,
406
- unresolved: items.filter(({ status }) => status === "unresolved").length,
407
- contradicted: items.filter(({ status }) => status === "contradicted").length,
408
- });