Files

5.0 KiB

name, description
name description
reverse-winui3-pkg-app Reverse engineer a WinUI 3 (.NET 8) desktop app with a pkg-compiled Node.js backend: ILSpy decompilation, XBF extraction from resources.pri, pkg payload extraction, self-contained publish, MSIX packaging with self-signed cert, and side-by-side launch

Reverse Engineering WinUI 3 + pkg-compiled Node.js Applications

When to use

Reversing a Windows desktop app that is:

  • WinUI 3 / Windows App SDK (.NET 8) frontend
  • pkg-compiled Node.js backend (VibeProxyServices.exe pattern)
  • Installed as MSIX in C:\Program Files\WindowsApps\

Phase 1: Locate and identify

# Find running process
Get-Process | Where-Object { $_.ProcessName -match 'TargetApp' }
# Get install path
(Get-Process TargetApp).Path

Identify app type by inspecting install directory:

  • coreclr.dll, hostfxr.dll → .NET 8 app
  • VibeProxy.dll (main logic) + VibeProxy.exe (thin launcher) → ILSpy target
  • resources.pri → XBF/XAML resources embedded
  • Watchers\*.exe (large, 100MB+) → likely pkg-compiled Node.js backend

Phase 2: Decompile C# with ILSpy

# Install ILSpy CLI
dotnet tool install --global ilspycmd

# Decompile main DLL with reference path for WinRT projections
ilspycmd "C:\path\to\App.dll" -p -o "C:\output\src" -r "C:\path\to\install\dir"

Key fixes after decompilation:

  • LangVersion in csproj: change to preview (ILSpy may set unsupported version)
  • CS0136 duplicate variables: rename second occurrence
  • FindOrRegisterForKey("literal"): ILSpy inlines string constants — fix call site to use const
  • Color ambiguity: qualify as Windows.UI.Color.FromArgb(...) not Color.FromArgb(...)
  • NavigationView.PaneBackground doesn't exist in WinUI 3 — use NavView.Background instead
  • Window.RequestedTheme not available — set theme on child elements instead

Phase 3: Extract XBF from resources.pri

# Dump PRI with makepri
makepri.exe dump /if "resources.pri" /of "dump.xml" /dt detailed /o

# Extract XBF binaries from Base64 in dump XML (PowerShell script)
# XBF entries have type="EmbeddedData" with Base64Value

XBF v2.1 format (WinUI 3):

  • Header: 12 bytes (magic + metaSize + nodeSize)
  • Offsets are relative to byte 12 (meta_start)
  • String table: uint32 count, then length-prefixed UTF-16LE strings with 2-byte padding
  • Type/Property tables: 12 bytes per entry (not 8)
  • Node section starts at 12 + metaSize
  • Node encoding differs from XBF v1.0 — existing tools (LibXbf) don't work

Phase 4: Extract pkg backend

pkg self-extracts to %TEMP%\AppName\version\dist at runtime. Check there first — no need to parse the 298MB binary.

Get-ChildItem "$env:TEMP\AppName" -Recurse

If not extracted yet, identify pkg version:

  • Search binary for process.versions.pkg → e.g. '6.22.0'
  • Search for NODE_SEA_FUSE — if :0, it's pkg not SEA
  • Trailing data after PE sections is gzip-compressed pkg payload

Phase 5: Build and package

# Self-contained publish (critical — FDD won't work in MSIX)
dotnet publish App.csproj -c Release -r win-x64 --self-contained true

Create staging directory from publish output, then overlay original:

  • resources.pri (XBF, strings, images)
  • Assets/ folder
  • Watchers/ folder
  • Locale directories (xx-XX/)
  • Microsoft.UI.Xaml/ folder
  • Native WinUI DLLs (whitelist — never overwrite published exe/dll)

Phase 6: MSIX packaging with self-signed cert

# Create cert matching manifest Publisher
$cert = New-SelfSignedCertificate -Subject "CN=PublisherFromManifest" ...
# Add to Trusted Root and Trusted People
# Pack with makeappx
makeappx.exe pack /d staging /p App.msix /nv
# Sign with signtool
signtool.exe sign /fd SHA256 /a /f cert.pfx /p password App.msix
# Install
Add-AppxPackage -Path App.msix

Requirements:

  • AllowAllTrustedApps=1 and AllowDevelopmentWithoutDevLicense=1 in registry
  • Manifest Publisher must exactly match cert Subject
  • Bump version on each rebuild
  • Remove stale AppxSignature.p7x, AppxBlockMap.xml, AppxMetadata/ from staging

Phase 7: Launch and verify

# Launch via AppsFolder (not Start-Process directly)
Start-Process explorer.exe -ArgumentList 'shell:AppsFolder\PackageFamilyName!App'
# Wait 8-15 seconds for WinUI window
# Verify: PID path matches Rev package, MainWindowTitle set, RAM > 150MB

UI verification:

  • UI Automation: [System.Windows.Automation.AutomationElement]::FromHandle($hwnd)
  • Screenshot + pixel sampling for color/design changes
  • Don't trust base.Title alone — custom title bar uses AppTitleTextBlock.Text

Known limitations

  • XAML markup (XBF v2.1) cannot be decompiled — original resources.pri is used
  • ILSpy leaves Unknown result type comments in 61+ files (WinRT projection IL)
  • copy_all.ps1 pattern overwrites rebuilt exe/dll — always rebuild AFTER copying
  • Window.RequestedTheme not available in WinUI 3 — set theme on child elements
  • Process may take 10-15 seconds to create window handle after launch