rea-agents 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -38
- package/bridge/ghidra/ReaGhidraBridge.java +96 -11
- package/dist/application/AndroidApplicationService.js +17 -0
- package/dist/application/AppleApplicationService.js +17 -0
- package/dist/application/ArtifactExtraction.js +1 -1
- package/dist/application/ArtifactInventory/classify.js +42 -0
- package/dist/application/ArtifactInventory/hash.js +43 -0
- package/dist/application/ArtifactInventory/reader.js +41 -0
- package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
- package/dist/application/ArtifactInventory/scanReader.js +124 -0
- package/dist/application/ArtifactInventory/types.js +10 -0
- package/dist/application/ArtifactInventory.js +9 -351
- package/dist/application/AuthorizedArtifactInventory.js +2 -2
- package/dist/application/BinarySession.js +47 -270
- package/dist/application/BinarySessionExecution.js +28 -0
- package/dist/application/BinarySessionOpen.js +39 -0
- package/dist/application/BinarySessionRecords.js +149 -0
- package/dist/application/BinarySessionStatus.js +75 -0
- package/dist/application/CapabilityInventory.js +24 -2
- package/dist/application/ClientRegistrationStatus.js +11 -4
- package/dist/application/CrossVersionInventory.js +8 -2
- package/dist/application/CrossVersionInvestigation.js +1 -23
- package/dist/application/CrossVersionInvestigationCollections.js +23 -0
- package/dist/application/DirectAnalysis.js +47 -44
- package/dist/application/Doctor.js +156 -238
- package/dist/application/DoctorDiagnostics.js +180 -0
- package/dist/application/ElectronBoundaryAnalysis.js +23 -7
- package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
- package/dist/application/EnhancedToolPagination.js +22 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +20 -37
- package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
- package/dist/application/InventoryProjectionEvidence.js +41 -0
- package/dist/application/InvestigationProviders.js +12 -0
- package/dist/application/InvestigationWorkspaceStore.js +24 -10
- package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
- package/dist/application/JavaScriptArtifactFiles.js +6 -2
- package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
- package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
- package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
- package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
- package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
- package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
- package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
- package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
- package/dist/application/JavaScriptJsonModules.js +39 -0
- package/dist/application/JavaScriptModuleRelationships.js +262 -0
- package/dist/application/JavaScriptReplayPermission.js +16 -0
- package/dist/application/JavaScriptReplayService.js +182 -156
- package/dist/application/LinuxHopper.js +10 -0
- package/dist/application/MacHopper.js +22 -11
- package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
- package/dist/application/PermissionAuthority.js +106 -63
- package/dist/application/ProcessCaptureCapability.js +1 -1
- package/dist/application/ProcessCapturePermission.js +13 -0
- package/dist/application/ProcessCli.js +2 -12
- package/dist/application/ProcessHarness.js +1 -1
- package/dist/application/ProcessPairedExperiment.js +72 -0
- package/dist/application/ProjectPermissionStore.js +48 -9
- package/dist/application/RealHopperAssertions.js +76 -0
- package/dist/application/ReconstructionCoverageService.js +69 -0
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
- package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
- package/dist/application/Setup.js +148 -260
- package/dist/application/SetupClientConfiguration.js +224 -0
- package/dist/application/SetupClients.js +24 -2
- package/dist/application/SetupPlan.js +124 -12
- package/dist/application/SetupSkill.js +54 -36
- package/dist/application/SupportedClients.js +1 -0
- package/dist/application/Uninstall.js +12 -3
- package/dist/application/Upgrade.js +16 -1
- package/dist/application/WindowsCapabilities.js +86 -0
- package/dist/artifacts/AsarArtifactReader.js +11 -0
- package/dist/browser/BrowserProcessStartup.js +88 -0
- package/dist/browser/CdpCaptureDocuments.js +12 -8
- package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
- package/dist/browser/CdpCaptureEventHandlers.js +336 -0
- package/dist/browser/CdpCaptureEventHelpers.js +71 -0
- package/dist/browser/CdpCaptureEventState.js +1 -0
- package/dist/browser/CdpCaptureEventTypes.js +1 -0
- package/dist/browser/CdpCaptureEvents.js +29 -496
- package/dist/browser/CdpObservationSession.js +51 -8
- package/dist/browser/CdpPageCapture.js +12 -133
- package/dist/browser/CdpPageCaptureScripts.js +97 -0
- package/dist/browser/CdpPageCaptureWorkers.js +46 -0
- package/dist/browser/CdpWebMcpDiscovery.js +38 -14
- package/dist/browser/PngVisualDiff.js +9 -2
- package/dist/catalogIdentity.js +4 -0
- package/dist/cli/artifactCommands.js +82 -0
- package/dist/cli/coreAnalysisCommands.js +232 -0
- package/dist/cli/managedCommands.js +397 -0
- package/dist/cli/managedProjectGraphCommand.js +24 -0
- package/dist/cli/options.js +9 -0
- package/dist/cli/setupCommands.js +113 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +122 -0
- package/dist/cli.js +10 -768
- package/dist/cliApplicationCommands.js +118 -4
- package/dist/cliBrowserAdvancedCommands.js +73 -16
- package/dist/cliBrowserCommands.js +39 -115
- package/dist/cliCommandNames.js +4 -0
- package/dist/cliElectronCommands.js +33 -62
- package/dist/cliEvidenceCommands.js +13 -2
- package/dist/cliInvestigationCommands.js +53 -10
- package/dist/cliObservationOptions.js +137 -0
- package/dist/cliPolicyCommands.js +80 -46
- package/dist/cliSetup.js +306 -0
- package/dist/config/environment.js +107 -0
- package/dist/config/parseConfig.js +228 -0
- package/dist/config/parsers.js +68 -0
- package/dist/config/permissions.js +30 -0
- package/dist/config/types.js +1 -0
- package/dist/config.js +1 -375
- package/dist/contracts/applicationToolContracts.js +134 -0
- package/dist/contracts/electronToolContracts.js +51 -3
- package/dist/contracts/managedToolContracts.js +8 -3
- package/dist/contracts/managedWorkflowToolContracts.js +3 -3
- package/dist/contracts/providerSelection.js +2 -0
- package/dist/contracts/sessionStatusContract.js +26 -0
- package/dist/contracts/toolContractTypes.js +12 -1
- package/dist/contracts/toolContracts.js +5 -12
- package/dist/contracts/toolEffects.js +14 -0
- package/dist/contracts/toolOutputSchemaGroups.js +274 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +328 -0
- package/dist/contracts/toolOutputSchemas.js +2 -550
- package/dist/domain/analysisErrorPresentation.js +234 -0
- package/dist/domain/analysisErrorProjection.js +284 -0
- package/dist/domain/androidApplication.js +206 -0
- package/dist/domain/appleApplication.js +221 -0
- package/dist/domain/artifactComparison.js +34 -15
- package/dist/domain/binaryTarget.js +87 -37
- package/dist/domain/boundedCartesianProjection.js +15 -0
- package/dist/domain/browserObservation.js +1 -285
- package/dist/domain/browserObservationSchemas.js +286 -0
- package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
- package/dist/domain/errors.js +4 -486
- package/dist/domain/functionComparison.js +4 -165
- package/dist/domain/functionComparisonDimensions.js +164 -0
- package/dist/domain/javascriptApplicationVersionItems.js +18 -6
- package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
- package/dist/domain/javascriptExportInstrumentation.js +97 -0
- package/dist/domain/javascriptFeatureTraversal.js +19 -7
- package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
- package/dist/domain/javascriptSemanticAnalysis.js +386 -0
- package/dist/domain/javascriptSemanticIr.js +30 -0
- package/dist/domain/javascriptSemanticProjection.js +366 -0
- package/dist/domain/javascriptSemanticState.js +40 -0
- package/dist/domain/javascriptSemanticTraversal.js +22 -0
- package/dist/domain/javascriptSemanticValues.js +352 -0
- package/dist/domain/javascriptStaticAnalysis.js +5 -221
- package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
- package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
- package/dist/domain/knownPageCoverage.js +21 -0
- package/dist/domain/managedApplicationGraph.js +14 -364
- package/dist/domain/managedApplicationGraphCoverage.js +170 -0
- package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
- package/dist/domain/managedApplicationGraphNodes.js +336 -0
- package/dist/domain/managedArtifact.js +16 -8
- package/dist/domain/managedMemberComparison.js +37 -391
- package/dist/domain/managedMemberComparisonCoverage.js +72 -0
- package/dist/domain/managedMemberComparisonMatch.js +356 -0
- package/dist/domain/managedNativeVerification.js +27 -389
- package/dist/domain/managedNativeVerificationMatch.js +272 -0
- package/dist/domain/managedNativeVerificationSchemas.js +141 -0
- package/dist/domain/managedReconstruction.js +82 -69
- package/dist/domain/managedRuntimeCorrelation.js +12 -3
- package/dist/domain/nodeRuntimeCharacterization.js +66 -0
- package/dist/domain/permissionPolicy.js +2 -0
- package/dist/domain/processComparison.js +19 -0
- package/dist/domain/processPairedExperiment.js +128 -0
- package/dist/domain/reconstructionCoverage.js +387 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
- package/dist/domain/reconstructionVerificationSchemas.js +8 -0
- package/dist/domain/replayMachine.js +316 -0
- package/dist/domain/replayMachineRuntime.js +215 -0
- package/dist/domain/runtimeCharacterization.js +85 -0
- package/dist/domain/runtimeIdentification.js +210 -0
- package/dist/domain/webBundleAnalyzer.js +3 -409
- package/dist/domain/webBundleAnalyzerAst.js +77 -0
- package/dist/domain/webBundleAnalyzerInspection.js +307 -0
- package/dist/domain/webBundleAnalyzerResult.js +120 -0
- package/dist/dotnet/ManagedArtifactInspector.js +50 -29
- package/dist/dotnet/ManagedMemberInspector.js +51 -785
- package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
- package/dist/dotnet/ManagedMemberRows.js +120 -0
- package/dist/dotnet/ManagedMetadataInventory.js +42 -306
- package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
- package/dist/dotnet/ManagedMetadataLayout.js +48 -111
- package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
- package/dist/dotnet/ManagedPeReader.js +59 -28
- package/dist/evaluation/CodexAgentEval.js +132 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraClient.js +76 -91
- package/dist/ghidra/GhidraClientStartup.js +29 -0
- package/dist/ghidra/GhidraClientWire.js +34 -0
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraDiagnostics.js +6 -1
- package/dist/ghidra/GhidraInstallation.js +20 -15
- package/dist/ghidra/GhidraLauncher.js +93 -29
- package/dist/ghidra/GhidraProvider.js +61 -161
- package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
- package/dist/ghidra/GhidraSessionValues.js +2 -0
- package/dist/ghidra/GhidraSocketConnection.js +44 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
- package/dist/ghidra/GhidraTransport.js +71 -0
- package/dist/identity.js +4 -2
- package/dist/main/messages.js +5 -0
- package/dist/main/reload.js +49 -0
- package/dist/main/shutdown.js +25 -0
- package/dist/main/startup.js +14 -0
- package/dist/main/state.js +26 -0
- package/dist/main/transport.js +61 -0
- package/dist/main/types.js +1 -0
- package/dist/main.js +35 -146
- package/dist/process/PrivateRuntimeRoot.js +3 -2
- package/dist/process/ProcessOwnership.js +35 -0
- package/dist/process/ProviderProcess.js +2 -0
- package/dist/replay/JavaScriptReplayWorker.js +64 -50
- package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
- package/dist/replay/ReplayOutcome.js +95 -0
- package/dist/replay/ReplayProcessLifecycle.js +71 -0
- package/dist/server/ProcessCaptureElicitation.js +157 -0
- package/dist/server/createServer.js +124 -56
- package/dist/server/javascriptApplicationResult.js +85 -0
- package/dist/server/registerApplicationTools/characterization.js +57 -0
- package/dist/server/registerApplicationTools/compareVersions.js +34 -0
- package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
- package/dist/server/registerApplicationTools/coverage.js +84 -0
- package/dist/server/registerApplicationTools/helpers.js +42 -0
- package/dist/server/registerApplicationTools/traceFeature.js +26 -0
- package/dist/server/registerApplicationTools/types.js +1 -0
- package/dist/server/registerApplicationTools.js +10 -112
- package/dist/server/registerBrowserTools.js +59 -83
- package/dist/server/registerElectronTools.js +48 -49
- package/dist/server/registerEnhancedTools.js +34 -42
- package/dist/server/registerEvidenceResources.js +56 -0
- package/dist/server/registerInvestigationTools/helpers.js +74 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +83 -116
- package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
- package/dist/server/registerManagedTools.js +18 -1
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
- package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
- package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
- package/dist/server/registerManagedWorkflowTools/types.js +1 -0
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
- package/dist/server/registerManagedWorkflowTools.js +10 -274
- package/dist/server/registerOfficialTools.js +73 -59
- package/dist/server/registerSessionRecordTools.js +137 -0
- package/dist/server/registerSessionStatusTool.js +97 -26
- package/dist/server/registerSessionTools.js +60 -164
- package/dist/server/sessionAvailabilityPolicy.js +10 -0
- package/dist/server/toolRegistrationOptions.js +101 -3
- package/dist/server/toolResult.js +15 -4
- package/package.json +11 -11
- package/skills/reverse-engineer-anything/SKILL.md +76 -0
- package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +25 -0
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
- package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
- package/scripts/prepare-node-pty.mjs +0 -35
- package/scripts/rebuild-native.mjs +0 -22
- package/skills/rea-analysis/SKILL.md +0 -222
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { managedFailure } from "./ManagedReaderFailure.js";
|
|
2
|
+
import { computeRowSize, } from "./ManagedMetadataRowSizes.js";
|
|
2
3
|
export const METADATA_TABLE_NAMES = [
|
|
3
4
|
"Module",
|
|
4
5
|
"TypeRef",
|
|
@@ -114,110 +115,7 @@ const codedSize = (name, rowCounts) => {
|
|
|
114
115
|
return maximum < 2 ** (16 - descriptor.bits) ? 2 : 4;
|
|
115
116
|
};
|
|
116
117
|
const tableSize = (index, rows) => (rows[index] ?? 0) < 0x1_0000 ? 2 : 4;
|
|
117
|
-
const
|
|
118
|
-
const t = (index) => tableSize(index, rowCounts);
|
|
119
|
-
const c = (name) => codedSize(name, rowCounts);
|
|
120
|
-
const { string: s, guid: g, blob: b } = heaps;
|
|
121
|
-
switch (table) {
|
|
122
|
-
case 0:
|
|
123
|
-
return 2 + s + g * 3;
|
|
124
|
-
case 1:
|
|
125
|
-
return c("ResolutionScope") + s * 2;
|
|
126
|
-
case 2:
|
|
127
|
-
return 4 + s * 2 + c("TypeDefOrRef") + t(4) + t(6);
|
|
128
|
-
case 3:
|
|
129
|
-
return t(4);
|
|
130
|
-
case 4:
|
|
131
|
-
return 2 + s + b;
|
|
132
|
-
case 5:
|
|
133
|
-
return t(6);
|
|
134
|
-
case 6:
|
|
135
|
-
return 8 + s + b + t(8);
|
|
136
|
-
case 7:
|
|
137
|
-
return t(8);
|
|
138
|
-
case 8:
|
|
139
|
-
return 4 + s;
|
|
140
|
-
case 9:
|
|
141
|
-
return t(2) + c("TypeDefOrRef");
|
|
142
|
-
case 10:
|
|
143
|
-
return c("MemberRefParent") + s + b;
|
|
144
|
-
case 11:
|
|
145
|
-
return 2 + c("HasConstant") + b;
|
|
146
|
-
case 12:
|
|
147
|
-
return c("HasCustomAttribute") + c("CustomAttributeType") + b;
|
|
148
|
-
case 13:
|
|
149
|
-
return c("HasFieldMarshal") + b;
|
|
150
|
-
case 14:
|
|
151
|
-
return 2 + c("HasDeclSecurity") + b;
|
|
152
|
-
case 15:
|
|
153
|
-
return 6 + t(2);
|
|
154
|
-
case 16:
|
|
155
|
-
return 4 + t(4);
|
|
156
|
-
case 17:
|
|
157
|
-
return b;
|
|
158
|
-
case 18:
|
|
159
|
-
return t(2) + t(20);
|
|
160
|
-
case 19:
|
|
161
|
-
return t(20);
|
|
162
|
-
case 20:
|
|
163
|
-
return 2 + s + c("TypeDefOrRef");
|
|
164
|
-
case 21:
|
|
165
|
-
return t(2) + t(23);
|
|
166
|
-
case 22:
|
|
167
|
-
return t(23);
|
|
168
|
-
case 23:
|
|
169
|
-
return 2 + s + b;
|
|
170
|
-
case 24:
|
|
171
|
-
return 2 + t(6) + c("HasSemantics");
|
|
172
|
-
case 25:
|
|
173
|
-
return t(2) + c("MethodDefOrRef") * 2;
|
|
174
|
-
case 26:
|
|
175
|
-
return s;
|
|
176
|
-
case 27:
|
|
177
|
-
return b;
|
|
178
|
-
case 28:
|
|
179
|
-
return 2 + c("MemberForwarded") + s + t(26);
|
|
180
|
-
case 29:
|
|
181
|
-
return 4 + t(4);
|
|
182
|
-
case 30:
|
|
183
|
-
return 8;
|
|
184
|
-
case 31:
|
|
185
|
-
return 4;
|
|
186
|
-
case 32:
|
|
187
|
-
return 16 + b + s * 2;
|
|
188
|
-
case 33:
|
|
189
|
-
return 4;
|
|
190
|
-
case 34:
|
|
191
|
-
return 12;
|
|
192
|
-
case 35:
|
|
193
|
-
return 12 + b * 2 + s * 2;
|
|
194
|
-
case 36:
|
|
195
|
-
return 4 + t(35);
|
|
196
|
-
case 37:
|
|
197
|
-
return 12 + t(35);
|
|
198
|
-
case 38:
|
|
199
|
-
return 4 + s + b;
|
|
200
|
-
case 39:
|
|
201
|
-
return 8 + s * 2 + c("Implementation");
|
|
202
|
-
case 40:
|
|
203
|
-
return 8 + s + c("Implementation");
|
|
204
|
-
case 41:
|
|
205
|
-
return t(2) * 2;
|
|
206
|
-
case 42:
|
|
207
|
-
return 4 + c("TypeOrMethodDef") + s;
|
|
208
|
-
case 43:
|
|
209
|
-
return c("MethodDefOrRef") + b;
|
|
210
|
-
case 44:
|
|
211
|
-
return t(42) + c("TypeDefOrRef");
|
|
212
|
-
default:
|
|
213
|
-
throw managedFailure("invalid-tables", "metadata.tables", `Metadata table ${String(table)} is unsupported`);
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
/** Parse ECMA-335 stream and table layout with checked byte extents. */
|
|
217
|
-
export const readManagedMetadataLayout = (artifact, rootOffset, size, maxTableRows) => {
|
|
218
|
-
if (size < 20 || rootOffset < 0 || rootOffset > artifact.length - size)
|
|
219
|
-
throw managedFailure("invalid-metadata-root", "metadata.root", "CLI metadata directory leaves the artifact byte range", rootOffset);
|
|
220
|
-
const bytes = artifact.subarray(rootOffset, rootOffset + size);
|
|
118
|
+
const readMetadataStreams = (bytes, rootOffset) => {
|
|
221
119
|
if (bytes.readUInt32LE(0) !== 0x424a_5342)
|
|
222
120
|
throw managedFailure("invalid-metadata-root", "metadata.signature", "CLI metadata signature is not BSJB", rootOffset);
|
|
223
121
|
const versionLength = bytes.readUInt32LE(12);
|
|
@@ -249,10 +147,13 @@ export const readManagedMetadataLayout = (artifact, rootOffset, size, maxTableRo
|
|
|
249
147
|
});
|
|
250
148
|
cursor = named.next;
|
|
251
149
|
}
|
|
150
|
+
return { streams, version };
|
|
151
|
+
};
|
|
152
|
+
const readTablesHeader = (bytes, streams) => {
|
|
252
153
|
const tablesStream = streamByName(streams, ["#~", "#-"]);
|
|
253
154
|
if (tablesStream === undefined)
|
|
254
155
|
throw managedFailure("missing-stream", "metadata.tables", "Required metadata table stream #~ or #- is absent");
|
|
255
|
-
const tableBytes =
|
|
156
|
+
const tableBytes = bytes.subarray(tablesStream.offset, tablesStream.offset + tablesStream.size);
|
|
256
157
|
requireRange(tableBytes, 0, 24, "metadata.tables-header");
|
|
257
158
|
const heapSizes = tableBytes[6] ?? 0;
|
|
258
159
|
const heaps = {
|
|
@@ -263,6 +164,9 @@ export const readManagedMetadataLayout = (artifact, rootOffset, size, maxTableRo
|
|
|
263
164
|
const valid = tableBytes.readBigUInt64LE(8);
|
|
264
165
|
if ((valid & ~SUPPORTED_TABLE_MASK) !== 0n)
|
|
265
166
|
throw managedFailure("invalid-tables", "metadata.valid-mask", "Metadata valid mask names unsupported tables outside the admitted ECMA-335 range", tablesStream.offset + 8);
|
|
167
|
+
return { tableBytes, tablesOffset: tablesStream.offset, heaps, valid };
|
|
168
|
+
};
|
|
169
|
+
const readRowCounts = (tableBytes, valid, maxTableRows, tablesOffset) => {
|
|
266
170
|
const rowCounts = Array(METADATA_TABLE_NAMES.length).fill(0);
|
|
267
171
|
let tableCursor = 24;
|
|
268
172
|
for (let index = 0; index < METADATA_TABLE_NAMES.length; index += 1) {
|
|
@@ -271,30 +175,64 @@ export const readManagedMetadataLayout = (artifact, rootOffset, size, maxTableRo
|
|
|
271
175
|
requireRange(tableBytes, tableCursor, 4, "metadata.table-row-count");
|
|
272
176
|
const count = tableBytes.readUInt32LE(tableCursor);
|
|
273
177
|
if (count > maxTableRows)
|
|
274
|
-
throw managedFailure("limit-exceeded", `metadata.${METADATA_TABLE_NAMES[index] ?? String(index)}`, `Metadata table row count ${String(count)} exceeds max_table_rows ${String(maxTableRows)}`,
|
|
178
|
+
throw managedFailure("limit-exceeded", `metadata.${METADATA_TABLE_NAMES[index] ?? String(index)}`, `Metadata table row count ${String(count)} exceeds max_table_rows ${String(maxTableRows)}`, tablesOffset + tableCursor);
|
|
275
179
|
rowCounts[index] = count;
|
|
276
180
|
tableCursor += 4;
|
|
277
181
|
}
|
|
182
|
+
return rowCounts;
|
|
183
|
+
};
|
|
184
|
+
const buildRowSizeContext = (rowCounts, heaps) => ({
|
|
185
|
+
tableSize: (index) => tableSize(index, rowCounts),
|
|
186
|
+
codedSize: (name) => codedSize(name, rowCounts),
|
|
187
|
+
stringSize: heaps.string,
|
|
188
|
+
guidSize: heaps.guid,
|
|
189
|
+
blobSize: heaps.blob,
|
|
190
|
+
});
|
|
191
|
+
const buildMetadataTables = ({ tableBytes, rowCounts, heaps, valid, tablesOffset, }) => {
|
|
278
192
|
const tables = new Map();
|
|
193
|
+
const context = buildRowSizeContext(rowCounts, heaps);
|
|
194
|
+
let tableCursor = 24;
|
|
195
|
+
for (let index = 0; index < METADATA_TABLE_NAMES.length; index += 1) {
|
|
196
|
+
if ((valid & (1n << BigInt(index))) === 0n)
|
|
197
|
+
continue;
|
|
198
|
+
tableCursor += 4;
|
|
199
|
+
}
|
|
279
200
|
for (let index = 0; index < METADATA_TABLE_NAMES.length; index += 1) {
|
|
280
201
|
const count = rowCounts[index] ?? 0;
|
|
281
202
|
if ((valid & (1n << BigInt(index))) === 0n)
|
|
282
203
|
continue;
|
|
283
|
-
const sizeOfRow =
|
|
204
|
+
const sizeOfRow = computeRowSize(index, context);
|
|
284
205
|
const byteLength = count * sizeOfRow;
|
|
285
206
|
if (!Number.isSafeInteger(byteLength))
|
|
286
|
-
throw managedFailure("invalid-tables", "metadata.tables", "Metadata table byte size overflowed",
|
|
207
|
+
throw managedFailure("invalid-tables", "metadata.tables", "Metadata table byte size overflowed", tablesOffset + tableCursor);
|
|
287
208
|
requireRange(tableBytes, tableCursor, byteLength, "metadata.table-data");
|
|
288
209
|
tables.set(index, {
|
|
289
210
|
index,
|
|
290
211
|
name: METADATA_TABLE_NAMES[index] ?? `Table${String(index)}`,
|
|
291
212
|
rowCount: count,
|
|
292
213
|
rowSize: sizeOfRow,
|
|
293
|
-
offset:
|
|
214
|
+
offset: tablesOffset + tableCursor,
|
|
294
215
|
});
|
|
295
216
|
tableCursor += byteLength;
|
|
296
217
|
}
|
|
297
|
-
|
|
218
|
+
return tables;
|
|
219
|
+
};
|
|
220
|
+
/** Parse ECMA-335 stream and table layout with checked byte extents. */
|
|
221
|
+
export const readManagedMetadataLayout = (artifact, rootOffset, size, maxTableRows) => {
|
|
222
|
+
if (size < 20 || rootOffset < 0 || rootOffset > artifact.length - size)
|
|
223
|
+
throw managedFailure("invalid-metadata-root", "metadata.root", "CLI metadata directory leaves the artifact byte range", rootOffset);
|
|
224
|
+
const bytes = artifact.subarray(rootOffset, rootOffset + size);
|
|
225
|
+
const { streams, version } = readMetadataStreams(bytes, rootOffset);
|
|
226
|
+
const { tableBytes, tablesOffset, heaps, valid } = readTablesHeader(artifact, streams);
|
|
227
|
+
const rowCounts = readRowCounts(tableBytes, valid, maxTableRows, tablesOffset);
|
|
228
|
+
const tables = buildMetadataTables({
|
|
229
|
+
tableBytes,
|
|
230
|
+
rowCounts,
|
|
231
|
+
heaps,
|
|
232
|
+
valid,
|
|
233
|
+
tablesOffset,
|
|
234
|
+
});
|
|
235
|
+
return {
|
|
298
236
|
rootOffset,
|
|
299
237
|
size,
|
|
300
238
|
version,
|
|
@@ -311,7 +249,6 @@ export const readManagedMetadataLayout = (artifact, rootOffset, size, maxTableRo
|
|
|
311
249
|
tableIndexSize: (index) => tableSize(index, rowCounts),
|
|
312
250
|
codedIndexSize: (name) => codedSize(name, rowCounts),
|
|
313
251
|
};
|
|
314
|
-
return layout;
|
|
315
252
|
};
|
|
316
253
|
/** Resolve a one-based metadata row to its exact file offset. */
|
|
317
254
|
export const metadataRowOffset = (layout, table, row) => {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { managedFailure } from "./ManagedReaderFailure.js";
|
|
2
|
+
const ROW_SIZE_FACTORIES = [
|
|
3
|
+
({ stringSize: s, guidSize: g }) => 2 + s + g * 3,
|
|
4
|
+
({ codedSize: c, stringSize: s }) => c("ResolutionScope") + s * 2,
|
|
5
|
+
({ tableSize: t, codedSize: c, stringSize: s }) => 4 + s * 2 + c("TypeDefOrRef") + t(4) + t(6),
|
|
6
|
+
({ tableSize: t }) => t(4),
|
|
7
|
+
({ stringSize: s, blobSize: b }) => 2 + s + b,
|
|
8
|
+
({ tableSize: t }) => t(6),
|
|
9
|
+
({ tableSize: t, stringSize: s, blobSize: b }) => 8 + s + b + t(8),
|
|
10
|
+
({ tableSize: t }) => t(8),
|
|
11
|
+
({ stringSize: s }) => 4 + s,
|
|
12
|
+
({ tableSize: t, codedSize: c }) => t(2) + c("TypeDefOrRef"),
|
|
13
|
+
({ codedSize: c, stringSize: s, blobSize: b }) => c("MemberRefParent") + s + b,
|
|
14
|
+
({ codedSize: c, blobSize: b }) => 2 + c("HasConstant") + b,
|
|
15
|
+
({ codedSize: c, blobSize: b }) => c("HasCustomAttribute") + c("CustomAttributeType") + b,
|
|
16
|
+
({ codedSize: c, blobSize: b }) => c("HasFieldMarshal") + b,
|
|
17
|
+
({ codedSize: c, blobSize: b }) => 2 + c("HasDeclSecurity") + b,
|
|
18
|
+
({ tableSize: t }) => 6 + t(2),
|
|
19
|
+
({ tableSize: t }) => 4 + t(4),
|
|
20
|
+
({ blobSize: b }) => b,
|
|
21
|
+
({ tableSize: t }) => t(2) + t(20),
|
|
22
|
+
({ tableSize: t }) => t(20),
|
|
23
|
+
({ stringSize: s, codedSize: c }) => 2 + s + c("TypeDefOrRef"),
|
|
24
|
+
({ tableSize: t }) => t(2) + t(23),
|
|
25
|
+
({ tableSize: t }) => t(23),
|
|
26
|
+
({ stringSize: s, blobSize: b }) => 2 + s + b,
|
|
27
|
+
({ tableSize: t, codedSize: c }) => 2 + t(6) + c("HasSemantics"),
|
|
28
|
+
({ tableSize: t, codedSize: c }) => t(2) + c("MethodDefOrRef") * 2,
|
|
29
|
+
({ stringSize: s }) => s,
|
|
30
|
+
({ blobSize: b }) => b,
|
|
31
|
+
({ tableSize: t, codedSize: c, stringSize: s }) => 2 + c("MemberForwarded") + s + t(26),
|
|
32
|
+
({ tableSize: t }) => 4 + t(4),
|
|
33
|
+
() => 8,
|
|
34
|
+
() => 4,
|
|
35
|
+
({ blobSize: b, stringSize: s }) => 16 + b + s * 2,
|
|
36
|
+
() => 4,
|
|
37
|
+
() => 12,
|
|
38
|
+
({ blobSize: b, stringSize: s }) => 12 + b * 2 + s * 2,
|
|
39
|
+
({ tableSize: t }) => 4 + t(35),
|
|
40
|
+
({ tableSize: t }) => 12 + t(35),
|
|
41
|
+
({ stringSize: s, blobSize: b }) => 4 + s + b,
|
|
42
|
+
({ stringSize: s, codedSize: c }) => 8 + s * 2 + c("Implementation"),
|
|
43
|
+
({ stringSize: s, codedSize: c }) => 8 + s + c("Implementation"),
|
|
44
|
+
({ tableSize: t }) => t(2) * 2,
|
|
45
|
+
({ stringSize: s, codedSize: c }) => 4 + c("TypeOrMethodDef") + s,
|
|
46
|
+
({ codedSize: c, blobSize: b }) => c("MethodDefOrRef") + b,
|
|
47
|
+
({ tableSize: t, codedSize: c }) => t(42) + c("TypeDefOrRef"),
|
|
48
|
+
];
|
|
49
|
+
export const computeRowSize = (table, context) => {
|
|
50
|
+
const factory = ROW_SIZE_FACTORIES[table];
|
|
51
|
+
if (factory === undefined)
|
|
52
|
+
throw managedFailure("invalid-tables", "metadata.tables", `Metadata table ${String(table)} is unsupported`);
|
|
53
|
+
return factory(context);
|
|
54
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { decodeInstructions, parseExceptionRegions, } from "./ManagedMemberInstructionDecoder.js";
|
|
2
|
+
import { sha256Bytes } from "./ManagedMetadataHeaps.js";
|
|
3
|
+
const readMethodBodyHeader = (bytes, offset) => {
|
|
4
|
+
const first = bytes.readUInt8(offset);
|
|
5
|
+
if ((first & 3) === 2)
|
|
6
|
+
return {
|
|
7
|
+
format: "tiny",
|
|
8
|
+
size: 1,
|
|
9
|
+
flags: 0,
|
|
10
|
+
maxStack: 8,
|
|
11
|
+
ilSize: first >> 2,
|
|
12
|
+
localSig: 0,
|
|
13
|
+
};
|
|
14
|
+
if ((first & 3) !== 3)
|
|
15
|
+
throw new RangeError("Unsupported method body header");
|
|
16
|
+
if (offset > bytes.length - 12)
|
|
17
|
+
throw new RangeError("Fat method body header leaves artifact");
|
|
18
|
+
const flagsAndSize = bytes.readUInt16LE(offset);
|
|
19
|
+
const headerDwords = flagsAndSize >>> 12;
|
|
20
|
+
if (headerDwords < 3)
|
|
21
|
+
throw new RangeError("Fat method body header is smaller than 12 bytes");
|
|
22
|
+
const size = headerDwords * 4;
|
|
23
|
+
if (offset > bytes.length - size)
|
|
24
|
+
throw new RangeError("Method body header leaves artifact");
|
|
25
|
+
return {
|
|
26
|
+
format: "fat",
|
|
27
|
+
size,
|
|
28
|
+
flags: flagsAndSize & 0x0fff,
|
|
29
|
+
maxStack: bytes.readUInt16LE(offset + 2),
|
|
30
|
+
ilSize: bytes.readUInt32LE(offset + 4),
|
|
31
|
+
localSig: bytes.readUInt32LE(offset + 8),
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export const methodBody = (bytes, pe, rva, limits) => {
|
|
35
|
+
if (rva === 0)
|
|
36
|
+
return emptyMethodBody(rva, "absent", null);
|
|
37
|
+
try {
|
|
38
|
+
const offset = pe.rvaToOffset(rva, 1, "method.body");
|
|
39
|
+
const header = readMethodBodyHeader(bytes, offset);
|
|
40
|
+
if (header.ilSize > limits.maxMethodBodyBytes)
|
|
41
|
+
return oversizedMethodBody(header, rva, offset, limits);
|
|
42
|
+
const ilOffset = offset + header.size;
|
|
43
|
+
if (ilOffset > bytes.length - header.ilSize)
|
|
44
|
+
throw new RangeError("Method IL bytes leave artifact");
|
|
45
|
+
const il = bytes.subarray(ilOffset, ilOffset + header.ilSize);
|
|
46
|
+
const decoded = decodeInstructions(il, limits.maxMethodInstructions);
|
|
47
|
+
const opcodeCounts = {};
|
|
48
|
+
for (const instruction of decoded.parsed)
|
|
49
|
+
opcodeCounts[instruction.opcode] =
|
|
50
|
+
(opcodeCounts[instruction.opcode] ?? 0) + 1;
|
|
51
|
+
const anchors = decoded.parsed
|
|
52
|
+
.map((instruction, index) => ({ instruction, index }))
|
|
53
|
+
.filter(({ instruction }) => instruction.operandKind !== "none")
|
|
54
|
+
.slice(0, limits.instructionAnchorLimit)
|
|
55
|
+
.map(({ instruction }) => ({
|
|
56
|
+
il_offset: instruction.offset,
|
|
57
|
+
opcode: instruction.opcode,
|
|
58
|
+
operand_kind: instruction.operandKind,
|
|
59
|
+
operand: instruction.operand,
|
|
60
|
+
}));
|
|
61
|
+
const normalized = Buffer.from(JSON.stringify(decoded.parsed.map(({ opcode, operandKind, operand }) => [
|
|
62
|
+
opcode,
|
|
63
|
+
operandKind,
|
|
64
|
+
operand,
|
|
65
|
+
])), "utf8");
|
|
66
|
+
const methodEnd = ilOffset + header.ilSize;
|
|
67
|
+
const sectionOffset = (methodEnd + 3) & ~3;
|
|
68
|
+
const status = decoded.issue !== null
|
|
69
|
+
? "malformed"
|
|
70
|
+
: decoded.truncated > 0
|
|
71
|
+
? "partial"
|
|
72
|
+
: "present";
|
|
73
|
+
return {
|
|
74
|
+
status,
|
|
75
|
+
header_format: header.format,
|
|
76
|
+
rva,
|
|
77
|
+
file_offset: offset,
|
|
78
|
+
max_stack: header.maxStack,
|
|
79
|
+
init_locals: (header.flags & 0x10) !== 0,
|
|
80
|
+
local_var_sig_token: header.localSig === 0
|
|
81
|
+
? null
|
|
82
|
+
: `0x${header.localSig.toString(16).padStart(8, "0")}`,
|
|
83
|
+
il_size: header.ilSize,
|
|
84
|
+
il_sha256: sha256Bytes(il),
|
|
85
|
+
normalized_il_sha256: status === "present" ? sha256Bytes(normalized) : null,
|
|
86
|
+
instruction_count: decoded.count,
|
|
87
|
+
decoded_instruction_count: decoded.parsed.length,
|
|
88
|
+
truncated_instructions: decoded.truncated,
|
|
89
|
+
opcode_counts: opcodeCounts,
|
|
90
|
+
anchors,
|
|
91
|
+
exception_regions: header.format === "fat" && (header.flags & 8) !== 0
|
|
92
|
+
? parseExceptionRegions(bytes, sectionOffset, bytes.length)
|
|
93
|
+
: [],
|
|
94
|
+
issue: decoded.issue ??
|
|
95
|
+
(decoded.truncated > 0
|
|
96
|
+
? `Instruction decode reached max_method_instructions ${String(limits.maxMethodInstructions)} before the end of the method body`
|
|
97
|
+
: null),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (cause) {
|
|
101
|
+
return emptyMethodBody(rva, "malformed", cause instanceof Error ? cause.message : "Method body parse failed");
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const emptyMethodBody = (rva, status, issue) => ({
|
|
105
|
+
status,
|
|
106
|
+
header_format: status === "absent" ? "none" : "unknown",
|
|
107
|
+
rva,
|
|
108
|
+
file_offset: null,
|
|
109
|
+
max_stack: null,
|
|
110
|
+
init_locals: null,
|
|
111
|
+
local_var_sig_token: null,
|
|
112
|
+
il_size: 0,
|
|
113
|
+
il_sha256: null,
|
|
114
|
+
normalized_il_sha256: null,
|
|
115
|
+
instruction_count: 0,
|
|
116
|
+
decoded_instruction_count: 0,
|
|
117
|
+
truncated_instructions: 0,
|
|
118
|
+
opcode_counts: {},
|
|
119
|
+
anchors: [],
|
|
120
|
+
exception_regions: [],
|
|
121
|
+
issue,
|
|
122
|
+
});
|
|
123
|
+
const oversizedMethodBody = (header, rva, offset, limits) => ({
|
|
124
|
+
status: "too-large",
|
|
125
|
+
header_format: header.format,
|
|
126
|
+
rva,
|
|
127
|
+
file_offset: offset,
|
|
128
|
+
max_stack: header.maxStack,
|
|
129
|
+
init_locals: (header.flags & 0x10) !== 0,
|
|
130
|
+
local_var_sig_token: header.localSig === 0
|
|
131
|
+
? null
|
|
132
|
+
: `0x${header.localSig.toString(16).padStart(8, "0")}`,
|
|
133
|
+
il_size: header.ilSize,
|
|
134
|
+
il_sha256: null,
|
|
135
|
+
normalized_il_sha256: null,
|
|
136
|
+
instruction_count: 0,
|
|
137
|
+
decoded_instruction_count: 0,
|
|
138
|
+
truncated_instructions: 0,
|
|
139
|
+
opcode_counts: {},
|
|
140
|
+
anchors: [],
|
|
141
|
+
exception_regions: [],
|
|
142
|
+
issue: `Method body exceeds max_method_body_bytes ${String(limits.maxMethodBodyBytes)}`,
|
|
143
|
+
});
|