fix(ghidra): publish Windows verification success after cleanup

This commit is contained in:
morluto committed 2026-10-10 13:43:01 +08:00
1 parent 941dc425ca
commit 7633dd8d5d
3 files changed
+46 -13

No files matched your search

+1 -1
View File
@@ -379,7 +379,7 @@ the tool fails with a `debugger-attach-denied` reason.
Install a Ghidra 12.1.x release and the 64-bit full JDK it declares, then configure REA to
use them. Ghidra analysis supports Linux x64/arm64 and macOS x64/arm64; each installation requires
the matching native decompiler. Experimental Windows x64 P0 admits native
x86-64 PE applications on local NTFS using bundled Job Object ownership,
x86 and x86-64 PE applications and DLLs on local NTFS using bundled Job Object ownership,
protected runtime DACLs, and handle-based path admission. See [Windows Ghidra P0](windows-ghidra-p0.md) and
[issue #527](https://github.com/morluto/rea/issues/527).
On Linux and macOS, `annotate_native_function` atomically edits a function name
+19 -12
View File
@@ -26,12 +26,21 @@ if (process.platform !== "win32" || process.arch !== "x64")
);
const exec = promisify(execFile);
const arguments_ = process.argv.slice(2);
const internalWorkspace = arguments_[0] === "--internal-workspace";
const fixtureArguments = internalWorkspace ? arguments_.slice(2) : arguments_;
const x86Fixture = fixtureArguments.includes("--x86");
const dllFixture = fixtureArguments.includes("--dll");
const [packageRootArgument, targetArgument, reportArgument] =
fixtureArguments.filter(
(argument) => argument !== "--x86" && argument !== "--dll",
);
// Windows locks the loaded package-owned addon until the verifier exits.
// Keep installation cleanup in a parent that never loads that addon.
if (arguments_[0] !== "--internal-workspace") {
if (!internalWorkspace) {
const ownedWorkspace = await mkdtemp(join(tmpdir(), "rea-packaged-ghidra-"));
let result;
try {
const result = await exec(
result = await exec(
process.execPath,
[
fileURLToPath(import.meta.url),
@@ -41,8 +50,6 @@ if (arguments_[0] !== "--internal-workspace") {
],
{ timeout: 900_000, maxBuffer: 8 * 1024 * 1024 },
);
process.stdout.write(result.stdout);
process.stderr.write(result.stderr);
} catch (cause) {
if (typeof cause.stdout === "string") process.stdout.write(cause.stdout);
if (typeof cause.stderr === "string") process.stderr.write(cause.stderr);
@@ -50,17 +57,17 @@ if (arguments_[0] !== "--internal-workspace") {
} finally {
await rm(ownedWorkspace, { recursive: true, force: true });
}
const report = JSON.parse(result.stdout);
report.workspaceCleanup = true;
report.ok = true;
if (reportArgument !== undefined)
await writeFile(reportArgument, `${JSON.stringify(report)}\n`);
process.stdout.write(`${JSON.stringify(report)}\n`);
process.stderr.write(result.stderr);
process.exit(0);
}
assert.ok(arguments_[1] !== undefined, "Missing verifier workspace.");
const workspace = resolve(arguments_[1]);
const fixtureArguments = arguments_.slice(2);
const x86Fixture = fixtureArguments.includes("--x86");
const dllFixture = fixtureArguments.includes("--dll");
const [packageRootArgument, targetArgument, reportArgument] =
fixtureArguments.filter(
(argument) => argument !== "--x86" && argument !== "--dll",
);
let packageRoot = resolve(packageRootArgument ?? ".");
// The default lane verifies the npm artifact in an isolated prefix. Explicit
// package roots support an already-installed artifact without a second install.
@@ -402,7 +409,7 @@ try {
assert.deepEqual(await readdir(join(callerDirectory, name)), []);
report.callerScriptCollisionsPreserved = true;
report.runtimeCleanup = true;
report.ok = true;
// Only the parent can attest success after removing the installation.
if (reportArgument !== undefined)
await writeFile(reportArgument, `${JSON.stringify(report)}\n`);
process.stdout.write(`${JSON.stringify(report)}\n`);
@@ -198,6 +198,32 @@ describe("Ghidra Mach-O slice support", () => {
});
describe("Ghidra platform support", () => {
it("commits the PE role and managed classification to profile identity", async () => {
const ghidra = provider({ ...installationHost(), platform: "win32" });
const application = peTarget("x86_64");
const library = {
...application,
executableRole: "shared-library",
} as const;
const digests = new Set<string>();
for (const target of [
application,
library,
{ ...library, managed: true },
]) {
const resolved = await ghidra.resolveAnalysisProfile(target);
if (!resolved.ok) throw resolved.error;
const profile = resolved.value.profile;
if (profile === null) throw new Error("Expected a PE analysis profile");
expect(profile.parameters).toMatchObject({
executable_role: target.executableRole,
managed: target.managed,
});
digests.add(profile.digest);
}
expect(digests.size).toBe(3);
});
it("keeps Windows annotation mutation unavailable independently of native controls", () => {
const ghidra = provider({ ...installationHost(), platform: "win32" });
expect(