From d1e0b1095f70fd55c7c9d97332b5c15e2aa2d2bd Mon Sep 17 00:00:00 2001 From: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com> Date: Tue, 13 Oct 2026 08:33:12 +0800 Subject: [PATCH] test(ghidra): derive header probe sizes from fixture bytes The shared ELF parser validates the complete header extent. Three ELF64 installation fixtures still declared a 52-byte file despite containing 64-byte headers, turning positive format evidence into unknown evidence. Construct complete-file probes from their bytes in one place, preserving incompatible, truncated and unreadable-header assertions. Reproduced all three CI failures before the correction. All 115 related Ghidra installation/doctor and ELF target/header tests pass afterward. The IDA changes in this PR were verified with Windows IDA Pro 9.3, not IDA Free; this fixture-only correction adds no real-Ghidra verification. --- src/ghidra/GhidraInstallation.test.ts | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/ghidra/GhidraInstallation.test.ts b/src/ghidra/GhidraInstallation.test.ts index 185c719738..21c4195adf 100644 --- a/src/ghidra/GhidraInstallation.test.ts +++ b/src/ghidra/GhidraInstallation.test.ts @@ -5,6 +5,7 @@ import { projectGhidraDoctorInspection } from "./GhidraDoctor.js"; import { ghidraJavaEnvironment, inspectGhidraInstallation, + type GhidraExecutableHeaderProbe, type GhidraInstallationHost, type GhidraJavaObservation, } from "./GhidraInstallation.js"; @@ -23,6 +24,11 @@ const WINDOWS_PROPERTIES = `${WINDOWS_INSTALL}\\Ghidra\\application.properties`; const WINDOWS_HEADLESS = `${WINDOWS_INSTALL}\\support\\analyzeHeadless.bat`; const WINDOWS_DECOMPILER = `${WINDOWS_INSTALL}\\Ghidra\\Features\\Decompiler\\os\\win_x86_64\\decompile.exe`; +const headerProbe = (bytes: Buffer): GhidraExecutableHeaderProbe => ({ + bytes, + size: bytes.length, +}); + const JAVA: GhidraJavaObservation = { version: "21.0.11", major: SUPPORTED_GHIDRA_JAVA_MAJOR, @@ -543,7 +549,7 @@ describe("Ghidra FAT native decompiler admission", () => { platform: "darwin", architecture: "arm64", }, - host({ executableHeader: () => ({ bytes, size: bytes.length }) }), + host({ executableHeader: () => headerProbe(bytes) }), ); expect(result.status).toBe(status); expect( @@ -561,7 +567,7 @@ describe("Ghidra FAT native decompiler admission", () => { platform: "darwin", architecture: "arm64", }, - host({ executableHeader: () => ({ bytes, size: bytes.length }) }), + host({ executableHeader: () => headerProbe(bytes) }), ); expect(result.status).toBe("available"); expect( @@ -581,9 +587,7 @@ describe("Ghidra native decompiler admission", () => { architecture: "x64" as const, }, executableHeader: (path: string) => - path === LINUX_DECOMPILER - ? { bytes: elf(1, 1, 8), size: 52 } - : undefined, + path === LINUX_DECOMPILER ? headerProbe(elf(1, 1, 8)) : undefined, }, { name: "a Linux x86-64 decompiler at the macOS arm64 path", @@ -594,9 +598,7 @@ describe("Ghidra native decompiler admission", () => { architecture: "arm64" as const, }, executableHeader: (path: string) => - path === MAC_DECOMPILER - ? { bytes: elf(2, 1, 62), size: 52 } - : undefined, + path === MAC_DECOMPILER ? headerProbe(elf(2, 1, 62)) : undefined, }, { name: "a macOS arm64 decompiler at the Linux x64 path", @@ -608,7 +610,7 @@ describe("Ghidra native decompiler admission", () => { }, executableHeader: (path: string) => path === LINUX_DECOMPILER - ? { bytes: thinMach(0xcffaedfe, 0x0100000c), size: 32 } + ? headerProbe(thinMach(0xcffaedfe, 0x0100000c)) : undefined, }, ])("distinguishes $name", ({ options, executableHeader }) => { @@ -632,9 +634,7 @@ describe("Ghidra native decompiler admission", () => { }, host({ executableHeader: (path: string) => - path === LINUX_DECOMPILER - ? { bytes: elf(2, 1, 62), size: 52 } - : undefined, + path === LINUX_DECOMPILER ? headerProbe(elf(2, 1, 62)) : undefined, }), ); expect(result.status).toBe("available"); @@ -678,7 +678,7 @@ describe("Ghidra native decompiler admission", () => { }, host({ executableHeader: (path: string) => - path === MAC_DECOMPILER ? { bytes, size: bytes.length } : undefined, + path === MAC_DECOMPILER ? headerProbe(bytes) : undefined, }), ); expect(result.status).toBe("available"); @@ -701,9 +701,7 @@ describe("Ghidra native decompiler admission", () => { }, host({ executableHeader: (path: string) => - path === MAC_DECOMPILER - ? { bytes: elf(2, 1, 62), size: 52 } - : undefined, + path === MAC_DECOMPILER ? headerProbe(elf(2, 1, 62)) : undefined, }), ); expect(result.status).toBe("unavailable");