Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f92e7e1991 |
@@ -137,6 +137,7 @@ REA; Node.js 22.x (>=22.19), 24.x (>=24.11) veya 26+ ve npm gerektirir. Ek araç
|
||||
| Yerel makine kodu içeren ikili dosyalar | Sözde kod, assembly kodu, dizeler, semboller, çağrılar ve referanslar | Hopper, Ghidra veya IDA; [yerel kod analizi](https://rea.tools/tr/guides/native/) |
|
||||
| Çevrimdışı ELF yapısı | Bölümler, segmentler, özgün semboller/yeniden konumlandırmalar ve statik analizden olası güvenlik önlemleri | Linux x64 üzerinde çağıranın sağladığı pwntools; [ikili dosya tanılama](../binary-diagnostics.md) |
|
||||
| Go ikili dosyaları | Gömülü compiler sürümü, modüller, replacement'lar ve build ayarları | Yerleşik statik ELF/PE/thin Mach-O incelemesi; Go kurulumu gerekmez |
|
||||
| Rust binaries | Embedded cargo-auditable crate names, versions, sources and dependency edges | Built-in static ELF/PE/thin Mach-O inspection; [Rust binaries](../rust-binaries.md) |
|
||||
| WASM artefaktı | Doğrulama, bölümler, tam import/export WAT biçimleri ve decode edilmiş WAT | Çağıranın sağladığı WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Linux x64 üzerinde yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](../evm-bytecode.md) |
|
||||
| SQLite veritabanları | Tablolar, sütunlar, index'ler, view'lar, trigger'lar ve seçilen sıradan tablo satırları | Yerel database/WAL snapshot'ı; native SQLite sınırlarıyla Node.js 24.x >=24.15 veya 26+ |
|
||||
|
||||
@@ -8,10 +8,4 @@ export function assertLinuxPackageProviderFailure(execution: {
|
||||
export function verifyPackagePlatform(input: {
|
||||
readonly cli: string;
|
||||
readonly environment: Readonly<Record<string, string | undefined>>;
|
||||
readonly platform?: string;
|
||||
readonly runCommand?: (
|
||||
command: string,
|
||||
arguments_: readonly string[],
|
||||
environment: Readonly<Record<string, string | undefined>>,
|
||||
) => Promise<string>;
|
||||
}): Promise<void>;
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import { json, run, runWithStatus } from "./lib/verify-package-core.mjs";
|
||||
|
||||
/** Run platform-specific deep-analysis smoke tests. */
|
||||
export async function verifyPackagePlatform({
|
||||
cli,
|
||||
environment,
|
||||
platform = process.platform,
|
||||
runCommand = run,
|
||||
}) {
|
||||
if (platform === "linux") {
|
||||
export async function verifyPackagePlatform({ cli, environment }) {
|
||||
if (process.platform === "linux") {
|
||||
const unsupportedExecution = await runWithStatus(
|
||||
cli,
|
||||
["analyze", process.execPath, "--json"],
|
||||
@@ -16,27 +11,25 @@ export async function verifyPackagePlatform({
|
||||
assertLinuxPackageProviderFailure(unsupportedExecution);
|
||||
} else {
|
||||
const overview = json(
|
||||
await runCommand(
|
||||
cli,
|
||||
["analyze", process.execPath, "--json"],
|
||||
environment,
|
||||
),
|
||||
await run(cli, ["analyze", process.execPath, "--json"], environment),
|
||||
);
|
||||
if (!hasPositiveProcedureCount(overview))
|
||||
if (
|
||||
overview.operation !== "binary_overview" ||
|
||||
overview.normalized_result?.procedure_count < 1
|
||||
)
|
||||
throw new Error(
|
||||
`packaged Hopper-backed analyze CLI failed: ${JSON.stringify(overview)}`,
|
||||
);
|
||||
const inspected = json(
|
||||
await runCommand(
|
||||
cli,
|
||||
["inspect", process.execPath, "--json"],
|
||||
environment,
|
||||
),
|
||||
await run(cli, ["inspect", process.execPath, "--json"], environment),
|
||||
);
|
||||
if (!hasPositiveProcedureCount(inspected))
|
||||
if (
|
||||
inspected.operation !== "binary_overview" ||
|
||||
inspected.normalized_result?.procedure_count < 1
|
||||
)
|
||||
throw new Error("packaged inspect CLI failed");
|
||||
const functionResult = json(
|
||||
await runCommand(
|
||||
await run(
|
||||
cli,
|
||||
["function", process.execPath, "0x1000", "--json"],
|
||||
environment,
|
||||
@@ -51,7 +44,7 @@ export async function verifyPackagePlatform({
|
||||
`packaged function CLI failed: ${JSON.stringify(functionResult)}`,
|
||||
);
|
||||
const xrefs = json(
|
||||
await runCommand(
|
||||
await run(
|
||||
cli,
|
||||
["xrefs", process.execPath, "0x1000", "--json"],
|
||||
environment,
|
||||
@@ -63,7 +56,7 @@ export async function verifyPackagePlatform({
|
||||
)
|
||||
throw new Error(`packaged xrefs CLI failed: ${JSON.stringify(xrefs)}`);
|
||||
const trace = json(
|
||||
await runCommand(
|
||||
await run(
|
||||
cli,
|
||||
["trace", process.execPath, "fixture", "--json"],
|
||||
environment,
|
||||
@@ -100,10 +93,3 @@ export const assertLinuxPackageProviderFailure = (execution) => {
|
||||
`packaged Linux Hopper verification did not fail closed: ${JSON.stringify(failure)}`,
|
||||
);
|
||||
};
|
||||
|
||||
const hasPositiveProcedureCount = (result) =>
|
||||
typeof result === "object" &&
|
||||
result !== null &&
|
||||
result.operation === "binary_overview" &&
|
||||
Number.isInteger(result.normalized_result?.procedure_count) &&
|
||||
result.normalized_result.procedure_count > 0;
|
||||
|
||||
@@ -186,28 +186,6 @@ describe("analysis provider registry: binding failures and cancellation", () =>
|
||||
expect(explicit.error.reason).toBe("target_unsupported");
|
||||
});
|
||||
|
||||
it("rejects an unknown environment preference even when every candidate rejects the target", async () => {
|
||||
const alpha = candidate("alpha");
|
||||
const misconfigured = new AnalysisProviderRegistry(
|
||||
[alpha.provider],
|
||||
"missing",
|
||||
);
|
||||
|
||||
for (const selected of [
|
||||
await misconfigured.select(ARTIFACT_TARGET),
|
||||
await misconfigured.select(ARTIFACT_TARGET, "missing"),
|
||||
]) {
|
||||
if (selected.ok) throw new Error("expected unknown provider rejection");
|
||||
expect(projectAnalysisError(selected.error)).toMatchObject({
|
||||
details: {
|
||||
selection_reason: "unknown_provider",
|
||||
requested_provider_id: "missing",
|
||||
candidate_ids: ["alpha"],
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("does not bind a profile with unresolved version or adapter failure", async () => {
|
||||
const unresolved = candidate("unresolved", { profile: "missing" });
|
||||
const failed = candidate("failed", { profile: "error" });
|
||||
|
||||
@@ -176,7 +176,7 @@ export class AnalysisProviderRegistry {
|
||||
return err(new AnalysisCancelledError("open_binary"));
|
||||
if (
|
||||
request === undefined &&
|
||||
this.#byId.has(selector) &&
|
||||
selector !== "auto" &&
|
||||
baseline.length > 0 &&
|
||||
baseline.every(
|
||||
({ targetSupport }) => targetSupport.status === "unsupported",
|
||||
|
||||
@@ -186,21 +186,6 @@ it("excludes structural auth material and explicit normalized values without gue
|
||||
expect(traces[0]?.incomplete_fact_records).toContain(2);
|
||||
});
|
||||
|
||||
it("omits a hidden derived total for a stream with more contributions than call arguments allow", () => {
|
||||
const events = Array.from({ length: 130 }, (_, index) =>
|
||||
event(
|
||||
Array.from({ length: 1_000 }, (_, offset) =>
|
||||
frame(index * 1_000 + offset, 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
const { traces } = facts(capture(events), ["130000"]);
|
||||
expect(traces[0]?.streams).toEqual([]);
|
||||
expect(traces[0]?.incomplete_fact_records).toEqual(
|
||||
Array.from({ length: 130 }, (_, ordinal) => ordinal),
|
||||
);
|
||||
});
|
||||
|
||||
it("hides marked ancestor keys and safe derived sums while still validating hidden subtrees", () => {
|
||||
const text = capture([event([frame(0, 3), frame(3, 4)])]);
|
||||
expect(facts(text, ["7"]).traces[0]?.streams).toEqual([]);
|
||||
|
||||
@@ -95,10 +95,10 @@ export const decodeQlogCapture = (
|
||||
...stream.reported_final_sizes,
|
||||
...stream.covered_ranges.flatMap((r) => [r.start, r.end]),
|
||||
];
|
||||
// A stream can have more contributions than call arguments allow.
|
||||
if (numericValues.some(excluded))
|
||||
for (const contribution of stream.contributions)
|
||||
fact.incomplete_fact_records.push(contribution.record_ordinal);
|
||||
fact.incomplete_fact_records.push(
|
||||
...stream.contributions.map((c) => c.record_ordinal),
|
||||
);
|
||||
else fact.streams.push(stream);
|
||||
}
|
||||
fact.incomplete_fact_records = [...new Set(fact.incomplete_fact_records)];
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { TOOL_CONTRACTS } from "./toolContracts.js";
|
||||
import {
|
||||
TOOL_EFFECTS,
|
||||
annotationsFromEffects,
|
||||
type ToolEffects,
|
||||
} from "./toolEffects.js";
|
||||
import { TOOL_EFFECTS, annotationsFromEffects } from "./toolEffects.js";
|
||||
|
||||
/**
|
||||
* Descriptions that name running, launching, executing, starting, installing,
|
||||
@@ -152,19 +148,8 @@ describe("tool effects", () => {
|
||||
});
|
||||
|
||||
it("derives destructiveHint from each destructive effect alone", () => {
|
||||
// Keep annotation algebra independent of any operation's audited effects.
|
||||
const base: ToolEffects = {
|
||||
mutatesTarget: false,
|
||||
mutatesSession: false,
|
||||
writesFilesystem: false,
|
||||
launchesProcess: false,
|
||||
accessesNetwork: false,
|
||||
changesUiState: false,
|
||||
mayDiscardData: false,
|
||||
executesForeignCode: false,
|
||||
mutatesDevice: false,
|
||||
idempotent: true,
|
||||
};
|
||||
const base = TOOL_EFFECTS["binary_session"];
|
||||
if (base === undefined) throw new Error("binary_session is unaudited");
|
||||
expect(annotationsFromEffects(base)).toEqual({
|
||||
readOnlyHint: true,
|
||||
destructiveHint: false,
|
||||
|
||||
@@ -605,7 +605,7 @@ export const TOOL_EFFECTS: Readonly<Record<string, ToolEffects>> = {
|
||||
mayDiscardData: true,
|
||||
idempotent: false,
|
||||
}),
|
||||
binary_session: effects({ launchesProcess: true }),
|
||||
binary_session: effects(),
|
||||
export_evidence_bundle: effects({
|
||||
writesFilesystem: true,
|
||||
mayDiscardData: true,
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
assertLinuxPackageProviderFailure,
|
||||
verifyPackagePlatform,
|
||||
} from "../../../scripts/verify-package-platform.mjs";
|
||||
import { assertLinuxPackageProviderFailure } from "../../../scripts/verify-package-platform.mjs";
|
||||
|
||||
const missingDisplay = {
|
||||
code: "provider_unavailable",
|
||||
@@ -25,37 +22,6 @@ const execution = (failure: unknown, status = 1) => ({
|
||||
stdout: JSON.stringify(failure),
|
||||
});
|
||||
|
||||
const overview = (procedure_count?: unknown, operation = "binary_overview") => ({
|
||||
operation,
|
||||
...(procedure_count === undefined
|
||||
? {}
|
||||
: { normalized_result: { procedure_count } }),
|
||||
});
|
||||
|
||||
const verifyMacOS = async (
|
||||
analyze: unknown,
|
||||
inspect: unknown,
|
||||
): Promise<void> => {
|
||||
const outputs: Readonly<Record<string, unknown>> = {
|
||||
analyze,
|
||||
inspect,
|
||||
function: {
|
||||
operation: "analyze_function",
|
||||
provider: { id: "hopper" },
|
||||
normalized_result: { procedure: { address: "0x1000" } },
|
||||
},
|
||||
xrefs: { operation: "xrefs", normalized_result: ["0x1000"] },
|
||||
trace: { operation: "trace_feature" },
|
||||
};
|
||||
await verifyPackagePlatform({
|
||||
cli: "fixture-cli",
|
||||
environment: {},
|
||||
platform: "darwin",
|
||||
runCommand: async (_cli, arguments_) =>
|
||||
JSON.stringify(outputs[arguments_[0]!]) ?? "",
|
||||
});
|
||||
};
|
||||
|
||||
describe("packaged Linux failure verification", () => {
|
||||
it("accepts the unsupported fixture build or an exact missing display dependency", () => {
|
||||
expect(() =>
|
||||
@@ -105,29 +71,3 @@ describe("packaged Linux failure verification", () => {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("packaged analyze and inspect result guards", () => {
|
||||
it("accepts positive integer procedure counts for both commands", async () => {
|
||||
await verifyMacOS(overview(1), overview(2));
|
||||
});
|
||||
|
||||
const malformed = [
|
||||
["missing result", undefined],
|
||||
["null result", null],
|
||||
["missing normalized count", overview()],
|
||||
["zero count", overview(0)],
|
||||
["non-integer count", overview(1.5)],
|
||||
["wrong operation", overview(2, "other_operation")],
|
||||
] as const;
|
||||
|
||||
it.each(["analyze", "inspect"] as const)(
|
||||
"rejects malformed %s results before trusting the package",
|
||||
async (command) => {
|
||||
for (const [label, invalid] of malformed) {
|
||||
const analyze = command === "analyze" ? invalid : overview(4);
|
||||
const inspect = command === "inspect" ? invalid : overview(4);
|
||||
await expect(verifyMacOS(analyze, inspect), label).rejects.toThrow();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user