Files
reverse-engineering-anything/src/artifacts/ArtifactEmbeddedFormatProbes.ts
T
morluto cb4e5cfbff feat(analysis): make resource budgets recoverable across CLI and MCP (#9706)
* refactor(analysis): centralize resource budgets and recovery facts

* feat(analysis): expose ASAR and Ghidra runtime admission controls

* feat(artifacts): expose reader admission and preserve limited recognition

* feat(javascript): expose recoverable semantic precision budgets

* feat(web): add recoverable source-map budgets and compact retained views

* feat(web): make historical capture decoding budgets recoverable

* fix(desktop): enforce selected view policies across capture and export

* feat(runtime): make Frida and LLDB retention budgets selectable

* feat(native): expose diagnostic budgets and preserve exhaustion causes

* feat(managed): expose recoverable snapshot and representation budgets

* feat(metadata): make Go and Rust inspection budgets recoverable

* feat(wasm): expose representation and producer admissions

* feat(evm): expose per-call worker resource budgets

* feat(android): make resource and string-pool omissions recoverable

* feat(producers): expose command and recorded-capture budgets

* docs(analysis): record recovery contracts and integrated validation

* fix(docs): link calibration oracle from published verification pages

* fix(docs): restore desktop task anchors and receipt links

* test(analysis): align fixtures with selectable budget contracts

* fix(analysis): remove source-location projector dependency cycle

* test(analysis): refresh budget recovery and verifier regressions

* test(analysis): preserve format and publication recovery expectations

* test(windows): align conformance with owned runtime admission

* fix(desktop): preserve selected alias kinds in exported state

* test(analysis): align provider fixtures with recoverable budgets

* test(desktop): validate emitted alias metadata structurally

* fix(ghidra): classify bounded Windows endpoint refusals

* test(cli): assert selectable artifact admission recovery

* fix(cli): preserve capture provenance in environment builds
2026-11-10 05:11:20 -05:00

204 lines
6.6 KiB
TypeScript

import {
probeBunStandaloneGraph,
type BunStandaloneProbe,
} from "./bun/BunModuleGraphLayout.js";
import {
locateDenoStandalone,
type DenoStandaloneProbe,
} from "./deno/DenoStandaloneLocation.js";
import {
resolveArtifactReaderLimits,
type ArtifactReaderLimits,
} from "../domain/artifactReaderLimits.js";
import type {
StableRegularFileDescriptor,
RegularFileState,
} from "../filesystem/RegularFile.js";
import {
regularFileState,
sameRegularFileState,
} from "../filesystem/RegularFile.js";
import { findDotnetBundleHeader } from "./dotnet/DotnetBundle.js";
import { ArtifactReaderFailure } from "./ArtifactReader.js";
import { abortIfNeeded } from "./ArtifactHash.js";
import { locateGodotPck, type GodotPckLocation } from "./GodotPckLocation.js";
import {
locateNodeSea,
type NodeSeaLocation,
} from "./nodeSea/NodeSeaLocation.js";
import {
observePyInstallerCookie,
type PyInstallerCookie,
type PyInstallerCookieObservation,
} from "./pyinstaller/CArchiveLayout.js";
/** Completed observations and explicit recognition limits; null alone is examined absence. */
export interface ArtifactEmbeddedFormatProbeFacts {
readonly sourceState: RegularFileState;
readonly readerLimits?: ArtifactReaderLimits;
readonly bunStandalone?: BunStandaloneProbe;
readonly denoStandalone?: DenoStandaloneProbe;
readonly godotPck?: GodotPckLocation | null;
readonly nodeSea?: NodeSeaLocation | null;
readonly nodeSeaRecognitionFailure?: ArtifactReaderFailure;
readonly dotnetBundleHeaderOffset?: number | null;
readonly pyInstaller?: PyInstallerCookieObservation;
}
/** Share format observations only across admissions of the same unchanged regular file. */
export class ArtifactEmbeddedFormatProbes {
#facts: ArtifactEmbeddedFormatProbeFacts;
constructor(
path: string,
private readonly source: StableRegularFileDescriptor,
private readonly signal?: AbortSignal,
previous?: ArtifactEmbeddedFormatProbeFacts,
private readonly limits: ArtifactReaderLimits = resolveArtifactReaderLimits(),
) {
abortIfNeeded(signal);
if (
previous !== undefined &&
!sameRegularFileState(previous.sourceState, source.initial)
)
throw new ArtifactReaderFailure(
"integrity",
`Root artifact changed before inventory: ${path}`,
);
const reusable =
previous !== undefined &&
JSON.stringify(previous.readerLimits) === JSON.stringify(limits);
if (previous !== undefined && !reusable) {
const {
bunStandalone: _bun,
nodeSea: _sea,
nodeSeaRecognitionFailure: _seaLimit,
...facts
} = previous;
this.#facts = { ...facts, readerLimits: limits };
} else
this.#facts = previous ?? {
sourceState: regularFileState(source.initial),
readerLimits: limits,
};
}
async godotPck(prefix?: Uint8Array): Promise<GodotPckLocation | undefined> {
abortIfNeeded(this.signal);
if (this.#facts.godotPck !== undefined)
return this.#facts.godotPck ?? undefined;
const location = await locateGodotPck(
this.source.handle,
this.source.initial.size,
this.signal,
prefix,
);
this.#facts = { ...this.#facts, godotPck: location ?? null };
return location;
}
async nodeSea(): Promise<NodeSeaLocation | undefined> {
abortIfNeeded(this.signal);
if (this.#facts.nodeSea !== undefined)
return this.#facts.nodeSea ?? undefined;
if (this.#facts.nodeSeaRecognitionFailure !== undefined) return undefined;
try {
const location = await locateNodeSea(
this.source.handle,
this.source.initial.size,
this.signal,
this.limits.node_sea,
);
this.#facts = { ...this.#facts, nodeSea: location ?? null };
return location;
} catch (cause) {
if (
cause instanceof ArtifactReaderFailure &&
(cause.readerLimit?.parameter ===
"artifact_limits.node_sea.recognition_header_count" ||
cause.readerLimit?.parameter ===
"artifact_limits.node_sea.recognition_load_command_bytes")
) {
this.#facts = { ...this.#facts, nodeSeaRecognitionFailure: cause };
return undefined;
}
throw cause;
}
}
async pyInstaller(): Promise<PyInstallerCookie | undefined> {
abortIfNeeded(this.signal);
if (this.#facts.pyInstaller !== undefined)
return this.#facts.pyInstaller.state === "located"
? this.#facts.pyInstaller.cookie
: undefined;
const found = await observePyInstallerCookie(
this.source.handle,
this.source.initial.size,
this.signal,
);
abortIfNeeded(this.signal);
if (!found.ok)
throw new ArtifactReaderFailure(found.error.reason, found.error.message);
this.#facts = { ...this.#facts, pyInstaller: found.value };
return found.value.state === "located" ? found.value.cookie : undefined;
}
async dotnetBundle(): Promise<number | undefined> {
abortIfNeeded(this.signal);
if (this.#facts.dotnetBundleHeaderOffset !== undefined)
return this.#facts.dotnetBundleHeaderOffset ?? undefined;
// An apphost inside a recognized CArchive cannot claim its outer carrier.
const packaged = await this.pyInstaller();
const header = await findDotnetBundleHeader(
this.source.handle,
this.source.initial.size,
this.signal,
packaged?.archiveStart ?? this.source.initial.size,
);
abortIfNeeded(this.signal);
this.#facts = { ...this.#facts, dotnetBundleHeaderOffset: header ?? null };
return header;
}
async bunStandalone(): Promise<BunStandaloneProbe> {
abortIfNeeded(this.signal);
if (this.#facts.bunStandalone !== undefined)
return this.#facts.bunStandalone;
const observed = await probeBunStandaloneGraph(
this.source.handle,
this.source.initial.size,
this.signal,
this.limits.bun,
);
abortIfNeeded(this.signal);
this.#facts = { ...this.#facts, bunStandalone: observed };
return observed;
}
async denoStandalone(): Promise<DenoStandaloneProbe> {
abortIfNeeded(this.signal);
if (this.#facts.denoStandalone !== undefined)
return this.#facts.denoStandalone;
const packaged = await this.pyInstaller();
const observed = await locateDenoStandalone(
this.source.handle,
this.source.initial.size,
this.signal,
packaged === undefined
? undefined
: {
start: packaged.archiveStart,
end: packaged.archiveStart + packaged.packageLength,
},
);
abortIfNeeded(this.signal);
this.#facts = { ...this.#facts, denoStandalone: observed };
return observed;
}
completedFacts(): ArtifactEmbeddedFormatProbeFacts {
return this.#facts;
}
}