mirror of
https://github.com/morluto/rea.git
synced 2026-10-19 04:19:54 -05:00
fix(ghidra): publish Windows verification success after cleanup
This commit is contained in:
1 parent
941dc425ca
commit
7633dd8d5d
3 files changed
+46
-13
No files matched your search
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in new issue
Block a user