Files
reverse-skills-max/our-skills/dotnet-winui3-reverse-engineering/SKILL.md

4.7 KiB
Raw Blame History

name, description
name description
dotnet-winui3-reverse-engineering 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

# 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

# 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

# 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