[GH-ISSUE #2186] Proposal: admit bounded ARM / ARM64 PE targets on Windows Ghidra P0 #730

Closed
opened 2026-10-15 18:27:46 +00:00 by bsakaguchi · 3 comments
Owner

Originally created by @WestLabsAI on GitHub (Oct 12, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2186

Proposal: admit bounded ARM / ARM64 PE targets on Windows Ghidra P0

Summary

On Windows, the Ghidra provider rejects every non-x86 target even though the
general (non-Windows) provider already treats arm and arm64 as first-class
architectures. I'd like to propose extending the Windows P0 admission boundary
to native ARM / ARM64 PE applications and DLLs
, mirroring the existing x86 /
x86-64 PE lane, and I'd like maintainer guidance on the required verification
before I open a PR.

This follows the precedent set for MIPS (#718 / #1362): a bounded architecture
admission with source-owned fixtures, a real-provider verifier, profile-identity
versioning, and docs — explicitly without widening any other coverage.

Current behaviour

inspectTargetSupport routes Windows hosts to inspectWindowsP0TargetSupport
(src/ghidra/GhidraProvider.ts:156), which narrows admission to x86 / x86-64
(src/ghidra/GhidraProvider.ts:313):

if (target.architecture !== "x86" && target.architecture !== "x86_64")
  return {
    status: "unsupported",
    code: "architecture_unsupported",
    reason: "Windows Ghidra P0 accepts x86 and x86-64 PE targets only.",
    diagnostics,
  };

Meanwhile the shared set already lists ARM/ARM64 (src/ghidra/GhidraProvider.ts:63):

const SUPPORTED_ARCHITECTURES = new Set(["x86", "x86_64", "arm", "arm64", "mips"]);

So on Windows an ARM PE is refused with architecture_unsupported purely at the
P0 policy layer, not because the engine cannot handle it.

Evidence that the engine path works on Windows

On a Windows 11 x64 host with the P0-documented toolchain (Ghidra 12.1.4,
Adoptium JDK 21), Ghidra's own headless analyzer analyses ARM firmware without
issue — e.g. a 288 KB ARM Cortex-M image loaded at a fixed base produced ~930
functions and full decompilation via analyzeHeadless ... -processor ARM:LE:32:Cortex.
The only thing refusing ARM through REA on Windows is the P0 architecture gate
above. (That firmware case is raw/Cortex-M and therefore out of scope here — see
non-goals — but it demonstrates the Java/JDK/host path is sound for ARM.)

Proposed scope

In scope

  • Admit native, non-managed ARM and ARM64 PE applications and DLLs through
    inspectWindowsP0TargetSupport, keeping every other P0 constraint identical
    (PE only, application/shared-library role, native/non-managed, NTFS path
    admission, read-only operation set, no database mutation).
  • Whatever native-addon change is needed so the PE-machine validation admits the
    ARM PE machine types (IMAGE_FILE_MACHINE_ARMNT 0x01C4, ARM64 0xAA64)
    alongside the x86/x64 ones.
  • Source-owned ARM/ARM64 PE fixtures (EXE + DLL, no imports/entry, two exported
    functions — matching the existing x86 DLL fixture description).
  • Extend the real-provider verification lane (verify:ghidra:windows) and the
    packaged lane to cover ARM, and bump the analysis-profile identity so older
    snapshots invalidate.
  • Docs: docs/windows-ghidra-p0.md, docs/ghidra-provider.md.

Non-goals (explicitly out of scope)

  • Raw / headerless binaries on Windows P0 (docs/raw-binary.md keeps Windows to
    "PE applications only").
  • Cortex-M / Thumb-only / big-endian processor variants, which docs/raw-binary.md
    already lists as unsupported for the raw feature. (Possible later follow-up.)
  • Any database-mutation or write authority on Windows P0.

Open questions for maintainers

  1. Is extending P0 to ARM/ARM64 PE acceptable in principle, or is the x86-only
    boundary intentional for reasons beyond staged verification?
  2. What verification evidence do you require to merge? The P0 native controls
    (DACLs, Job Object, path admission, loopback auth) look architecture-neutral,
    but the PE-machine check and the verify:ghidra:windows lane are the parts I
    expect to need real ARM runs for.
  3. Does the native Windows addon need rebuilding to admit ARM PE machine types,
    or is PE-machine admission enforced only in TypeScript?
  4. Should this track under a new issue or fold into the existing architecture
    roadmap (the one that carried #718)?

Environment

  • Host: Windows 11 x64
  • Ghidra: 12.1.4 (operator-installed), Adoptium JDK 21
  • REA: rea-agents 6.4.0 (repository main @ 5190843)
Originally created by @WestLabsAI on GitHub (Oct 12, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2186 # Proposal: admit bounded ARM / ARM64 PE targets on Windows Ghidra P0 ## Summary On Windows, the Ghidra provider rejects every non-x86 target even though the general (non-Windows) provider already treats `arm` and `arm64` as first-class architectures. I'd like to propose **extending the Windows P0 admission boundary to native ARM / ARM64 PE applications and DLLs**, mirroring the existing x86 / x86-64 PE lane, and I'd like maintainer guidance on the required verification before I open a PR. This follows the precedent set for MIPS (#718 / #1362): a *bounded* architecture admission with source-owned fixtures, a real-provider verifier, profile-identity versioning, and docs — explicitly without widening any other coverage. ## Current behaviour `inspectTargetSupport` routes Windows hosts to `inspectWindowsP0TargetSupport` (`src/ghidra/GhidraProvider.ts:156`), which narrows admission to x86 / x86-64 (`src/ghidra/GhidraProvider.ts:313`): ```ts if (target.architecture !== "x86" && target.architecture !== "x86_64") return { status: "unsupported", code: "architecture_unsupported", reason: "Windows Ghidra P0 accepts x86 and x86-64 PE targets only.", diagnostics, }; ``` Meanwhile the shared set already lists ARM/ARM64 (`src/ghidra/GhidraProvider.ts:63`): ```ts const SUPPORTED_ARCHITECTURES = new Set(["x86", "x86_64", "arm", "arm64", "mips"]); ``` So on Windows an ARM PE is refused with `architecture_unsupported` purely at the P0 policy layer, not because the engine cannot handle it. ## Evidence that the engine path works on Windows On a Windows 11 x64 host with the P0-documented toolchain (Ghidra 12.1.4, Adoptium JDK 21), Ghidra's own headless analyzer analyses ARM firmware without issue — e.g. a 288 KB ARM Cortex-M image loaded at a fixed base produced ~930 functions and full decompilation via `analyzeHeadless ... -processor ARM:LE:32:Cortex`. The only thing refusing ARM through REA on Windows is the P0 architecture gate above. (That firmware case is raw/Cortex-M and therefore out of scope here — see non-goals — but it demonstrates the Java/JDK/host path is sound for ARM.) ## Proposed scope **In scope** - Admit native, non-managed **ARM and ARM64 PE** applications and DLLs through `inspectWindowsP0TargetSupport`, keeping every other P0 constraint identical (PE only, application/shared-library role, native/non-managed, NTFS path admission, read-only operation set, no database mutation). - Whatever native-addon change is needed so the PE-machine validation admits the ARM PE machine types (`IMAGE_FILE_MACHINE_ARMNT 0x01C4`, `ARM64 0xAA64`) alongside the x86/x64 ones. - Source-owned ARM/ARM64 PE fixtures (EXE + DLL, no imports/entry, two exported functions — matching the existing x86 DLL fixture description). - Extend the real-provider verification lane (`verify:ghidra:windows`) and the packaged lane to cover ARM, and bump the analysis-profile identity so older snapshots invalidate. - Docs: `docs/windows-ghidra-p0.md`, `docs/ghidra-provider.md`. **Non-goals (explicitly out of scope)** - Raw / headerless binaries on Windows P0 (`docs/raw-binary.md` keeps Windows to "PE applications only"). - Cortex-M / Thumb-only / big-endian processor variants, which `docs/raw-binary.md` already lists as unsupported for the raw feature. (Possible later follow-up.) - Any database-mutation or write authority on Windows P0. ## Open questions for maintainers 1. Is extending P0 to ARM/ARM64 PE acceptable in principle, or is the x86-only boundary intentional for reasons beyond staged verification? 2. What verification evidence do you require to merge? The P0 native controls (DACLs, Job Object, path admission, loopback auth) look architecture-neutral, but the PE-machine check and the `verify:ghidra:windows` lane are the parts I expect to need real ARM runs for. 3. Does the native Windows addon need rebuilding to admit ARM PE machine types, or is PE-machine admission enforced only in TypeScript? 4. Should this track under a new issue or fold into the existing architecture roadmap (the one that carried #718)? ## Environment - Host: Windows 11 x64 - Ghidra: 12.1.4 (operator-installed), Adoptium JDK 21 - REA: `rea-agents` 6.4.0 (repository main @ `5190843`)
Author
Owner

@matbrgz commented on GitHub (Oct 12, 2026):

Architecture & Scope Decision Review

Admitting bounded ARM / ARM64 PE targets on Windows Ghidra P0 aligns with Windows on Arm (WoA) adoption and mirrors the existing macOS ARM64 and Linux AArch64 Ghidra lanes:

  • Language Mapping: Pointers should map explicitly to ARM:LE:32:v8 (for ARM32 PE) and AARCH64:LE:64:v8A (for ARM64/ARM64EC PE), avoiding Ghidra auto-selection ambiguities.
  • Verification Gate: Following the MIPS precedent (#718), integrating this into inspectWindowsP0TargetSupport requires:
    1. Minimal source-built PE fixtures for ARM64 with verified function entry and decompiler readback.
    2. Affirmation in docs/ and npm run verify:ghidra.
<!-- gh-comment-id:6134394224 --> @matbrgz commented on GitHub (Oct 12, 2026): ### Architecture & Scope Decision Review Admitting bounded ARM / ARM64 PE targets on Windows Ghidra P0 aligns with Windows on Arm (WoA) adoption and mirrors the existing macOS ARM64 and Linux AArch64 Ghidra lanes: - **Language Mapping:** Pointers should map explicitly to `ARM:LE:32:v8` (for ARM32 PE) and `AARCH64:LE:64:v8A` (for ARM64/ARM64EC PE), avoiding Ghidra auto-selection ambiguities. - **Verification Gate:** Following the MIPS precedent (#718), integrating this into `inspectWindowsP0TargetSupport` requires: 1. Minimal source-built PE fixtures for ARM64 with verified function entry and decompiler readback. 2. Affirmation in `docs/` and `npm run verify:ghidra`.
Author
Owner

@WestLabsAI commented on GitHub (Oct 13, 2026):

Thanks @matbrgz — this scopes it well, and I agree on keeping it bounded rather than a broad widening.

Language mapping. Agreed:

  • ARM32 PE (IMAGE_FILE_MACHINE_ARMNT) → ARM:LE:32:v8 (Thumb)
  • ARM64 / ARM64EC PE (IMAGE_FILE_MACHINE_ARM64) → AARCH64:LE:64:v8A

For PE targets this is what Ghidra's own PE loader selects from the machine
field, so no manual language assignment (as in the raw-binary lane) is needed —
the provider only has to admit the architecture. ARM64EC is in scope.

Verification gate (following #718). Will provide:

  1. minimal source-built ARM64 PE fixtures (EXE + DLL, no imports/entry, two
    exported functions — same shape as the existing x86 DLL fixtures), with
    verified function entry and decompiler readback;
  2. docs in docs/windows-ghidra-p0.md, and real-provider confirmation via
    npm run verify:ghidra.

Real-provider acceptance needs a Windows-on-Arm host with Ghidra for the
fixture readback; I can supply the fixtures and the admission/test/doc changes,
but would appreciate a pointer on running the verify:ghidra lane on the
protected self-hosted Windows-on-Arm environment (or whether CI can cover it).

Scope clarification. This issue stays limited to native ARM/ARM64 PE.
Raw/headerless ARM (incl. Cortex-M / Thumb-only firmware) remains out of scope
here — that's a separate raw-binary-on-Windows follow-up, consistent with
docs/raw-binary.md.

PoC. I've prepared a bounded change that extends
inspectWindowsP0TargetSupport to admit arm/arm64 PE (keeping the PE-only,
role, native/non-managed, NTFS path-admission and read-only constraints
unchanged), updates the capability text, the Windows P0 admission test, and the
docs. It gates admission only; the real-provider fixture verification above is
the remaining piece before it should merge. Happy to open it as a draft PR
against this issue if that's the preferred next step.

<!-- gh-comment-id:6139122602 --> @WestLabsAI commented on GitHub (Oct 13, 2026): Thanks @matbrgz — this scopes it well, and I agree on keeping it bounded rather than a broad widening. **Language mapping.** Agreed: - ARM32 PE (`IMAGE_FILE_MACHINE_ARMNT`) → `ARM:LE:32:v8` (Thumb) - ARM64 / **ARM64EC** PE (`IMAGE_FILE_MACHINE_ARM64`) → `AARCH64:LE:64:v8A` For PE targets this is what Ghidra's own PE loader selects from the machine field, so no manual language assignment (as in the raw-binary lane) is needed — the provider only has to admit the architecture. ARM64EC is in scope. **Verification gate (following #718).** Will provide: 1. minimal source-built ARM64 PE fixtures (EXE + DLL, no imports/entry, two exported functions — same shape as the existing x86 DLL fixtures), with verified function entry and decompiler readback; 2. docs in `docs/windows-ghidra-p0.md`, and real-provider confirmation via `npm run verify:ghidra`. Real-provider acceptance needs a Windows-on-Arm host with Ghidra for the fixture readback; I can supply the fixtures and the admission/test/doc changes, but would appreciate a pointer on running the `verify:ghidra` lane on the protected self-hosted Windows-on-Arm environment (or whether CI can cover it). **Scope clarification.** This issue stays limited to **native ARM/ARM64 PE**. Raw/headerless ARM (incl. Cortex-M / Thumb-only firmware) remains out of scope here — that's a separate raw-binary-on-Windows follow-up, consistent with `docs/raw-binary.md`. **PoC.** I've prepared a bounded change that extends `inspectWindowsP0TargetSupport` to admit `arm`/`arm64` PE (keeping the PE-only, role, native/non-managed, NTFS path-admission and read-only constraints unchanged), updates the capability text, the Windows P0 admission test, and the docs. It gates admission only; the real-provider fixture verification above is the remaining piece before it should merge. Happy to open it as a draft PR against this issue if that's the preferred next step.
Author
Owner

@WestLabsAI commented on GitHub (Oct 13, 2026):

Thanks @matbrgz — this scopes it well, and I agree on keeping it bounded rather than a broad widening.

Language mapping. Agreed:

  • ARM32 PE (IMAGE_FILE_MACHINE_ARMNT) → ARM:LE:32:v8 (Thumb)
  • ARM64 / ARM64EC PE (IMAGE_FILE_MACHINE_ARM64) → AARCH64:LE:64:v8A

For PE targets this is what Ghidra's own PE loader selects from the machine
field, so no manual language assignment (as in the raw-binary lane) is needed —
the provider only has to admit the architecture. ARM64EC is in scope.

Verification gate (following #718). Will provide:

  1. minimal source-built ARM64 PE fixtures (EXE + DLL, no imports/entry, two
    exported functions — same shape as the existing x86 DLL fixtures), with
    verified function entry and decompiler readback;
  2. docs in docs/windows-ghidra-p0.md, and real-provider confirmation via
    npm run verify:ghidra.

Real-provider acceptance needs a Windows-on-Arm host with Ghidra for the
fixture readback; I can supply the fixtures and the admission/test/doc changes,
but would appreciate a pointer on running the verify:ghidra lane on the
protected self-hosted Windows-on-Arm environment (or whether CI can cover it).

Scope clarification. This issue stays limited to native ARM/ARM64 PE.
Raw/headerless ARM (incl. Cortex-M / Thumb-only firmware) remains out of scope
here — that's a separate raw-binary-on-Windows follow-up, consistent with
docs/raw-binary.md.

PoC. I've prepared a bounded change that extends
inspectWindowsP0TargetSupport to admit arm/arm64 PE (keeping the PE-only,
role, native/non-managed, NTFS path-admission and read-only constraints
unchanged), updates the capability text, the Windows P0 admission test, and the
docs. It gates admission only; the real-provider fixture verification above is
the remaining piece before it should merge. Happy to open it as a draft PR
against this issue if that's the preferred next step.

<!-- gh-comment-id:6139356807 --> @WestLabsAI commented on GitHub (Oct 13, 2026): Thanks @matbrgz — this scopes it well, and I agree on keeping it bounded rather than a broad widening. **Language mapping.** Agreed: - ARM32 PE (`IMAGE_FILE_MACHINE_ARMNT`) → `ARM:LE:32:v8` (Thumb) - ARM64 / **ARM64EC** PE (`IMAGE_FILE_MACHINE_ARM64`) → `AARCH64:LE:64:v8A` For PE targets this is what Ghidra's own PE loader selects from the machine field, so no manual language assignment (as in the raw-binary lane) is needed — the provider only has to admit the architecture. ARM64EC is in scope. **Verification gate (following #718).** Will provide: 1. minimal source-built ARM64 PE fixtures (EXE + DLL, no imports/entry, two exported functions — same shape as the existing x86 DLL fixtures), with verified function entry and decompiler readback; 2. docs in `docs/windows-ghidra-p0.md`, and real-provider confirmation via `npm run verify:ghidra`. Real-provider acceptance needs a Windows-on-Arm host with Ghidra for the fixture readback; I can supply the fixtures and the admission/test/doc changes, but would appreciate a pointer on running the `verify:ghidra` lane on the protected self-hosted Windows-on-Arm environment (or whether CI can cover it). **Scope clarification.** This issue stays limited to **native ARM/ARM64 PE**. Raw/headerless ARM (incl. Cortex-M / Thumb-only firmware) remains out of scope here — that's a separate raw-binary-on-Windows follow-up, consistent with `docs/raw-binary.md`. **PoC.** I've prepared a bounded change that extends `inspectWindowsP0TargetSupport` to admit `arm`/`arm64` PE (keeping the PE-only, role, native/non-managed, NTFS path-admission and read-only constraints unchanged), updates the capability text, the Windows P0 admission test, and the docs. It gates admission only; the real-provider fixture verification above is the remaining piece before it should merge. Happy to open it as a draft PR against this issue if that's the preferred next step.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#730
No description provided.