mirror of
https://github.com/morluto/rea.git
synced 2026-11-07 05:56:19 -10:00
fix(ghidra): guide packed program import recovery (#8820)
* fix(ghidra): guide packed program import recovery * test(ghidra): verify packed import recovery facts
This commit is contained in:
1 parent
fdfc210879
commit
9196c30f6e
3 files changed
+64
-4
No files matched your search
@@ -1429,6 +1429,20 @@ in the project root; when omitted it defaults to the selected target's filename.
|
||||
Paths, globs and command flags are not program names. The matching `.rep`
|
||||
directory must be present; restore `.grez` archives with Ghidra first.
|
||||
|
||||
For a `.gzf` packed program, first import it into a new Ghidra project in an
|
||||
existing, caller-selected directory. A packed program is not a `.grez` project
|
||||
archive:
|
||||
|
||||
```bash
|
||||
"$GHIDRA_INSTALL_DIR/support/analyzeHeadless" "/absolute/new-project-directory" "new-project" \
|
||||
-import "/absolute/program.gzf" -noanalysis
|
||||
```
|
||||
|
||||
Select the resulting `new-project.gpr` with `REA_GHIDRA_PROJECT_PATH`. If the
|
||||
imported program name differs from the selected target's filename, set
|
||||
`REA_GHIDRA_PROGRAM_NAME` to the name reported by Ghidra's import. REA then
|
||||
opens its own read-only project copy; it does not import the packed program.
|
||||
|
||||
```bash
|
||||
export REA_ANALYSIS_PROVIDER=ghidra
|
||||
export REA_GHIDRA_PROJECT_PATH=/absolute/projects/app-analysis.gpr
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
import { isAbsolute, basename } from "node:path";
|
||||
import { z } from "zod";
|
||||
|
||||
/** Recovery for a packed Program selected where REA requires a project. */
|
||||
export const GHIDRA_PACKED_PROGRAM_RECOVERY =
|
||||
"A .gzf is a packed program, not a .gpr project. Import it into a new project with Ghidra analyzeHeadless <project-directory> <project-name> -import <file.gzf> -noanalysis; select its .gpr and, if needed, set REA_GHIDRA_PROGRAM_NAME to the imported program name.";
|
||||
|
||||
/** A single expanded local project marker; archives must be restored first. */
|
||||
export const ghidraProjectPathSchema = z
|
||||
.string()
|
||||
.min(1)
|
||||
.refine(isAbsolute, "Ghidra project path must be absolute")
|
||||
.refine(
|
||||
(path) => path.endsWith(".gpr") && basename(path).length > 4,
|
||||
"Select an expanded .gpr project marker; restore .grez archives first",
|
||||
);
|
||||
.superRefine((path, context) => {
|
||||
if (path.endsWith(".gpr") && basename(path).length > 4) return;
|
||||
context.addIssue({
|
||||
code: "custom",
|
||||
message: path.toLowerCase().endsWith(".gzf")
|
||||
? GHIDRA_PACKED_PROGRAM_RECOVERY
|
||||
: "Select an expanded .gpr project marker; restore .grez archives first",
|
||||
});
|
||||
});
|
||||
|
||||
/** Headless -process accepts globs and flags; this workflow selects one root program. */
|
||||
export const ghidraProgramNameSchema = z
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { join } from "node:path";
|
||||
import { expect } from "vitest";
|
||||
|
||||
import { GHIDRA_PACKED_PROGRAM_RECOVERY } from "../../../src/config/ghidraExistingProject.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
|
||||
cliTest(
|
||||
"explains how to import a packed Ghidra program before selecting a project",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-packed-project-doctor-");
|
||||
const result = await cli.run({
|
||||
arguments: ["--json", "doctor", "--provider", "ghidra"],
|
||||
environment: { REA_GHIDRA_PROJECT_PATH: join(root, "program.gzf") },
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.json).toMatchObject({
|
||||
healthy: false,
|
||||
scope_checks: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "runtime-configuration:REA_GHIDRA_PROJECT_PATH",
|
||||
ok: false,
|
||||
classification: "config_drift",
|
||||
detail: `REA_GHIDRA_PROJECT_PATH: ${GHIDRA_PACKED_PROGRAM_RECOVERY}`,
|
||||
}),
|
||||
]),
|
||||
});
|
||||
for (const required of [
|
||||
"analyzeHeadless",
|
||||
"-import",
|
||||
"-noanalysis",
|
||||
".gpr",
|
||||
"REA_GHIDRA_PROGRAM_NAME",
|
||||
])
|
||||
expect(GHIDRA_PACKED_PROGRAM_RECOVERY).toContain(required);
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user