4.5 KiB
4.5 KiB
name, description
| name | description |
|---|---|
| winui3-msix-reverse | Reverse engineer a WinUI 3 MSIX app: ILSpy decompile, rebuild with dotnet publish self-contained, overlay original native assets, loose-register without admin, add custom pages |
Reverse Engineering WinUI 3 MSIX Apps
Prerequisites
- ILSpy CLI (
ilspycmd) installed via dotnet tool - Windows SDK (makeappx.exe, signtool.exe)
- .NET 8 SDK
- Target MSIX installed (locate via
Get-AppxPackage)
Step 1: Decompile
ilspycmd -p --decompile-baml "C:\Path\To\Target.dll" -o "C:\Output\src"
- Produces C# files from .NET assembly
--decompile-bamlattempts XAML but XBF v2+ may not decompile- Fix CS errors (duplicate variables, ambiguous references, missing
using)
Step 2: Build
dotnet publish Project.csproj -c Release -r win-x64 --self-contained true
- Must use
--self-contained true— original MSIX bundles .NET runtime, FDD will fail with "No frameworks were found" - Original
runtimeconfig.jsonusesincludedFrameworks, rebuilt usesframework— self-contained fixes this
Step 3: Overlay Original Assets
Copy from original MSIX install dir to publish output:
resources.pri(XBF, strings, images)Assets/folderWatchers/folder (backend executables)- Locale dirs (
xx-YY/pattern) Microsoft.UI.Xaml/folder- Native WinUI DLLs (CoreMessagingXP.dll, dcompi.dll, etc.)
- Never overwrite rebuilt VibeProxy.exe/dll
Step 4: Create AppxManifest.xml
- New
IdentityName (e.g.AtC.VibeProxyRev) - Same Publisher CN as original
- Bump Version (e.g.
3.7.2.8) - Same
EntryPoint="Windows.FullTrustApplication" rescap:Capability Name="runFullTrust"
Step 5: Register — Two Options
Option A: Loose Register (no admin, no signing) — PREFERRED
# Enable dev mode
Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" -Name "AllowDevelopmentWithoutDevLicense" -Value 1
# Register from staging dir
Add-AppxPackage -Register "C:\Staging\AppxManifest.xml"
- No cert needed, no admin for cert stores
- Package runs from staging dir, not WindowsApps
- Works when
AllowAllTrustedApps=1+AllowDevelopmentWithoutDevLicense=1
Option B: Signed MSIX (requires admin for cert stores)
# Create self-signed cert
$cert = New-SelfSignedCertificate -Subject "CN=..." -CertStoreLocation "Cert:\CurrentUser\My" ...
# MUST add to LocalMachine\Root and LocalMachine\TrustedPeople (requires admin)
# CurrentUser\Root is NOT trusted for MSIX — returns 0x800B0109
# Pack
makeappx pack /d Staging /p Output.msix /nv
# Sign
signtool sign /fd SHA256 /a /f cert.pfx /p password Output.msix
# Install
Add-AppxPackage -Path Output.msix
# CLEANUP: Remove cert from all stores + delete PFX after install
Step 6: Launch
Start-Process explorer.exe -ArgumentList 'shell:AppsFolder\PackageFamilyName!App'
- Wait ≥8 seconds before checking process
- Verify: PID path starts with Rev package, not original
- Check
MainWindowTitleis non-empty - RAM > 150MB indicates UI rendered
Step 7: Verify Changes
- UI Automation:
[System.Windows.Automation.AutomationElement]::FromHandle($proc.MainWindowHandle) - Find Text elements by name to confirm UI changes visible
- Screenshot + pixel sampling for visual proof
Step 8: Add Custom Functions
- Create new
Pagesubclass inVibeProxy.Views/ - Add routing in
NavigateToTag:"CustomPage" => typeof(CustomPage) - Add
NavigationViewItemprogrammatically in constructor:
var navItem = new NavigationViewItem { Content = "Custom", Tag = "CustomPage", Icon = new FontIcon { Glyph = "\uE9D9;" } };
NavView.MenuItems.Add(navItem);
- Verify via UI Automation: find ListItem with name matching Content
Critical Lessons
- PowerShell
$_gets stripped through bash inline — always use.ps1script files CurrentUser\Rootcert store is NOT trusted for MSIX — must useLocalMachine(admin) or loose register- XBF v2.1 XAML not decompilable — use original
resources.pri, modify UI programmatically in C# NavView.PaneBackgrounddoesn't exist in WinUI 3 — useNavView.BackgroundinsteadWindow.RequestedThemenot available — set theme on child elementsColoris ambiguous — qualify asWindows.UI.Color.FromArgb(...)- Self-contained publish is mandatory — FDD fails in MSIX without framework discovery
makeappx packon 1200+ files takes ~70 seconds — use async/backgroundAdd-AppxPackageon 300MB MSIX takes minutes — use loose register instead