Files

93 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: dotnet-winui3-reverse-engineering
description: "Decompile a WinUI 3 / Windows App SDK MSIX-packaged .NET app to C# source + extract XBF resources from PRI"
---
# Reverse Engineering WinUI 3 / Windows App SDK .NET Applications
## When to use
When you need to decompile a UWP/WinUI 3/Windows App SDK MSIX-packaged .NET application to readable C# source code.
## Prerequisites
- `dotnet` SDK installed
- `ilspycmd` (install via `dotnet tool install --global ilspycmd`)
- `makepri.exe` from Windows SDK (usually at `C:\Program Files (x86)\Windows Kits\10\bin\<version>\x64\makepri.exe`)
- Target app installed as MSIX (in `C:\Program Files\WindowsApps\`)
## Procedure
### 1. Locate the app
```powershell
# Find running process
Get-Process <AppName> | Select-Object Id,Path
# Or search WindowsApps
Get-ChildItem "C:\Program Files\WindowsApps" -Filter "*<AppName>*"
```
### 2. Identify the main DLL
WinUI 3 apps have a thin native .exe loader (~400KB) and the real logic in `<AppName>.dll` (several MB). Check for `coreclr.dll`, `hostfxr.dll` → .NET 8 runtime.
### 3. Decompile C# with ILSpy
```bash
# Basic decompile (C# only, no XAML)
ilspycmd "<AppName>.dll" -p -o "<output_dir>" -r "<install_dir>"
# With BAML→XAML (works for WPF, NOT for WinUI 3)
ilspycmd "<AppName>.dll" -p -o "<output_dir>" --decompile-baml -r "<install_dir>"
```
**Important:** WinUI 3 compiles XAML to XBF (XAML Binary Format) v2.1, NOT BAML. `--decompile-baml` will NOT produce XAML files. XBF files are embedded in `resources.pri`.
### 4. Fix csproj for build
- ILSpy generates `<Reference>` with `HintPath` pointing to install dir — copy DLLs to local `libs/` folder
- Change `<LangVersion>15.0</LangVersion>` to `<LangVersion>preview</LangVersion>` (SDK 10 doesn't support 15.0)
- Set `<GenerateAssemblyInfo>False</GenerateAssemblyInfo>` to avoid conflicts
- Copy `Microsoft.WindowsAppRuntime.dll` (native, ~1.3MB) to output — it's NOT copied by default
### 5. Extract XBF from resources.pri
```bash
# Dump PRI to XML
makepri.exe dump /if "<install_dir>\resources.pri" /of "<output.xml" /dt detailed /o
```
Then extract XBF binaries (they're Base64-encoded `EmbeddedData` entries):
- Look for `<NamedResource name="*.xbf">` entries with `<Candidate type="EmbeddedData">`
- Base64 value starts with `WEJG` (= "XBF" in Base64)
- Decode Base64 → write to .xbf files preserving directory structure
### 6. XBF v2.1 format notes
- Header: magic(4) + metadataSize(uint32) + nodeSize(uint32) = 12 bytes
- Metadata section starts at byte 12, contains: version(2×uint32) + 6 table offsets(uint64) + hash(64 bytes)
- **Table offsets are RELATIVE to metadata start (byte 12), not absolute file offsets**
- String table: count(uint32) + entries [len(uint32) + UTF-16LE chars + 2-byte padding]
- Type/Property tables: 12 bytes per entry (3×uint32), NOT 8 bytes like v1.0
- Assembly/TypeNamespace tables may have 0 entries
- Node section: starts at byte 12+metadataSize, uses different encoding than v1.0
- **No working XBF v2.1→XAML decompiler exists** (LibXbf/XbfDecompiler only support v1.0/v2.0)
- Best path to XAML: runtime hook `Application.LoadComponent` in live app + serialize visual tree
### 7. Smoke-launch limitations
WinUI 3 apps CANNOT run standalone without MSIX registration:
- `Microsoft.UI.Xaml.Application.Start()` requires WinRT activation factory
- WinRT activation needs package identity (AppX registration)
- Error: `FileNotFoundException` in `WinRT.ActivationFactory` → `BaseActivationFactory`
- To launch: create temporary AppX manifest + `Add-AppxPackage`, or run inside original MSIX context
### 8. Known artifacts in decompiled code
- `//IL_XXXX: Unknown result type` comments in 60+ files (WinRT projection IL)
- `_003C_003Ec` compiler-generated closure classes (from lambda captures)
- `__KnownINotifyPropertyChangedArgs` / `__KnownINotifyPropertyChangingArgs` (CommunityToolkit.Mvvm internals)
- These compile as warnings (CS8632, CS0618) but don't break the build
- **GREEN build ≠ behavior-equivalent to original** — WinRT projection stubs may be semantically incorrect
## OmniRoute provider architecture (for forks)
- Provider definitions: `src/shared/constants/providers/` split by auth type:
- `noauth.ts` — free, no API key (opencode, felo, duckduckgo)
- `apikey/` — split into `frontier-labs.ts`, `gateways.ts`, `inference-hosts.ts`, `enterprise-cloud.ts`, `regional.ts`, `specialty-media.ts`
- `oauth.ts` — OAuth providers (cursor, zed, kiro)
- `web-cookie.ts` — browser cookie auth
- `local.ts` — Ollama, LM Studio, vLLM
- Provider format: `{ id, alias, name, icon, color, textIcon, website, authHint?, hasFree?, freeNote?, serviceKinds?, notice? }`
- Models: `src/shared/constants/models.ts` + `src/lib/providers/staticModels.ts`
- Aggregated in `providers.ts` → `AI_PROVIDERS` proxy