[PR #1015] [CLOSED] docs(ghidra): explain Windows P0 rejections for 32-bit x86 PE targets #2582

Closed
opened 2026-10-17 21:07:51 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1015
Author: @akram1089
Created: 10/7/2026
Status: ❌ Closed

Base: main ← Head: docs/806-windows-x86-pe-boundary


📝 Commits (1)

  • 57f42af docs(ghidra): explain Windows P0 rejections for 32-bit x86 PE targets

📊 Changes

2 files changed (+36 additions, -0 deletions)

View changed files

📝 docs/windows-ghidra-p0.md (+31 -0)
📝 src/ghidra/GhidraProvider.behavior.test.ts (+5 -0)

📄 Description

Summary

Refs #806.

On Windows, open_binary identifies a 32-bit x86 PE executable, but every later deep operation fails with a generic provider_unavailable. The Windows Ghidra P0 guide states the supported x86-64 boundary, but it does not say what happens to a target outside that boundary, why the failure reads provider_unavailable instead of target_unsupported, or where to find the real rejection reason. This PR documents that path and the providers that admit such targets, and pins the 32-bit x86 rejection with a test.

It does not add 32-bit x86 support to Windows Ghidra P0, so it references #806 rather than closing it. The maintainer can decide whether this documentation is enough for the issue's "clearly documented ... and exposed an appropriate alternative" option.

Problem and expected behavior

  • Trigger (from #806): on a Windows x64 host, open a native 32-bit x86 PE application with automatic provider selection, then request binary_overview or list_procedures.
  • Observed: open_binary succeeds (format: pe, architecture: x86). The deep operation fails with provider_unavailable, and the actionable reason ("Windows Ghidra P0 accepts x86-64 PE targets only.") appears only in the diagnostics.
  • Cause, traced in source:
    • GhidraProvider.inspectTargetSupport on win32 returns architecture_unsupported for any non-x86_64 PE.
    • HopperProvider admits the PE but is unavailable with unsupported_host on Windows.
    • Automatic selection therefore finds no usable candidate, and open_binary opens without a bound provider (AnalysisProviderRegistry#selectAutomatically).
    • unboundOperationError reports target_unsupported only when every candidate rejects the target. Because Hopper admits it, the reported reason is provider_unavailable.
  • Expected: the guide explains this outcome, shows where the per-provider reasons appear, and points to providers that admit these targets, without claiming unverified coverage.

Change and scope

  • docs/windows-ghidra-p0.md: a new "Targets outside this boundary" subsection under "Supported boundary".
    • A table of the Windows Ghidra rejection codes, taken from inspectWindowsP0TargetSupport: target_kind_unsupported, target_format_unsupported, architecture_unsupported, target_role_unsupported, and managed_target_unsupported.
    • How automatic selection reports target_unsupported versus provider_unavailable, and that an explicit Ghidra selection can fail open_binary with target_unsupported instead.
    • Where the per-provider reason appears: binary_session analysis_provider_candidates[].availability / target_support, and the error's details.rejections, which analysisErrorProjection.providerErrorDetails serializes.
    • Which providers admit these targets, scoped to admission rather than verification:
      • IDA admits executable inputs without an architecture restriction (IdaProvider.inspectTargetSupport); its guide states its verified scope.
      • Linux/macOS Ghidra admits x86, x86-64, ARM, and ARM64 (SUPPORTED_ARCHITECTURES), and its real PE conformance covers x86-64 PE.
  • src/ghidra/GhidraProvider.behavior.test.ts: the existing Windows P0 test already pinned ARM64 PE. It now also asserts that a native 32-bit x86 PE application is architecture_unsupported, with host_platform: "win32" and architecture: "x86" diagnostics.

Not included:

  • No change to admission, selection, error codes, or messages.
  • No 32-bit Windows support.
  • No claim that IDA or Linux/macOS Ghidra has been verified on 32-bit PE.

Contract and boundary impact

  • Semantic owner and earliest changed stage: documentation only (Windows Ghidra P0 guide), plus a provider test
  • CLI and MCP/tool-catalog contract: none
  • Provider, bridge, target-format, or platform compatibility: none (documents existing admission)
  • Evidence, artifact, provenance, or reconstruction contract: none
  • Process execution, authorization, cleanup, or containment impact: none
  • Generated metadata (docs/product-catalog.json), package, or installation impact: none

Evidence and regression coverage

  • Tests added or updated: keeps Windows P0 unavailable until native isolation authority exists now covers peTarget("x86").
  • Base reproduction or other evidence: the documented behavior is source-derived from GhidraProvider.ts (inspectWindowsP0TargetSupport), HopperProvider.ts (inspectAvailability and inspectTargetSupport), IdaProvider.ts, AnalysisProviderRegistry.ts (select, #selectConcrete, #selectAutomatically, unboundOperationError), BinarySessionStatus.ts, and analysisErrorProjection.ts. It matches the open_binary success followed by provider_unavailable reported in #806.
  • User-visible CLI/MCP output: not applicable (no output change)
  • Remaining proof gaps: no real Windows Ghidra or IDA run against a 32-bit PE was performed. The guide states admission only and defers verified scope to each provider's guide.

Validation performed

  • npx vitest run src/ghidra/GhidraProvider.behavior.test.ts: 26 passed
  • npm run check:fast (typecheck and lint): passed
  • npx oxfmt --check docs/windows-ghidra-p0.md src/ghidra/GhidraProvider.behavior.test.ts: all files formatted

Compatibility, safety, and release

  • Breaking changes or migration steps: none
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable (docs and a unit test only)
  • Package or release metadata impact: none
  • Security, privacy, process, or containment review: no paths, secrets, or target data added

Review checklist

  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1015 **Author:** [@akram1089](https://github.com/akram1089) **Created:** 10/7/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `docs/806-windows-x86-pe-boundary` --- ### 📝 Commits (1) - [`57f42af`](https://github.com/morluto/rea/commit/57f42af4526ce5ed9982aa4574832128db5f6e9e) docs(ghidra): explain Windows P0 rejections for 32-bit x86 PE targets ### 📊 Changes **2 files changed** (+36 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `docs/windows-ghidra-p0.md` (+31 -0) 📝 `src/ghidra/GhidraProvider.behavior.test.ts` (+5 -0) </details> ### 📄 Description ## Summary Refs #806. On Windows, `open_binary` identifies a 32-bit x86 PE executable, but every later deep operation fails with a generic `provider_unavailable`. The Windows Ghidra P0 guide states the supported x86-64 boundary, but it does not say what happens to a target outside that boundary, why the failure reads `provider_unavailable` instead of `target_unsupported`, or where to find the real rejection reason. This PR documents that path and the providers that admit such targets, and pins the 32-bit x86 rejection with a test. It does not add 32-bit x86 support to Windows Ghidra P0, so it references #806 rather than closing it. The maintainer can decide whether this documentation is enough for the issue's "clearly documented ... and exposed an appropriate alternative" option. ## Problem and expected behavior - Trigger (from #806): on a Windows x64 host, open a native 32-bit x86 PE application with automatic provider selection, then request `binary_overview` or `list_procedures`. - Observed: `open_binary` succeeds (`format: pe`, `architecture: x86`). The deep operation fails with `provider_unavailable`, and the actionable reason ("Windows Ghidra P0 accepts x86-64 PE targets only.") appears only in the diagnostics. - Cause, traced in source: - `GhidraProvider.inspectTargetSupport` on `win32` returns `architecture_unsupported` for any non-`x86_64` PE. - `HopperProvider` admits the PE but is unavailable with `unsupported_host` on Windows. - Automatic selection therefore finds no usable candidate, and `open_binary` opens without a bound provider (`AnalysisProviderRegistry#selectAutomatically`). - `unboundOperationError` reports `target_unsupported` only when every candidate rejects the target. Because Hopper admits it, the reported reason is `provider_unavailable`. - Expected: the guide explains this outcome, shows where the per-provider reasons appear, and points to providers that admit these targets, without claiming unverified coverage. ## Change and scope - `docs/windows-ghidra-p0.md`: a new "Targets outside this boundary" subsection under "Supported boundary". - A table of the Windows Ghidra rejection codes, taken from `inspectWindowsP0TargetSupport`: `target_kind_unsupported`, `target_format_unsupported`, `architecture_unsupported`, `target_role_unsupported`, and `managed_target_unsupported`. - How automatic selection reports `target_unsupported` versus `provider_unavailable`, and that an explicit Ghidra selection can fail `open_binary` with `target_unsupported` instead. - Where the per-provider reason appears: `binary_session` `analysis_provider_candidates[].availability` / `target_support`, and the error's `details.rejections`, which `analysisErrorProjection.providerErrorDetails` serializes. - Which providers admit these targets, scoped to admission rather than verification: - IDA admits executable inputs without an architecture restriction (`IdaProvider.inspectTargetSupport`); its guide states its verified scope. - Linux/macOS Ghidra admits x86, x86-64, ARM, and ARM64 (`SUPPORTED_ARCHITECTURES`), and its real PE conformance covers x86-64 PE. - `src/ghidra/GhidraProvider.behavior.test.ts`: the existing Windows P0 test already pinned ARM64 PE. It now also asserts that a native 32-bit x86 PE application is `architecture_unsupported`, with `host_platform: "win32"` and `architecture: "x86"` diagnostics. Not included: - No change to admission, selection, error codes, or messages. - No 32-bit Windows support. - No claim that IDA or Linux/macOS Ghidra has been verified on 32-bit PE. ## Contract and boundary impact - Semantic owner and earliest changed stage: documentation only (Windows Ghidra P0 guide), plus a provider test - CLI and MCP/tool-catalog contract: none - Provider, bridge, target-format, or platform compatibility: none (documents existing admission) - Evidence, artifact, provenance, or reconstruction contract: none - Process execution, authorization, cleanup, or containment impact: none - Generated metadata (`docs/product-catalog.json`), package, or installation impact: none ## Evidence and regression coverage - Tests added or updated: `keeps Windows P0 unavailable until native isolation authority exists` now covers `peTarget("x86")`. - Base reproduction or other evidence: the documented behavior is source-derived from `GhidraProvider.ts` (`inspectWindowsP0TargetSupport`), `HopperProvider.ts` (`inspectAvailability` and `inspectTargetSupport`), `IdaProvider.ts`, `AnalysisProviderRegistry.ts` (`select`, `#selectConcrete`, `#selectAutomatically`, `unboundOperationError`), `BinarySessionStatus.ts`, and `analysisErrorProjection.ts`. It matches the `open_binary` success followed by `provider_unavailable` reported in #806. - User-visible CLI/MCP output: not applicable (no output change) - Remaining proof gaps: no real Windows Ghidra or IDA run against a 32-bit PE was performed. The guide states admission only and defers verified scope to each provider's guide. ## Validation performed - `npx vitest run src/ghidra/GhidraProvider.behavior.test.ts`: 26 passed - `npm run check:fast` (typecheck and lint): passed - `npx oxfmt --check docs/windows-ghidra-p0.md src/ghidra/GhidraProvider.behavior.test.ts`: all files formatted ## Compatibility, safety, and release - Breaking changes or migration steps: none - Real Hopper/Ghidra, browser, or OS coverage: not applicable (docs and a unit test only) - Package or release metadata impact: none - Security, privacy, process, or containment review: no paths, secrets, or target data added ## Review checklist - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:07:51 +00:00
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#2582
No description provided.