[GH-ISSUE #4794] Add basic SNES ROM support via Ghidra raw binary loading (65C816) #2493

Open
opened 2026-10-17 21:05:40 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @entzyeung on GitHub (Oct 17, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4794

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Setup, packaging, or upgrade

Current limitation

REA can analyse native binaries, firmware, and several other formats, but has no first-class support for Super Nintendo (SNES) ROM files.
SNES ROMs (.sfc / .smc) are raw cartridge dumps whose main CPU is the 65C816. Users who want to inspect a game (for example Super Street Fighter II) currently have to manually load the file in Ghidra outside of REA’s workflows.

Use cases

A developer or researcher wants to understand how a specific mechanic works in a Super Nintendo game (for example Super Street Fighter II) without manually setting up a Ghidra project outside of REA.

They point REA at a local .sfc/.smc file they own, specify the 65C816 architecture and an optional load address, and receive the same structured Evidence (pseudocode, cross-references, strings, etc.) that REA already returns for other native binaries.

Desired outcome and success criteria

Add a minimal way to open a single-file SNES ROM and receive the same Evidence format REA already returns for other binaries (pseudocode, xrefs, strings, etc.).

Proposed interface (MCP / CLI):

  • Accept a local path to a .sfc or .smc file
  • Accept an architecture identifier (65816 / 65c816)
  • Accept an optional load address (default suitable for common LoROM mapping)
  • Hand the bytes to Ghidra as a raw binary with the 65C816 processor
  • Return normal REA Evidence

Success criteria:

  • Opening a user-supplied SNES ROM produces usable pseudocode and cross-references for at least a few functions
  • The existing Evidence contracts and Ghidra provider are reused
  • No commercial ROM or decompiled commercial code is shipped

Expected interaction with targets

Read existing files or captured data

Target and scope details (optional)

Read-only analysis of a caller-supplied local .sfc/.smc file.
No execution, injection, mutation, network access, or persistence of the target.
Ghidra (or equivalent backend) is used only for static analysis of the provided bytes.

Scope (v1):

  • Single-file ROM only
  • Explicit architecture + optional load address
  • Reuse existing Ghidra provider and Evidence contracts
  • Read-only analysis

Non-goals:

  • No multi-file or interleaved ROM sets
  • No automatic LoROM/HiROM detection (manual load address is fine for v1)
  • No emulation or running the game
  • No shipping or embedding any commercial ROM or decompiled commercial code
  • No new disassembler (rely on Ghidra’s existing 65C816 support)

Verification available so far

Idea only; I need help defining checks

Verification details (optional)

Verification plan:

  • Use a user-supplied Super Street Fighter II (SNES) ROM that the contributor owns
  • Confirm that opening the ROM produces usable pseudocode and cross-references for at least a few known functions
  • Document the exact Ghidra language ID and load-address examples used
  • No commercial ROM or decompiled commercial code will be attached or shipped

Alternatives considered

  • Manually loading the .sfc/.smc file in Ghidra outside of REA and then copying results back by hand. This works but breaks REA’s unified Evidence workflow and agent integration.
  • Treating the ROM as a generic raw binary with no architecture guidance. This fails because the 65C816 instruction set and load address are not inferred automatically.
  • Waiting for full console-platform support. This is larger than needed; a minimal raw-binary path reusing the existing Ghidra provider is sufficient for v1.

Possible direction

Add a thin target kind (or extend open_binary) that accepts:

  • path to a single .sfc or .smc file
  • architecture = "65816" / "65c816"
  • optional load address (default suitable for common LoROM)

REA hands the bytes to the existing Ghidra provider as a raw binary with the matching 65C816 language.
Return the normal Evidence envelope already used for other native binaries.
Keep the change read-only and limited to single-file ROMs for the first version.

References

Originally created by @entzyeung on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4794 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal. - [x] I understand the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope) must be reviewed before integration; open questions are welcome here. - [x] This request does not include credentials, private samples, or sensitive target data. ### Area Setup, packaging, or upgrade ### Current limitation REA can analyse native binaries, firmware, and several other formats, but has no first-class support for Super Nintendo (SNES) ROM files. SNES ROMs (.sfc / .smc) are raw cartridge dumps whose main CPU is the 65C816. Users who want to inspect a game (for example Super Street Fighter II) currently have to manually load the file in Ghidra outside of REA’s workflows. ### Use cases A developer or researcher wants to understand how a specific mechanic works in a Super Nintendo game (for example Super Street Fighter II) without manually setting up a Ghidra project outside of REA. They point REA at a local .sfc/.smc file they own, specify the 65C816 architecture and an optional load address, and receive the same structured Evidence (pseudocode, cross-references, strings, etc.) that REA already returns for other native binaries. ### Desired outcome and success criteria Add a minimal way to open a single-file SNES ROM and receive the same Evidence format REA already returns for other binaries (pseudocode, xrefs, strings, etc.). Proposed interface (MCP / CLI): - Accept a local path to a .sfc or .smc file - Accept an architecture identifier (65816 / 65c816) - Accept an optional load address (default suitable for common LoROM mapping) - Hand the bytes to Ghidra as a raw binary with the 65C816 processor - Return normal REA Evidence Success criteria: - Opening a user-supplied SNES ROM produces usable pseudocode and cross-references for at least a few functions - The existing Evidence contracts and Ghidra provider are reused - No commercial ROM or decompiled commercial code is shipped ### Expected interaction with targets Read existing files or captured data ### Target and scope details (optional) Read-only analysis of a caller-supplied local .sfc/.smc file. No execution, injection, mutation, network access, or persistence of the target. Ghidra (or equivalent backend) is used only for static analysis of the provided bytes. Scope (v1): - Single-file ROM only - Explicit architecture + optional load address - Reuse existing Ghidra provider and Evidence contracts - Read-only analysis Non-goals: - No multi-file or interleaved ROM sets - No automatic LoROM/HiROM detection (manual load address is fine for v1) - No emulation or running the game - No shipping or embedding any commercial ROM or decompiled commercial code - No new disassembler (rely on Ghidra’s existing 65C816 support) ### Verification available so far Idea only; I need help defining checks ### Verification details (optional) Verification plan: - Use a user-supplied Super Street Fighter II (SNES) ROM that the contributor owns - Confirm that opening the ROM produces usable pseudocode and cross-references for at least a few known functions - Document the exact Ghidra language ID and load-address examples used - No commercial ROM or decompiled commercial code will be attached or shipped ### Alternatives considered - Manually loading the .sfc/.smc file in Ghidra outside of REA and then copying results back by hand. This works but breaks REA’s unified Evidence workflow and agent integration. - Treating the ROM as a generic raw binary with no architecture guidance. This fails because the 65C816 instruction set and load address are not inferred automatically. - Waiting for full console-platform support. This is larger than needed; a minimal raw-binary path reusing the existing Ghidra provider is sufficient for v1. ### Possible direction Add a thin target kind (or extend open_binary) that accepts: - path to a single .sfc or .smc file - architecture = "65816" / "65c816" - optional load address (default suitable for common LoROM) REA hands the bytes to the existing Ghidra provider as a raw binary with the matching 65C816 language. Return the normal Evidence envelope already used for other native binaries. Keep the change read-only and limited to single-file ROMs for the first version. ### References - Existing REA native analysis path and Evidence contracts (reused, not replaced). - Ghidra 65C816 / 65816 processor support (community and upstream discussion: https://github.com/NationalSecurityAgency/ghidra/issues/250). - Related prior art / community loaders: - https://github.com/joshleaves/ghidra-snes - https://github.com/achan1989/ghidra-snes-loader (archived) - Similar REA feature discussion for other architectures (e.g. PowerPC / GameCube DOL proposals in the issue tracker). - Verification will use a caller-supplied Super Street Fighter II (SNES) ROM owned by the contributor; no ROM or decompiled commercial code will be attached.
Author
Owner

@XinwangTao commented on GitHub (Oct 18, 2026):

Good scope discipline — keeping v1 to single-file ROMs with an explicit architecture and manual load address is the right call; LoROM/HiROM auto-detection can be a follow-up once the basic path is proven. Since a PR (#4911) already implements the 65816 admission, one thing worth verifying in the merged flow is that the raw binary loading preserves the SMC/SFC header offset handling (the 512-byte copier header on .smc files shifts the load address), otherwise the default LoROM mapping could silently be off by 0x200. Also good to confirm the Evidence output reuses the existing Ghidra provider contracts unchanged so nothing new needs to be maintained for SNES specifically.

<!-- gh-comment-id:6248279437 --> @XinwangTao commented on GitHub (Oct 18, 2026): Good scope discipline — keeping v1 to single-file ROMs with an explicit architecture and manual load address is the right call; LoROM/HiROM auto-detection can be a follow-up once the basic path is proven. Since a PR (#4911) already implements the 65816 admission, one thing worth verifying in the merged flow is that the raw binary loading preserves the SMC/SFC header offset handling (the 512-byte copier header on .smc files shifts the load address), otherwise the default LoROM mapping could silently be off by 0x200. Also good to confirm the Evidence output reuses the existing Ghidra provider contracts unchanged so nothing new needs to be maintained for SNES specifically.
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#2493
No description provided.