mirror of
https://github.com/morluto/rea.git
synced 2026-10-29 19:05:45 +00:00
Copy each selected target into the ephemeral Ghidra runtime and reject the snapshot unless its SHA-256 matches the provider-neutral target identity. Advance the Java bridge protocol to v4, require Ghidra's imported executable digest to match again, and include that digest in the authenticated session handshake and diagnostics. Preserve bounded streaming hashes and remove mismatched snapshots before launch.
52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
import { createHash } from "node:crypto";
|
|
import { access, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
|
|
import { createGhidraTargetSnapshot } from "../src/ghidra/GhidraTargetSnapshot.js";
|
|
|
|
const roots: string[] = [];
|
|
|
|
afterEach(async () => {
|
|
await Promise.all(
|
|
roots.splice(0).map((root) => rm(root, { recursive: true, force: true })),
|
|
);
|
|
});
|
|
|
|
describe("Ghidra target snapshot", () => {
|
|
it("copies an exact digest-bound target into the private runtime", async () => {
|
|
const root = await mkdtemp(join(tmpdir(), "rea-ghidra-snapshot-"));
|
|
roots.push(root);
|
|
const source = join(root, "source.exe");
|
|
const bytes = Buffer.from("native PE fixture");
|
|
const sha256 = createHash("sha256").update(bytes).digest("hex");
|
|
await writeFile(source, bytes);
|
|
|
|
const snapshot = await createGhidraTargetSnapshot(source, root, sha256);
|
|
|
|
expect(snapshot).toEqual({
|
|
path: join(root, `target-${sha256.slice(0, 12)}.exe`),
|
|
sha256,
|
|
});
|
|
await expect(readFile(snapshot.path)).resolves.toEqual(bytes);
|
|
});
|
|
|
|
it("removes a snapshot whose digest differs from admission", async () => {
|
|
const root = await mkdtemp(join(tmpdir(), "rea-ghidra-snapshot-"));
|
|
roots.push(root);
|
|
const source = join(root, "source with unsafe extension.%PATH%");
|
|
await writeFile(source, "changed target");
|
|
const expected = "a".repeat(64);
|
|
const snapshotPath = join(root, `target-${expected.slice(0, 12)}.bin`);
|
|
|
|
await expect(
|
|
createGhidraTargetSnapshot(source, root, expected),
|
|
).rejects.toThrow(/digest mismatch/u);
|
|
await expect(access(snapshotPath)).rejects.toMatchObject({
|
|
code: "ENOENT",
|
|
});
|
|
});
|
|
});
|