diff --git a/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md b/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md index a4fc6d18f0..33b9a9e798 100644 --- a/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md +++ b/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md @@ -175,7 +175,9 @@ additional evidence only when the provider accepts and matches them. REA has a built-in read-only snapshot parser for x64 PE targets with .NET 8 RTR 9.1 metadata. An optional headless Ghidra adapter adds database annotations and broader metadata recovery on Linux; it requires an explicitly configured -NativeAOT JAR. These are separate routes. See the +NativeAOT JAR. These are separate routes. The built-in parser also runs on +Windows Ghidra P0; read frozen literals from its report, because +`search_strings` does not include them. See the [NativeAOT guide](https://github.com/morluto/rea/blob/main/docs/ghidra-nativeaot.md) for setup, supported layouts, and host restrictions. Preserve binary identity and distinguish derived metadata from Ghidra database observations. Recovered diff --git a/docs/ghidra-nativeaot.md b/docs/ghidra-nativeaot.md index d9505a226f..394d7fdf5f 100644 --- a/docs/ghidra-nativeaot.md +++ b/docs/ghidra-nativeaot.md @@ -17,10 +17,14 @@ submodule and is a separate, more capable workflow. The parser currently handles x64 PE32+ and RTR 9.1, including bounded DEHYDRATED_DATA processing, MethodTable relationships, virtual slots, and frozen strings. Other RTR versions and PE architectures are reported as -unsupported or partial. The matching .NET 8.0.22 fixture is source-built and -the parser's Windows-host Ghidra workflow has not yet had a real Windows-host -run. This does not establish Windows Ghidra import or decompiler behavior. -Windows Ghidra P0 has no database mutation authority. A PE/CLI or ReadyToRun +unsupported or partial. The matching .NET 8.0.22 fixture is source-built. + +On a Windows host, Windows Ghidra P0 runs the parser without a JAR. Metadata, +MethodTable relationships, virtual slots and frozen strings come from the +parser report, and `analyze_function` decompiles slot targets. Tools that read +the Ghidra database do not see rehydrated bytes (see below), because only the +optional adapter writes them into the database and Windows Ghidra P0 has no +database mutation authority. A PE/CLI or ReadyToRun assembly should use `inspect_managed_artifact`; it is not NativeAOT. ## Build and configure @@ -57,7 +61,9 @@ returns `observations.metadata_recovery` inline from the captured source snapsho including the RTR header, MethodTable addresses, frozen strings, derived overlay identity, and examined/recovered counts. Its enclosing `unsupported` load-image status means independent PE load-image verification was not performed; it does -not mean the metadata parser failed or the executable failed to load. +not mean the metadata parser failed or the executable failed to load. Without +the optional adapter, each recovered type's `type` is `null`, because no Ghidra +DataType exists; select it by `address`. Pass a returned MethodTable address to `inspect_native_data_type`. A direct PE query also derives the snapshot metadata from the authenticated Ghidra session @@ -67,8 +73,12 @@ The database result remains `unavailable` when Ghidra has no DataType at that address; its `metadata_recovery.source` is `read-only-derived-overlay` and carries related type, interface, slot, and target observations. Generated address identities do not claim original managed names. The parser does not -merge frozen literals into Ghidra's database string inventory. Follow slot -targets with `analyze_function` and ordinary cross-references. +merge frozen literals into Ghidra's database string inventory: read them from +`metadata_recovery.frozen_strings`, not `search_strings`. Slot targets come +from the parser report; on Windows P0 without the adapter, a `read_bytes` of +a slot in the rehydrated region returns no bytes. The Linux adapter route +verifies a complete slot read and its target. Follow slot targets with `analyze_function` and ordinary +cross-references. The built-in CLI path uses a MethodTable address returned by the parser or another observation: @@ -129,3 +139,11 @@ compiler/linker symbols and raw directory bytes provide the oracle. Stripped fixtures exercise heuristic detection. Tests do not execute the resulting NativeAOT binaries. Fixture generation and adapter compilation are optional and never prerequisites of ordinary native analysis or setup. + +The real MCP lane runs only on a Linux x64 host with the adapter. The +Windows-host behavior above was checked manually over MCP on Windows 11 x64 +(non-elevated, Ghidra 12.1.4, JDK 21, no JAR) with the source-built win-x64 +symbols fixture. The format, RTR version and frozen strings matched the fixture +oracle; the derived MethodTable, its base type, its interface and a virtual +slot reaching the overridden method matched the linker map; and pseudocode was +readable. No CI lane repeats this check. diff --git a/docs/managed-code-analysis.md b/docs/managed-code-analysis.md index d60603ce39..1d1a579e69 100644 --- a/docs/managed-code-analysis.md +++ b/docs/managed-code-analysis.md @@ -233,8 +233,9 @@ these routes, their layout/host restrictions, derived-memory provenance, and verification coverage. REA's experimental Windows Ghidra boundary admits native x86 and x86-64 PE -applications and DLLs for static analysis. This does not establish Windows -NativeAOT metadata-recovery coverage. +applications and DLLs for static analysis. For x64 PE NativeAOT, the read-only +parser also runs there; the [NativeAOT guide](ghidra-nativeaot.md) lists what a +Windows host covers. For NativeAOT analysis, preserve the selected native artifact's path and digest and report recovered type data with its returned provenance. Linking those types diff --git a/docs/testing.md b/docs/testing.md index 7aa80d22a8..213c48e44c 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -646,6 +646,12 @@ records independent symbol/directory/SHA oracles; it never executes the target. Linux also builds stripped, ordinary-native and small malformed/ambiguous/layout negative inputs. The optional Windows fixture workflow builds a PE on a Windows runner; analyzing that PE on Linux does not verify a Windows Ghidra host. +On a local Windows host, the .NET 8 ILCompiler finds the linker only through +Visual Studio 2019 or 2022 (`vswhere -version [16,18)`). With only Visual +Studio Build Tools 2026 installed, open its x64 Developer Command Prompt. +In that same `cmd.exe` session, run `set IlcUseEnvironmentalTools=true` and +then `npm run build:fixtures:nativeaot`. Running `vcvars64.bat` as a child of +PowerShell does not preserve its environment in the parent PowerShell session. Build the clean pinned upstream adapter with `build:ghidra:nativeaot`, then set `REA_GHIDRA_NATIVEAOT_JAR`. Run `verify:ghidra:nativeaot -- symbols`, `-- stripped`, diff --git a/docs/windows-ghidra-p0.md b/docs/windows-ghidra-p0.md index 5def0dae49..78e11ee79c 100644 --- a/docs/windows-ghidra-p0.md +++ b/docs/windows-ghidra-p0.md @@ -29,8 +29,10 @@ admitted raw NMOS 6502 mapping on Windows. Windows P0 admission remains limited to native PE and raw NMOS 6502 images. For x64 PE NativeAOT RTR 9.1, the read-only snapshot parser can report metadata through `inspect_native_load_image` and `inspect_native_data_type` without a JAR or -database mutation. A real Windows-host NativeAOT Ghidra run is still required -to establish the complete host workflow. +database mutation: MethodTable relationships, virtual slots and frozen strings. +`analyze_function` decompiles slot targets. Database reads of the rehydrated +bytes (`read_bytes`, `search_strings`) return nothing on this host. See +[NativeAOT](ghidra-nativeaot.md). This boundary does not establish general Windows feature parity. Ghidra GUI state, annotations, other target architectures and formats, and Hopper-only