* feat(native): admit raw binaries with caller-supplied architecture and entry * fix(native): honor raw-binary preparation and entry identity * fix(ghidra): stream raw snapshot attestation with cancellation * fix(native): preserve and validate raw lifecycle entries --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
84 lines
3.0 KiB
TypeScript
84 lines
3.0 KiB
TypeScript
import { isAbsolute } from "node:path";
|
|
import { executableFormatHintSchema } from "../domain/dosCom.js";
|
|
import { localPathStringSchema } from "../domain/localPath.js";
|
|
import {
|
|
binaryArchitectureSchema,
|
|
rawBinaryEntryPointSchema,
|
|
rawBinarySelectionError,
|
|
} from "../domain/rawBinary.js";
|
|
import { z } from "zod";
|
|
import { analysisProviderSelectorSchema } from "./providerSelection.js";
|
|
|
|
/** Caller-supplied analysis snapshot path; must name its destination absolutely. */
|
|
const snapshotPathSchema = localPathStringSchema
|
|
.refine(isAbsolute, {
|
|
message:
|
|
"snapshot_path must be an absolute local filesystem path (for example /tmp/rea/analysis.json or C:\\rea\\analysis.json)",
|
|
})
|
|
.describe(
|
|
"Absolute local filesystem path for the analysis snapshot; relative paths are rejected.",
|
|
);
|
|
|
|
/** Caller-supplied analysis target path; must name the target absolutely. */
|
|
const binaryTargetPathSchema = localPathStringSchema
|
|
.refine(isAbsolute, {
|
|
message:
|
|
"path must be an absolute local filesystem path (for example /tmp/fixture.bin or C:\\analysis\\fixture.bin)",
|
|
})
|
|
.describe(
|
|
"Absolute local filesystem path for the analysis target; relative paths are rejected.",
|
|
);
|
|
|
|
/** Input contract for opening a target with an optional staged snapshot. */
|
|
export const openBinaryInputSchema = z
|
|
.strictObject({
|
|
path: binaryTargetPathSchema,
|
|
format: executableFormatHintSchema
|
|
.optional()
|
|
.describe(
|
|
"Explicit headerless interpretation: dos-com or raw-binary. Omission preserves header-based detection.",
|
|
),
|
|
architecture: binaryArchitectureSchema
|
|
.optional()
|
|
.describe(
|
|
"Caller-supplied CPU family. Required with format=raw-binary; rejected otherwise.",
|
|
),
|
|
entry_point: rawBinaryEntryPointSchema
|
|
.optional()
|
|
.describe(
|
|
"Caller-supplied load and entry address (0xhex). File offset 0 is mapped here. Required with format=raw-binary; rejected otherwise.",
|
|
),
|
|
provider_id: analysisProviderSelectorSchema.optional(),
|
|
snapshot_path: snapshotPathSchema.optional(),
|
|
})
|
|
.superRefine((value, context) => {
|
|
const pairing = rawBinarySelectionError({
|
|
...(value.format === undefined ? {} : { format: value.format }),
|
|
...(value.architecture === undefined
|
|
? {}
|
|
: { architecture: value.architecture }),
|
|
...(value.entry_point === undefined
|
|
? {}
|
|
: { entryPoint: value.entry_point }),
|
|
});
|
|
if (pairing === undefined) return;
|
|
context.addIssue({
|
|
code: "custom",
|
|
path:
|
|
value.format === "raw-binary"
|
|
? value.architecture === undefined
|
|
? ["architecture"]
|
|
: ["entry_point"]
|
|
: value.architecture === undefined
|
|
? ["entry_point"]
|
|
: ["architecture"],
|
|
message: pairing,
|
|
});
|
|
});
|
|
|
|
/** Input contract for closing a target after an optional atomic snapshot. */
|
|
export const closeBinaryInputSchema = z.strictObject({
|
|
snapshot_path: snapshotPathSchema.optional(),
|
|
overwrite: z.boolean().default(false),
|
|
});
|