--- 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\\x64\makepri.exe`) - Target app installed as MSIX (in `C:\Program Files\WindowsApps\`) ## Procedure ### 1. Locate the app ```powershell # Find running process Get-Process | Select-Object Id,Path # Or search WindowsApps Get-ChildItem "C:\Program Files\WindowsApps" -Filter "**" ``` ### 2. Identify the main DLL WinUI 3 apps have a thin native .exe loader (~400KB) and the real logic in `.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 ".dll" -p -o "" -r "" # With BAML→XAML (works for WPF, NOT for WinUI 3) ilspycmd ".dll" -p -o "" --decompile-baml -r "" ``` **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 `` with `HintPath` pointing to install dir — copy DLLs to local `libs/` folder - Change `15.0` to `preview` (SDK 10 doesn't support 15.0) - Set `False` 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 "\resources.pri" /of "` entries with `` - 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