mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 08:17:02 +00:00
feat(native): inspect offline ELF layout through pwntools (#1037)
* feat(native): inspect offline ELF layout through pwntools * fix(build): prepare offline ELF verification on clean runners * fix(native): preserve snapshot acquisition cancellation * fix(native): handle sectionless ELF and retain decoder diagnostics * test(native): verify malformed symbol table entry sizes * fix(native): respect inherited limits and unused segment fields * fix(native): preserve packed relocations and decoder launch constraints * fix(native): validate symbol spans and preserve resource failures * fix(native): preserve diagnostic completeness and memory failures * fix(native): guard bridge imports against allocation failures * fix(native): validate relocation symbol and section references * fix(native): retain diagnostics through compounded cleanup failures * fix(native): preserve unresolved relocation section references * fix(native): bound linkage evidence and preserve CPU signal diagnostics * fix(native): preserve file-size resource failure evidence * fix(native): retain opaque linkage names and late cancellation output * test(native): make CPU-limit fixture robust across runners * fix(native): verify resource failure branches before interpreting exits * fix(native): validate declared ELF string references * fix(native): validate section-name table before decoding * fix(native): enforce canonical ELF name-table escapes
This commit is contained in:
1 parent
8d5c88f17c
commit
4fc6565b0f
59 files changed
+5068
-45
No files matched your search
@@ -0,0 +1,131 @@
|
||||
import { expect, it } from "vitest";
|
||||
import { BinaryLayoutService } from "./BinaryLayoutService.js";
|
||||
import {
|
||||
binaryLayoutFixture,
|
||||
BINARY_LAYOUT_TEST_PROVIDER,
|
||||
} from "../../../tests/fixtures/binaryDiagnostics/layout.js";
|
||||
import { parseEvidence } from "../../domain/evidence.js";
|
||||
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
|
||||
import { err, ok } from "../../domain/result.js";
|
||||
|
||||
it("binds original bytes, inline observations, unknowns and producing identity", async () => {
|
||||
const fixture = binaryLayoutFixture();
|
||||
const service = new BinaryLayoutService({
|
||||
identity: BINARY_LAYOUT_TEST_PROVIDER,
|
||||
inspect: () => Promise.resolve(ok(fixture)),
|
||||
});
|
||||
const result = await service.inspect({ path: fixture.artifact.path });
|
||||
if (!result.ok) throw result.error;
|
||||
const evidence = parseEvidence(result.value);
|
||||
expect(evidence.normalized_result).toEqual(fixture);
|
||||
expect(evidence.raw_result).toEqual(fixture);
|
||||
expect(evidence.subject?.digest.sha256).toBe(fixture.artifact.sha256);
|
||||
expect(evidence.provider).toEqual(BINARY_LAYOUT_TEST_PROVIDER);
|
||||
expect(evidence.confidence).toBe("observed");
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ path: "relative.elf" },
|
||||
{ path: "/selected.elf", approval: true },
|
||||
{ path: 123 },
|
||||
{},
|
||||
])(
|
||||
"rejects malformed selection before starting the provider: %j",
|
||||
async (input) => {
|
||||
const service = new BinaryLayoutService({
|
||||
identity: BINARY_LAYOUT_TEST_PROVIDER,
|
||||
inspect: () => {
|
||||
throw new Error("must not run");
|
||||
},
|
||||
});
|
||||
expect(await service.inspect(input)).toMatchObject({
|
||||
ok: false,
|
||||
error: { _tag: "AnalysisInputError" },
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("preserves a provider's actionable unsupported reason", async () => {
|
||||
const failure = new AnalysisCapabilityUnavailableError(
|
||||
"fixture-layout",
|
||||
"inspect_binary_layout",
|
||||
"ELF core belongs to recorded-crash analysis.",
|
||||
);
|
||||
const service = new BinaryLayoutService({
|
||||
identity: BINARY_LAYOUT_TEST_PROVIDER,
|
||||
inspect: () => Promise.resolve(err(failure)),
|
||||
});
|
||||
expect(await service.inspect({ path: "/source.elf" })).toEqual(err(failure));
|
||||
});
|
||||
|
||||
it("cancels before invocation and after an acquired observation", async () => {
|
||||
const controller = new AbortController();
|
||||
const service = new BinaryLayoutService({
|
||||
identity: BINARY_LAYOUT_TEST_PROVIDER,
|
||||
inspect: () => {
|
||||
controller.abort();
|
||||
return Promise.resolve(ok(binaryLayoutFixture()));
|
||||
},
|
||||
});
|
||||
expect(
|
||||
await service.inspect(
|
||||
{ path: "/artifacts/source-owned.elf" },
|
||||
{ signal: controller.signal },
|
||||
),
|
||||
).toMatchObject({
|
||||
ok: false,
|
||||
error: {
|
||||
_tag: "AnalysisCancelledError",
|
||||
capturedOutput: binaryLayoutFixture().diagnostics,
|
||||
},
|
||||
});
|
||||
const untouched = new BinaryLayoutService({
|
||||
identity: BINARY_LAYOUT_TEST_PROVIDER,
|
||||
inspect: () => {
|
||||
throw new Error("must not run");
|
||||
},
|
||||
});
|
||||
expect(
|
||||
await untouched.inspect(
|
||||
{ path: "/source.elf" },
|
||||
{ signal: controller.signal },
|
||||
),
|
||||
).toMatchObject({ ok: false, error: { _tag: "AnalysisCancelledError" } });
|
||||
});
|
||||
|
||||
it.each(["different-path", "invalid-digest", "outside-range"])(
|
||||
"rejects provider evidence at the next boundary: %s",
|
||||
async (problem) => {
|
||||
const fixture = binaryLayoutFixture();
|
||||
if (problem === "different-path") fixture.artifact.path = "/different.elf";
|
||||
if (problem === "invalid-digest") fixture.artifact.sha256 = "unobserved";
|
||||
if (problem === "outside-range")
|
||||
fixture.segments.push({
|
||||
index: 0,
|
||||
type: "PT_LOAD",
|
||||
offset: "0x80",
|
||||
header_location: { offset: "0x0", bytes: "0x38" },
|
||||
file_backing: "file",
|
||||
file_size: "0x1",
|
||||
memory_size: "0x1",
|
||||
virtual_address: "0x20000000000001",
|
||||
physical_address: "0x0",
|
||||
alignment: "0x1",
|
||||
flags: "0x5",
|
||||
permissions: { read: true, write: false, execute: true },
|
||||
});
|
||||
const service = new BinaryLayoutService({
|
||||
identity: BINARY_LAYOUT_TEST_PROVIDER,
|
||||
inspect: () => Promise.resolve(ok(fixture)),
|
||||
});
|
||||
expect(
|
||||
await service.inspect({ path: "/artifacts/source-owned.elf" }),
|
||||
).toMatchObject({
|
||||
ok: false,
|
||||
error: {
|
||||
_tag: "AnalysisOutputError",
|
||||
capturedOutput: fixture.diagnostics,
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user