rea-agents 5.0.0 → 6.0.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 +157 -650
- package/bridge/mitmproxy/capture.py +210 -0
- package/bridge/native/rea_lldb_tracer.py +303 -0
- package/bridge/process/ProcessRunTokenReader.swift +263 -0
- package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
- package/bridge/pwndbg/core_context.py +101 -0
- package/bridge/pwndbg/launch.py +39 -0
- package/bridge/pwndbg/launch_impl.py +34 -0
- package/bridge/pwntools/decoder_runtime.py +59 -0
- package/bridge/pwntools/layout.py +39 -0
- package/bridge/pwntools/layout_impl.py +309 -0
- package/bridge/pwntools/recorded_crash.py +39 -0
- package/bridge/pwntools/recorded_crash_impl.py +143 -0
- package/dist/android/JadxProvider.js +1 -0
- package/dist/application/CapabilityInventory.js +21 -0
- package/dist/application/DirectAnalysis.js +97 -23
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/ReconstructionObligationCandidates.js +5 -1
- package/dist/application/WebNetworkCapturePort.js +1 -0
- package/dist/application/WebNetworkCaptureService.js +132 -0
- package/dist/application/WindowsCapabilities.js +1 -1
- package/dist/application/binary/AnalysisSnapshotCache.js +49 -6
- package/dist/application/binary/BinarySession.js +38 -10
- package/dist/application/binary/BinarySessionOpen.js +16 -3
- package/dist/application/binary/BinarySessionRecords.js +20 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +57 -0
- package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +60 -0
- package/dist/application/evm/EvmInterfacePort.js +1 -0
- package/dist/application/evm/EvmInterfaceService.js +62 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -2
- package/dist/application/javascript/JavaScriptApplicationService.js +15 -2
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +42 -23
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +74 -24
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +23 -10
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +145 -70
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +5 -5
- package/dist/application/{ProcessCli.js → process/ProcessCli.js} +10 -10
- package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +4 -4
- package/dist/artifacts/ArtifactProvider.js +30 -3
- package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
- package/dist/artifacts/ZipArtifactReader.js +3 -0
- package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
- package/dist/artifacts/apple/MachoLoadCommandReader.js +294 -0
- package/dist/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
- package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +3 -3
- package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
- package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
- package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
- package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +3 -3
- package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
- package/dist/artifacts/readStableArtifact.js +20 -4
- package/dist/browser/CdpCaptureEventHandlers.js +90 -2
- package/dist/browser/CdpCaptureEvents.js +9 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +12 -3
- package/dist/browser/history/CaptureFailures.js +101 -0
- package/dist/browser/history/CaptureFormatError.js +10 -0
- package/dist/browser/history/CaptureRedaction.js +65 -0
- package/dist/browser/history/CaptureRelease.js +12 -0
- package/dist/browser/history/HarCapture.js +165 -0
- package/dist/browser/history/HarCaptureAdapter.js +20 -0
- package/dist/browser/history/HarCaptureProcess.js +57 -0
- package/dist/browser/history/HarJson.js +91 -0
- package/dist/browser/history/HarSchema.js +72 -0
- package/dist/browser/history/HistoricalCaptureDecoder.js +186 -0
- package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
- package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
- package/dist/cli/artifactCommands.js +26 -1
- package/dist/cli/binaryDiagnosticsCommands.js +39 -0
- package/dist/cli/coreAnalysisCommands.js +2 -2
- package/dist/cli/coreBinaryCommands.js +8 -8
- package/dist/cli/electronCommands.js +16 -9
- package/dist/cli/evmCommands.js +24 -0
- package/dist/cli/firmwareCommands.js +6 -3
- package/dist/cli/javascriptApplicationAnalysis.js +16 -3
- package/dist/cli/jsonOutput.js +133 -0
- package/dist/cli/nativeCallCommands.js +35 -0
- package/dist/cli/processCommands.js +1 -1
- package/dist/cli/streamedJsonOutput.js +56 -0
- package/dist/cli/utilityCommands.js +2 -0
- package/dist/cli/webNetworkCaptureCommands.js +40 -0
- package/dist/cli.js +9 -3
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +6 -0
- package/dist/cliJsonInput.js +30 -1
- package/dist/cliOutput.js +21 -6
- package/dist/composition/binaryDiagnostics.js +8 -0
- package/dist/composition/evm.js +4 -0
- package/dist/composition/webNetworkCaptures.js +6 -0
- package/dist/contracts/artifactToolContracts.js +6 -0
- package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
- package/dist/contracts/browserToolContracts.js +4 -3
- package/dist/contracts/errorSchemas.js +8 -1
- package/dist/contracts/evm/evmToolContracts.js +20 -0
- package/dist/contracts/investigationExamples.js +2 -2
- package/dist/contracts/managed/managedToolContracts.js +7 -3
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
- package/dist/contracts/native/nativeToolContracts.js +17 -1
- package/dist/contracts/officialToolContracts.js +12 -9
- package/dist/contracts/process/processCaptureExample.js +2 -0
- package/dist/contracts/sessionLifecycleInputs.js +22 -5
- package/dist/contracts/sessionStatusContract.js +10 -2
- package/dist/contracts/sessionToolContracts.js +8 -1
- package/dist/contracts/sessionToolSchemas.js +10 -3
- package/dist/contracts/toolContractExamples.js +1 -1
- package/dist/contracts/toolContracts.js +6 -0
- package/dist/contracts/toolEffects.js +30 -0
- package/dist/contracts/toolOutputSchemaGroups.js +5 -1
- package/dist/contracts/toolOutputSchemaPrimitives.js +1 -1
- package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
- package/dist/domain/analysisErrorBase.js +15 -0
- package/dist/domain/analysisErrorCore.js +59 -5
- package/dist/domain/analysisErrorPresentation.js +29 -1
- package/dist/domain/analysisErrorProjection.js +52 -2
- package/dist/domain/analysisSnapshot.js +166 -2
- package/dist/domain/apple/dyldPaths.js +81 -0
- package/dist/domain/apple/dylibResolution.js +367 -0
- package/dist/domain/apple/dylibResolutionFindings.js +75 -0
- package/dist/domain/artifactPathSyntax.js +1 -1
- package/dist/domain/browserObservation.js +1 -1
- package/dist/domain/browserObservationSchemas.js +13 -0
- package/dist/domain/browserScenarioValues.js +9 -2
- package/dist/domain/callPathSchemas.js +1 -1
- package/dist/domain/canonicalDigest.js +13 -1
- package/dist/domain/changedBehavior.js +3 -3
- package/dist/domain/comparisonStatus.js +2 -30
- package/dist/domain/conformanceTrustGate.js +0 -16
- package/dist/domain/evidence.js +17 -5
- package/dist/domain/evm/evmInterface.js +63 -0
- package/dist/domain/explicitSensitiveFailure.js +92 -0
- package/dist/domain/explicitSensitiveValues.js +10 -0
- package/dist/domain/firmware/firmwareAnalysis.js +8 -1
- package/dist/domain/javascript/electronActiveObservation.js +9 -4
- package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
- package/dist/domain/javascript/javascriptSemanticGraph.js +21 -5
- package/dist/domain/jsonValue.js +4 -0
- package/dist/domain/localPath.js +2 -0
- package/dist/domain/native/binaryLayout.js +357 -0
- package/dist/domain/native/nativeCallObservation.js +164 -0
- package/dist/domain/native/objcSwiftMetadata.js +0 -39
- package/dist/domain/native/recordedCrash.js +266 -0
- package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
- package/dist/domain/{processCapture.js → process/processCapture.js} +139 -2
- package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
- package/dist/domain/process/processCaptureParsing.js +54 -0
- package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
- package/dist/domain/{processComparison.js → process/processComparison.js} +1 -1
- package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
- package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
- package/dist/domain/providerSelectionError.js +4 -2
- package/dist/domain/reconstructionVerification.js +3 -3
- package/dist/domain/reconstructionVerificationSchemas.js +1 -1
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +3 -3
- package/dist/domain/webCaptureDiff.js +1 -0
- package/dist/domain/webNetworkCapture.js +118 -0
- package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
- package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
- package/dist/dotnet/ManagedMemberInspector.js +4 -2
- package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
- package/dist/dotnet/ManagedMemberRows.js +14 -3
- package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
- package/dist/dotnet/ManagedMetadataInventory.js +38 -28
- package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
- package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
- package/dist/dotnet/ManagedPeReader.js +11 -0
- package/dist/evm/EvmBytecodeCarrier.js +21 -0
- package/dist/evm/EvmWorkerLimits.js +40 -0
- package/dist/evm/EvmoleFailures.js +126 -0
- package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
- package/dist/evm/EvmoleInterfaceProvider.js +273 -0
- package/dist/evm/EvmoleInterfaceWorker.js +87 -0
- package/dist/evm/EvmoleRelease.js +16 -0
- package/dist/firmware/FirmwareCommand.js +1 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraLauncher.js +1 -0
- package/dist/ghidra/GhidraProvider.js +2 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +1 -1
- package/dist/hopper/BridgeLauncher.js +2 -0
- package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
- package/dist/javascript/recovery/WakaruCommand.js +3 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +1 -0
- package/dist/native/CommandRunner.js +2 -1
- package/dist/native/LldbCallTracer.js +278 -0
- package/dist/native/NativeCallObservation.js +135 -0
- package/dist/native/NativeMacOSProvider.js +19 -3
- package/dist/native/NativeMacOSProviderMetadata.js +8 -3
- package/dist/native/pwndbg/PwndbgCoreContext.js +160 -0
- package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
- package/dist/native/pwntools/PwntoolsFailures.js +180 -0
- package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
- package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
- package/dist/native/pwntools/PwntoolsRelease.js +19 -0
- package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
- package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +101 -0
- package/dist/process/DarwinProcessRunTokenReader.js +294 -0
- package/dist/process/OwnedCommand.js +113 -0
- package/dist/process/ProcessOwnership.js +263 -33
- package/dist/process/ProcessOwnershipObservation.js +161 -24
- package/dist/process/ProviderProcess.js +30 -3
- package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
- package/dist/{application → process/capture}/ProcessCaptureError.js +17 -1
- package/dist/process/capture/ProcessCaptureLifecycle.js +615 -0
- package/dist/{application → process/capture}/ProcessHarness.js +195 -29
- package/dist/{application → process/capture}/ProcessSampling.js +2 -2
- package/dist/server/createServer.js +22 -0
- package/dist/server/promptCompletion.js +10 -3
- package/dist/server/registerBinaryDiagnosticsTools.js +17 -0
- package/dist/server/registerEvidenceTools.js +1 -1
- package/dist/server/registerEvmTools.js +17 -0
- package/dist/server/registerProcessComparisonTool.js +1 -1
- package/dist/server/registerRecordedCrashTools.js +17 -0
- package/dist/server/registerSessionTools.js +2 -2
- package/dist/server/registerWebNetworkCaptureTool.js +28 -0
- package/dist/server/sessionAvailabilityPolicy.js +3 -0
- package/dist/server/sessionToolPolicies.js +1 -1
- package/dist/server/toolResult.js +1 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +37 -9
- package/scripts/rea.mjs +11 -3
- package/skills/reverse-engineer-anything/SKILL.md +23 -3
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
- package/third_party/README.md +60 -0
- package/third_party/evmole/LICENSE +21 -0
- package/third_party/evmole/README.md +22 -0
- package/third_party/pwndbg/LICENSE.md +21 -0
- package/third_party/pwndbg/README.md +23 -0
- package/third_party/pwntools/README.md +40 -0
- package/dist/application/AuthorizedArtifactInventory.js +0 -7
- package/dist/application/ProcessCaptureLifecycle.js +0 -299
- package/dist/application/StoreFileLock.js +0 -124
- package/dist/contracts/processCaptureExample.js +0 -2
- package/dist/domain/bytecodeProvider.js +0 -178
- package/dist/domain/customProtocolCapture.js +0 -137
- package/dist/domain/eventProcessTree.js +0 -225
- package/dist/domain/mobileApplicationInvestigation.js +0 -159
- package/dist/domain/packageAnalysis.js +0 -123
- package/dist/domain/peInspection.js +0 -197
- package/dist/domain/processCaptureParsing.js +0 -21
- package/dist/domain/protocolCapture.js +0 -217
- package/dist/domain/runtimeIdentification.js +0 -212
- package/dist/generatedMcpToolCatalog.js +0 -37
- /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
- /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
- /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
- /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
- /package/dist/domain/{processScenario.js → process/processScenario.js} +0 -0
- /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
- /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
- /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
- /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
- /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
- /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
- /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
- /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
- /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
- /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
- /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { jsonValueSchema } from "./jsonValue.js";
|
|
3
|
-
/** Supported transport types for custom protocol capture. */
|
|
4
|
-
export const transportTypeSchema = z.enum([
|
|
5
|
-
"tcp",
|
|
6
|
-
"udp",
|
|
7
|
-
"ipc",
|
|
8
|
-
"unix-socket",
|
|
9
|
-
"named-pipe",
|
|
10
|
-
"xpc",
|
|
11
|
-
]);
|
|
12
|
-
/** Direction of a protocol frame. */
|
|
13
|
-
export const frameDirectionSchema = z.enum(["sent", "received", "intercepted"]);
|
|
14
|
-
/** A captured protocol frame. */
|
|
15
|
-
export const protocolFrameSchema = z.strictObject({
|
|
16
|
-
/** Monotonic sequence number. */
|
|
17
|
-
sequence: z.number().int().nonnegative(),
|
|
18
|
-
/** Timestamp in milliseconds. */
|
|
19
|
-
at_ms: z.number().int().nonnegative(),
|
|
20
|
-
/** Transport type. */
|
|
21
|
-
transport: transportTypeSchema,
|
|
22
|
-
/** Direction of the frame. */
|
|
23
|
-
direction: frameDirectionSchema,
|
|
24
|
-
/** Source process identity. */
|
|
25
|
-
source_pid: z.number().int().nullable(),
|
|
26
|
-
/** Destination process identity. */
|
|
27
|
-
dest_pid: z.number().int().nullable(),
|
|
28
|
-
/** Endpoint address (IP:port, socket path, pipe name). */
|
|
29
|
-
source_endpoint: z.string().nullable(),
|
|
30
|
-
/** Destination endpoint. */
|
|
31
|
-
dest_endpoint: z.string().nullable(),
|
|
32
|
-
/** Raw frame data as base64. */
|
|
33
|
-
raw_data: z.string().nullable(),
|
|
34
|
-
/** Decoded/parsed frame content if known. */
|
|
35
|
-
decoded_content: jsonValueSchema.nullable(),
|
|
36
|
-
/** Frame size in bytes. */
|
|
37
|
-
size: z.number().int().nonnegative(),
|
|
38
|
-
/** Whether the frame was truncated. */
|
|
39
|
-
truncated: z.boolean().default(false),
|
|
40
|
-
});
|
|
41
|
-
/** Authentication flow stage. */
|
|
42
|
-
export const authStageSchema = z.enum([
|
|
43
|
-
"init",
|
|
44
|
-
"challenge",
|
|
45
|
-
"response",
|
|
46
|
-
"token_exchange",
|
|
47
|
-
"renewal",
|
|
48
|
-
"revocation",
|
|
49
|
-
"failure",
|
|
50
|
-
"success",
|
|
51
|
-
]);
|
|
52
|
-
/** Token lifecycle event. */
|
|
53
|
-
export const tokenLifecycleEventSchema = z.enum([
|
|
54
|
-
"issued",
|
|
55
|
-
"refreshed",
|
|
56
|
-
"expired",
|
|
57
|
-
"revoked",
|
|
58
|
-
"renewed",
|
|
59
|
-
]);
|
|
60
|
-
/** A captured authentication flow event. */
|
|
61
|
-
export const authFlowEventSchema = z.strictObject({
|
|
62
|
-
/** Monotonic sequence number. */
|
|
63
|
-
sequence: z.number().int().nonnegative(),
|
|
64
|
-
/** Timestamp in milliseconds. */
|
|
65
|
-
at_ms: z.number().int().nonnegative(),
|
|
66
|
-
/** Authentication stage. */
|
|
67
|
-
stage: authStageSchema,
|
|
68
|
-
/** Protocol used. */
|
|
69
|
-
protocol: z.string().min(1),
|
|
70
|
-
/** Token type if applicable. */
|
|
71
|
-
token_type: z.string().nullable(),
|
|
72
|
-
/** Token lifecycle event. */
|
|
73
|
-
token_lifecycle: tokenLifecycleEventSchema.nullable(),
|
|
74
|
-
/** Correlation ID linking challenge-response pairs. */
|
|
75
|
-
correlation_id: z.string().nullable(),
|
|
76
|
-
/** Whether the capture producer marked credentials as redacted. */
|
|
77
|
-
credentials_redacted: z.boolean().default(false),
|
|
78
|
-
/** Whether the authentication succeeded. */
|
|
79
|
-
succeeded: z.boolean().default(false),
|
|
80
|
-
/** Error message if authentication failed. */
|
|
81
|
-
error: z.string().nullable(),
|
|
82
|
-
});
|
|
83
|
-
/** A captured protocol session. */
|
|
84
|
-
export const customProtocolCaptureSchema = z.strictObject({
|
|
85
|
-
/** Transport type for this session. */
|
|
86
|
-
transport: transportTypeSchema,
|
|
87
|
-
/** Captured frames in order. */
|
|
88
|
-
frames: z.array(protocolFrameSchema),
|
|
89
|
-
/** Authentication flow events. */
|
|
90
|
-
auth_events: z.array(authFlowEventSchema).default([]),
|
|
91
|
-
/** Whether any frame was truncated. */
|
|
92
|
-
has_truncated: z.boolean().default(false),
|
|
93
|
-
/** Whether the capture producer detected credential content. */
|
|
94
|
-
credentials_detected: z.boolean().default(false),
|
|
95
|
-
});
|
|
96
|
-
/** Correlate a frame with process identity. */
|
|
97
|
-
export function correlateProcessIdentity(frame, pid) {
|
|
98
|
-
return frame.source_pid === pid || frame.dest_pid === pid;
|
|
99
|
-
}
|
|
100
|
-
/** Check if a frame contains credential-like content. */
|
|
101
|
-
export function looksLikeCredentialFrame(frame) {
|
|
102
|
-
const patterns = [
|
|
103
|
-
"password",
|
|
104
|
-
"token",
|
|
105
|
-
"secret",
|
|
106
|
-
"api_key",
|
|
107
|
-
"apikey",
|
|
108
|
-
"authorization",
|
|
109
|
-
"credential",
|
|
110
|
-
];
|
|
111
|
-
const content = JSON.stringify(frame.decoded_content ?? "").toLowerCase();
|
|
112
|
-
return patterns.some((p) => content.includes(p));
|
|
113
|
-
}
|
|
114
|
-
/** Filter frames by transport type. */
|
|
115
|
-
export function framesByTransport(frames, transport) {
|
|
116
|
-
return frames.filter((f) => f.transport === transport);
|
|
117
|
-
}
|
|
118
|
-
/** Get all authentication flow events for a specific protocol. */
|
|
119
|
-
export function authEventsByProtocol(events, protocol) {
|
|
120
|
-
return events.filter((e) => e.protocol === protocol);
|
|
121
|
-
}
|
|
122
|
-
/** Get successful authentication events. */
|
|
123
|
-
export function successfulAuthEvents(events) {
|
|
124
|
-
return events.filter((e) => e.succeeded);
|
|
125
|
-
}
|
|
126
|
-
/** Get failed authentication events. */
|
|
127
|
-
export function failedAuthEvents(events) {
|
|
128
|
-
return events.filter((e) => !e.succeeded);
|
|
129
|
-
}
|
|
130
|
-
/** Compute the duration of an authentication flow in milliseconds. */
|
|
131
|
-
export function authFlowDuration(events) {
|
|
132
|
-
const first = events.at(0);
|
|
133
|
-
const last = events.at(-1);
|
|
134
|
-
if (first === undefined || last === undefined)
|
|
135
|
-
return null;
|
|
136
|
-
return last.at_ms - first.at_ms;
|
|
137
|
-
}
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
/** Event types for event-backed process-tree capture. */
|
|
3
|
-
export const processEventTypeSchema = z.enum([
|
|
4
|
-
"spawn",
|
|
5
|
-
"exit",
|
|
6
|
-
"re_exec",
|
|
7
|
-
"reparent",
|
|
8
|
-
"signal",
|
|
9
|
-
"name_change",
|
|
10
|
-
"thread_create",
|
|
11
|
-
"thread_exit",
|
|
12
|
-
]);
|
|
13
|
-
/** A single event-backed process-tree event. */
|
|
14
|
-
export const processTreeEventSchema = z.strictObject({
|
|
15
|
-
/** Monotonic event sequence number. */
|
|
16
|
-
sequence: z.number().int().nonnegative(),
|
|
17
|
-
/** Event timestamp in milliseconds. */
|
|
18
|
-
at_ms: z.number().int().nonnegative(),
|
|
19
|
-
/** Event type. */
|
|
20
|
-
type: processEventTypeSchema,
|
|
21
|
-
/** Process ID. */
|
|
22
|
-
pid: z.number().int().positive(),
|
|
23
|
-
/** Parent process ID. */
|
|
24
|
-
ppid: z.number().int().nullable(),
|
|
25
|
-
/** Process name if known. */
|
|
26
|
-
process_name: z.string().nullable(),
|
|
27
|
-
/** Executable path if known. */
|
|
28
|
-
executable: z.string().nullable(),
|
|
29
|
-
/** Command line arguments. */
|
|
30
|
-
arguments: z.array(z.string()).default([]),
|
|
31
|
-
/** Previous PID (for reparent events). */
|
|
32
|
-
previous_pid: z.number().int().nullable(),
|
|
33
|
-
/** Previous PPID (for reparent events). */
|
|
34
|
-
previous_ppid: z.number().int().nullable(),
|
|
35
|
-
/** Exit code (for exit events). */
|
|
36
|
-
exit_code: z.number().int().nullable(),
|
|
37
|
-
/** Signal number (for signal events). */
|
|
38
|
-
signal: z.number().int().nullable(),
|
|
39
|
-
/** Thread ID (for thread events). */
|
|
40
|
-
tid: z.number().int().nullable(),
|
|
41
|
-
});
|
|
42
|
-
/** Process node in a reconstructed tree. */
|
|
43
|
-
export const processNodeSchema = z.strictObject({
|
|
44
|
-
pid: z.number().int().positive(),
|
|
45
|
-
ppid: z.number().int().nullable(),
|
|
46
|
-
process_name: z.string().nullable(),
|
|
47
|
-
executable: z.string().nullable(),
|
|
48
|
-
arguments: z.array(z.string()).default([]),
|
|
49
|
-
children: z.array(z.number().int()).default([]),
|
|
50
|
-
spawn_time_ms: z.number().int().nullable(),
|
|
51
|
-
exit_time_ms: z.number().int().nullable(),
|
|
52
|
-
exit_code: z.number().int().nullable(),
|
|
53
|
-
is_re_exec: z.boolean().default(false),
|
|
54
|
-
is_reparented: z.boolean().default(false),
|
|
55
|
-
previous_ppid: z.number().int().nullable(),
|
|
56
|
-
});
|
|
57
|
-
/** Result of event-backed process-tree reconstruction. */
|
|
58
|
-
export const processTreeReconstructionSchema = z.strictObject({
|
|
59
|
-
/** Root PID of the process tree. */
|
|
60
|
-
root_pid: z.number().int().positive(),
|
|
61
|
-
/** All reconstructed process nodes. */
|
|
62
|
-
processes: z.array(processNodeSchema).min(0),
|
|
63
|
-
/** Events that were consumed. */
|
|
64
|
-
events_consumed: z.number().int().nonnegative(),
|
|
65
|
-
/** Events that could not be matched. */
|
|
66
|
-
events_unmatched: z.number().int().nonnegative(),
|
|
67
|
-
/** Short-lived descendants that were missed by sampling. */
|
|
68
|
-
short_lived_descendants: z.number().int().nonnegative(),
|
|
69
|
-
/** Whether any re-exec was detected. */
|
|
70
|
-
has_re_exec: z.boolean().default(false),
|
|
71
|
-
/** Whether any reparenting was detected. */
|
|
72
|
-
has_reparenting: z.boolean().default(false),
|
|
73
|
-
});
|
|
74
|
-
const applyProcessTreeEvent = (event, state) => {
|
|
75
|
-
let node = state.nodes.get(event.pid);
|
|
76
|
-
switch (event.type) {
|
|
77
|
-
case "spawn": {
|
|
78
|
-
if (!node) {
|
|
79
|
-
node = {
|
|
80
|
-
pid: event.pid,
|
|
81
|
-
ppid: event.ppid,
|
|
82
|
-
process_name: event.process_name,
|
|
83
|
-
executable: event.executable,
|
|
84
|
-
arguments: event.arguments,
|
|
85
|
-
children: [],
|
|
86
|
-
spawn_time_ms: event.at_ms,
|
|
87
|
-
exit_time_ms: null,
|
|
88
|
-
exit_code: null,
|
|
89
|
-
is_re_exec: false,
|
|
90
|
-
is_reparented: false,
|
|
91
|
-
previous_ppid: null,
|
|
92
|
-
};
|
|
93
|
-
state.nodes.set(event.pid, node);
|
|
94
|
-
}
|
|
95
|
-
if (event.ppid !== null) {
|
|
96
|
-
const parentChildren = state.children.get(event.ppid) ?? [];
|
|
97
|
-
parentChildren.push(event.pid);
|
|
98
|
-
state.children.set(event.ppid, parentChildren);
|
|
99
|
-
}
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
case "exit":
|
|
103
|
-
if (node) {
|
|
104
|
-
node.exit_time_ms = event.at_ms;
|
|
105
|
-
node.exit_code = event.exit_code;
|
|
106
|
-
if (node.spawn_time_ms !== null &&
|
|
107
|
-
event.at_ms - node.spawn_time_ms < 100)
|
|
108
|
-
state.shortLivedDescendants++;
|
|
109
|
-
}
|
|
110
|
-
else
|
|
111
|
-
state.eventsUnmatched++;
|
|
112
|
-
break;
|
|
113
|
-
case "re_exec":
|
|
114
|
-
if (node) {
|
|
115
|
-
node.is_re_exec = true;
|
|
116
|
-
node.executable = event.executable ?? node.executable;
|
|
117
|
-
node.arguments = event.arguments;
|
|
118
|
-
state.hasReExec = true;
|
|
119
|
-
}
|
|
120
|
-
else
|
|
121
|
-
state.eventsUnmatched++;
|
|
122
|
-
break;
|
|
123
|
-
case "reparent":
|
|
124
|
-
if (node) {
|
|
125
|
-
node.previous_ppid = node.ppid;
|
|
126
|
-
node.ppid = event.ppid;
|
|
127
|
-
node.is_reparented = true;
|
|
128
|
-
state.hasReparenting = true;
|
|
129
|
-
}
|
|
130
|
-
else
|
|
131
|
-
state.eventsUnmatched++;
|
|
132
|
-
break;
|
|
133
|
-
case "signal":
|
|
134
|
-
case "name_change":
|
|
135
|
-
case "thread_create":
|
|
136
|
-
case "thread_exit":
|
|
137
|
-
// These events are recorded but don't modify the tree structure.
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
/** Reconstruct a process tree from event-backed capture. */
|
|
142
|
-
export function reconstructProcessTree(events, rootPid) {
|
|
143
|
-
const nodes = new Map();
|
|
144
|
-
const children = new Map();
|
|
145
|
-
let eventsConsumed = 0;
|
|
146
|
-
const state = {
|
|
147
|
-
nodes,
|
|
148
|
-
children,
|
|
149
|
-
eventsUnmatched: 0,
|
|
150
|
-
hasReExec: false,
|
|
151
|
-
hasReparenting: false,
|
|
152
|
-
shortLivedDescendants: 0,
|
|
153
|
-
};
|
|
154
|
-
const sorted = [...events].sort((a, b) => a.at_ms - b.at_ms);
|
|
155
|
-
for (const event of sorted) {
|
|
156
|
-
eventsConsumed++;
|
|
157
|
-
applyProcessTreeEvent(event, state);
|
|
158
|
-
}
|
|
159
|
-
// Attach children to nodes
|
|
160
|
-
for (const [pid, childPids] of children) {
|
|
161
|
-
const node = nodes.get(pid);
|
|
162
|
-
if (node)
|
|
163
|
-
node.children = childPids;
|
|
164
|
-
}
|
|
165
|
-
return {
|
|
166
|
-
root_pid: rootPid,
|
|
167
|
-
processes: [...nodes.values()],
|
|
168
|
-
events_consumed: eventsConsumed,
|
|
169
|
-
events_unmatched: state.eventsUnmatched,
|
|
170
|
-
short_lived_descendants: state.shortLivedDescendants,
|
|
171
|
-
has_re_exec: state.hasReExec,
|
|
172
|
-
has_reparenting: state.hasReparenting,
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
/** Get all descendant PIDs of a given root PID. */
|
|
176
|
-
export function getDescendants(processes, rootPid) {
|
|
177
|
-
const byPid = new Map(processes.map((p) => [p.pid, p]));
|
|
178
|
-
const visited = new Set();
|
|
179
|
-
const result = [];
|
|
180
|
-
const queue = [rootPid];
|
|
181
|
-
for (let head = 0; head < queue.length; head += 1) {
|
|
182
|
-
const pid = queue[head];
|
|
183
|
-
if (pid === undefined)
|
|
184
|
-
continue;
|
|
185
|
-
if (visited.has(pid))
|
|
186
|
-
continue;
|
|
187
|
-
visited.add(pid);
|
|
188
|
-
const node = byPid.get(pid);
|
|
189
|
-
if (node) {
|
|
190
|
-
for (const child of node.children) {
|
|
191
|
-
if (!visited.has(child)) {
|
|
192
|
-
result.push(child);
|
|
193
|
-
queue.push(child);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
return result;
|
|
199
|
-
}
|
|
200
|
-
/** Check if a process tree contains a specific PID. */
|
|
201
|
-
export function containsProcess(processes, pid) {
|
|
202
|
-
return processes.some((p) => p.pid === pid);
|
|
203
|
-
}
|
|
204
|
-
/** Get the maximum tree depth from the root. */
|
|
205
|
-
export function maxTreeDepth(processes, rootPid) {
|
|
206
|
-
const byPid = new Map(processes.map((p) => [p.pid, p]));
|
|
207
|
-
const pending = [{ pid: rootPid, depth: 0 }];
|
|
208
|
-
const visited = new Set();
|
|
209
|
-
let maximumDepth = 0;
|
|
210
|
-
while (pending.length > 0) {
|
|
211
|
-
const current = pending.pop();
|
|
212
|
-
if (!current || visited.has(current.pid))
|
|
213
|
-
continue;
|
|
214
|
-
visited.add(current.pid);
|
|
215
|
-
const node = byPid.get(current.pid);
|
|
216
|
-
if (!node || node.children.length === 0)
|
|
217
|
-
continue;
|
|
218
|
-
const childDepth = current.depth + 1;
|
|
219
|
-
maximumDepth = Math.max(maximumDepth, childDepth);
|
|
220
|
-
for (const childPid of node.children)
|
|
221
|
-
if (!visited.has(childPid))
|
|
222
|
-
pending.push({ pid: childPid, depth: childDepth });
|
|
223
|
-
}
|
|
224
|
-
return maximumDepth;
|
|
225
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
/** Supported mobile artifact formats. */
|
|
3
|
-
export const mobileArtifactFormatSchema = z.enum([
|
|
4
|
-
"apk",
|
|
5
|
-
"aab",
|
|
6
|
-
"ipa",
|
|
7
|
-
"dex",
|
|
8
|
-
"native_lib",
|
|
9
|
-
]);
|
|
10
|
-
/** Mobile platform. */
|
|
11
|
-
export const mobilePlatformSchema = z.enum([
|
|
12
|
-
"android",
|
|
13
|
-
"ios",
|
|
14
|
-
"cross_platform",
|
|
15
|
-
]);
|
|
16
|
-
/** Android manifest entry. */
|
|
17
|
-
export const androidManifestSchema = z.strictObject({
|
|
18
|
-
package_name: z.string().min(1),
|
|
19
|
-
version_name: z.string().nullable(),
|
|
20
|
-
version_code: z.number().int().nullable(),
|
|
21
|
-
min_sdk: z.number().int().nullable(),
|
|
22
|
-
target_sdk: z.number().int().nullable(),
|
|
23
|
-
permissions: z.array(z.string()).default([]),
|
|
24
|
-
activities: z.array(z.string()).default([]),
|
|
25
|
-
services: z.array(z.string()).default([]),
|
|
26
|
-
receivers: z.array(z.string()).default([]),
|
|
27
|
-
providers: z.array(z.string()).default([]),
|
|
28
|
-
});
|
|
29
|
-
/** iOS app manifest (Info.plist). */
|
|
30
|
-
export const iosManifestSchema = z.strictObject({
|
|
31
|
-
bundle_identifier: z.string().min(1),
|
|
32
|
-
bundle_version: z.string().nullable(),
|
|
33
|
-
short_version: z.string().nullable(),
|
|
34
|
-
minimum_os_version: z.string().nullable(),
|
|
35
|
-
supported_platforms: z.array(z.string()).default([]),
|
|
36
|
-
ui_required_device_capabilities: z.array(z.string()).default([]),
|
|
37
|
-
app_permissions: z.array(z.string()).default([]),
|
|
38
|
-
});
|
|
39
|
-
/** Signing information. */
|
|
40
|
-
export const signingInfoSchema = z.strictObject({
|
|
41
|
-
is_signed: z.boolean().default(false),
|
|
42
|
-
signer_identity: z.string().nullable(),
|
|
43
|
-
certificate_fingerprint: z.string().nullable(),
|
|
44
|
-
signature_scheme: z.string().nullable(),
|
|
45
|
-
is_debuggable: z.boolean().default(false),
|
|
46
|
-
});
|
|
47
|
-
/** Native library entry. */
|
|
48
|
-
export const nativeLibrarySchema = z.strictObject({
|
|
49
|
-
path: z.string().min(1),
|
|
50
|
-
architecture: z.string().nullable(),
|
|
51
|
-
size: z.number().int().nonnegative(),
|
|
52
|
-
digest: z
|
|
53
|
-
.string()
|
|
54
|
-
.regex(/^[a-f0-9]{64}$/u)
|
|
55
|
-
.nullable(),
|
|
56
|
-
});
|
|
57
|
-
/** Resource entry within a mobile artifact. */
|
|
58
|
-
export const mobileResourceSchema = z.strictObject({
|
|
59
|
-
path: z.string().min(1),
|
|
60
|
-
type: z.enum([
|
|
61
|
-
"layout",
|
|
62
|
-
"drawable",
|
|
63
|
-
"string",
|
|
64
|
-
"asset",
|
|
65
|
-
"raw",
|
|
66
|
-
"native_lib",
|
|
67
|
-
"manifest",
|
|
68
|
-
"entitlements",
|
|
69
|
-
"provisioning",
|
|
70
|
-
"other",
|
|
71
|
-
]),
|
|
72
|
-
size: z.number().int().nonnegative(),
|
|
73
|
-
});
|
|
74
|
-
/** Static analysis result for a mobile artifact. */
|
|
75
|
-
export const mobileArtifactManifestSchema = z.strictObject({
|
|
76
|
-
format: mobileArtifactFormatSchema,
|
|
77
|
-
platform: mobilePlatformSchema,
|
|
78
|
-
app_name: z.string().nullable(),
|
|
79
|
-
android_manifest: androidManifestSchema.nullable(),
|
|
80
|
-
ios_manifest: iosManifestSchema.nullable(),
|
|
81
|
-
signing: signingInfoSchema,
|
|
82
|
-
resources: z.array(mobileResourceSchema).default([]),
|
|
83
|
-
native_libraries: z.array(nativeLibrarySchema).default([]),
|
|
84
|
-
total_size: z.number().int().nonnegative(),
|
|
85
|
-
architectures: z.array(z.string()).default([]),
|
|
86
|
-
});
|
|
87
|
-
/** Detect mobile artifact format from file extension. */
|
|
88
|
-
export function detectMobileFormat(path) {
|
|
89
|
-
const lower = path.toLowerCase();
|
|
90
|
-
if (lower.endsWith(".apk"))
|
|
91
|
-
return "apk";
|
|
92
|
-
if (lower.endsWith(".aab"))
|
|
93
|
-
return "aab";
|
|
94
|
-
if (lower.endsWith(".ipa"))
|
|
95
|
-
return "ipa";
|
|
96
|
-
if (lower.endsWith(".dex"))
|
|
97
|
-
return "dex";
|
|
98
|
-
if (lower.endsWith(".so") || lower.endsWith(".dylib") || lower.endsWith(".a"))
|
|
99
|
-
return "native_lib";
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
/** Detect platform from format. */
|
|
103
|
-
export function detectPlatform(format) {
|
|
104
|
-
switch (format) {
|
|
105
|
-
case "apk":
|
|
106
|
-
case "aab":
|
|
107
|
-
case "dex":
|
|
108
|
-
return "android";
|
|
109
|
-
case "ipa":
|
|
110
|
-
return "ios";
|
|
111
|
-
case "native_lib":
|
|
112
|
-
return "cross_platform";
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
/** Classify a resource by its path. */
|
|
116
|
-
export function classifyMobileResource(path) {
|
|
117
|
-
const lower = path.toLowerCase();
|
|
118
|
-
if (lower.includes("androidmanifest.xml"))
|
|
119
|
-
return "manifest";
|
|
120
|
-
if (lower.includes(".entitlements"))
|
|
121
|
-
return "entitlements";
|
|
122
|
-
if (lower.includes("provisioning") || lower.includes(".mobileprovision"))
|
|
123
|
-
return "provisioning";
|
|
124
|
-
if (lower.includes("/layout/"))
|
|
125
|
-
return "layout";
|
|
126
|
-
if (lower.includes("/drawable/") || lower.includes("/mipmap/"))
|
|
127
|
-
return "drawable";
|
|
128
|
-
if (lower.includes("/values/"))
|
|
129
|
-
return "string";
|
|
130
|
-
if (lower.includes("assets/") || lower.includes("raw/"))
|
|
131
|
-
return "asset";
|
|
132
|
-
if (lower.endsWith(".so") || lower.endsWith(".dylib"))
|
|
133
|
-
return "native_lib";
|
|
134
|
-
if (lower.endsWith(".xml"))
|
|
135
|
-
return "layout";
|
|
136
|
-
return "other";
|
|
137
|
-
}
|
|
138
|
-
/** Get all native libraries for a specific architecture. */
|
|
139
|
-
export function nativeLibsByArchitecture(manifest, arch) {
|
|
140
|
-
return manifest.native_libraries.filter((l) => l.architecture === arch);
|
|
141
|
-
}
|
|
142
|
-
/** Check if an Android artifact has internet permission. */
|
|
143
|
-
export function hasInternetPermission(manifest) {
|
|
144
|
-
if (!manifest.android_manifest)
|
|
145
|
-
return false;
|
|
146
|
-
return manifest.android_manifest.permissions.some((p) => p.includes("INTERNET") || p.includes("android.permission.INTERNET"));
|
|
147
|
-
}
|
|
148
|
-
/** Get all unique architectures across native libraries. */
|
|
149
|
-
export function getAllArchitectures(manifest) {
|
|
150
|
-
const archs = new Set();
|
|
151
|
-
for (const lib of manifest.native_libraries) {
|
|
152
|
-
if (lib.architecture)
|
|
153
|
-
archs.add(lib.architecture);
|
|
154
|
-
}
|
|
155
|
-
for (const arch of manifest.architectures) {
|
|
156
|
-
archs.add(arch);
|
|
157
|
-
}
|
|
158
|
-
return [...archs];
|
|
159
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
/** Supported Windows package formats. */
|
|
3
|
-
export const packageFormatSchema = z.enum(["msix", "msi", "appx"]);
|
|
4
|
-
/** A resource entry within a package. */
|
|
5
|
-
export const packageResourceSchema = z.strictObject({
|
|
6
|
-
/** Resource path within the package. */
|
|
7
|
-
path: z.string().min(1),
|
|
8
|
-
/** Resource type. */
|
|
9
|
-
type: z.enum([
|
|
10
|
-
"manifest",
|
|
11
|
-
"icon",
|
|
12
|
-
"configuration",
|
|
13
|
-
"certificate",
|
|
14
|
-
"executable",
|
|
15
|
-
"library",
|
|
16
|
-
"data",
|
|
17
|
-
"other",
|
|
18
|
-
]),
|
|
19
|
-
/** Size in bytes. */
|
|
20
|
-
size: z.number().int().nonnegative(),
|
|
21
|
-
/** SHA-256 digest. */
|
|
22
|
-
digest: z
|
|
23
|
-
.string()
|
|
24
|
-
.regex(/^[a-f0-9]{64}$/u)
|
|
25
|
-
.nullable(),
|
|
26
|
-
});
|
|
27
|
-
/** Digital signature information. */
|
|
28
|
-
export const digitalSignatureSchema = z.strictObject({
|
|
29
|
-
/** Whether the package is signed. */
|
|
30
|
-
is_signed: z.boolean(),
|
|
31
|
-
/** Signer subject name. */
|
|
32
|
-
signer_subject: z.string().nullable(),
|
|
33
|
-
/** Certificate thumbprint. */
|
|
34
|
-
certificate_thumbprint: z.string().nullable(),
|
|
35
|
-
/** Whether the signature is valid. */
|
|
36
|
-
is_valid: z.boolean().default(false),
|
|
37
|
-
/** Whether the signature is timestamped. */
|
|
38
|
-
is_timestamped: z.boolean().default(false),
|
|
39
|
-
/** Timestamp signer if present. */
|
|
40
|
-
timestamp_signer: z.string().nullable(),
|
|
41
|
-
});
|
|
42
|
-
/** A Windows package manifest for static analysis. */
|
|
43
|
-
export const packageManifestSchema = z.strictObject({
|
|
44
|
-
/** Package format. */
|
|
45
|
-
format: packageFormatSchema,
|
|
46
|
-
/** Package identity name. */
|
|
47
|
-
name: z.string().min(1),
|
|
48
|
-
/** Package publisher. */
|
|
49
|
-
publisher: z.string().nullable(),
|
|
50
|
-
/** Package version. */
|
|
51
|
-
version: z.string().nullable(),
|
|
52
|
-
/** Architecture. */
|
|
53
|
-
architecture: z.enum(["x86", "x64", "arm", "arm64", "neutral", "unknown"]),
|
|
54
|
-
/** Package resources. */
|
|
55
|
-
resources: z.array(packageResourceSchema).default([]),
|
|
56
|
-
/** Digital signature. */
|
|
57
|
-
signature: digitalSignatureSchema,
|
|
58
|
-
/** Whether the package is a framework. */
|
|
59
|
-
is_framework: z.boolean().default(false),
|
|
60
|
-
/** Package dependencies. */
|
|
61
|
-
dependencies: z.array(z.string()).default([]),
|
|
62
|
-
/** Capabilities declared in the manifest. */
|
|
63
|
-
capabilities: z.array(z.string()).default([]),
|
|
64
|
-
});
|
|
65
|
-
/** Detect package format from file extension. */
|
|
66
|
-
export function detectPackageFormat(path) {
|
|
67
|
-
const lower = path.toLowerCase();
|
|
68
|
-
if (lower.endsWith(".msix"))
|
|
69
|
-
return "msix";
|
|
70
|
-
if (lower.endsWith(".msi"))
|
|
71
|
-
return "msi";
|
|
72
|
-
if (lower.endsWith(".appx"))
|
|
73
|
-
return "appx";
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
/** Check if a resource path looks like a manifest. */
|
|
77
|
-
export function isManifestResource(path) {
|
|
78
|
-
const lower = path.toLowerCase();
|
|
79
|
-
return (lower.includes("appxmanifest.xml") ||
|
|
80
|
-
lower.includes("appxmanifest") ||
|
|
81
|
-
lower.includes("manifest.xml") ||
|
|
82
|
-
lower.endsWith("_manifest.xml"));
|
|
83
|
-
}
|
|
84
|
-
/** Check if a resource path looks like a configuration file. */
|
|
85
|
-
export function isConfigurationResource(path) {
|
|
86
|
-
const lower = path.toLowerCase();
|
|
87
|
-
return (lower.endsWith(".xml") ||
|
|
88
|
-
lower.endsWith(".json") ||
|
|
89
|
-
lower.endsWith(".ini") ||
|
|
90
|
-
lower.endsWith(".config"));
|
|
91
|
-
}
|
|
92
|
-
/** Classify a resource by its path. */
|
|
93
|
-
export function classifyResource(path) {
|
|
94
|
-
if (isManifestResource(path))
|
|
95
|
-
return "manifest";
|
|
96
|
-
const lower = path.toLowerCase();
|
|
97
|
-
if (lower.endsWith(".ico") ||
|
|
98
|
-
lower.endsWith(".png") ||
|
|
99
|
-
lower.endsWith(".jpg") ||
|
|
100
|
-
lower.endsWith(".jpeg"))
|
|
101
|
-
return "icon";
|
|
102
|
-
if (isConfigurationResource(path))
|
|
103
|
-
return "configuration";
|
|
104
|
-
if (lower.endsWith(".cer") ||
|
|
105
|
-
lower.endsWith(".pfx") ||
|
|
106
|
-
lower.endsWith(".p12"))
|
|
107
|
-
return "certificate";
|
|
108
|
-
if (lower.endsWith(".exe") || lower.endsWith(".dll"))
|
|
109
|
-
return lower.endsWith(".exe") ? "executable" : "library";
|
|
110
|
-
return "other";
|
|
111
|
-
}
|
|
112
|
-
/** Get all resources of a specific type. */
|
|
113
|
-
export function resourcesByType(manifest, type) {
|
|
114
|
-
return manifest.resources.filter((r) => r.type === type);
|
|
115
|
-
}
|
|
116
|
-
/** Get the total size of all resources. */
|
|
117
|
-
export function totalResourceSize(manifest) {
|
|
118
|
-
return manifest.resources.reduce((sum, r) => sum + r.size, 0);
|
|
119
|
-
}
|
|
120
|
-
/** Check if a package has a valid signature. */
|
|
121
|
-
export function hasValidSignature(manifest) {
|
|
122
|
-
return manifest.signature.is_signed && manifest.signature.is_valid;
|
|
123
|
-
}
|