reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
107
our-skills/winui3-msix-reverse/SKILL.md
Normal file
107
our-skills/winui3-msix-reverse/SKILL.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
name: winui3-msix-reverse
|
||||
description: "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
|
||||
```bash
|
||||
ilspycmd -p --decompile-baml "C:\Path\To\Target.dll" -o "C:\Output\src"
|
||||
```
|
||||
- Produces C# files from .NET assembly
|
||||
- `--decompile-baml` attempts XAML but XBF v2+ may not decompile
|
||||
- Fix CS errors (duplicate variables, ambiguous references, missing `using`)
|
||||
|
||||
## Step 2: Build
|
||||
```bash
|
||||
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.json` uses `includedFrameworks`, rebuilt uses `framework` — self-contained fixes this
|
||||
|
||||
## Step 3: Overlay Original Assets
|
||||
Copy from original MSIX install dir to publish output:
|
||||
- `resources.pri` (XBF, strings, images)
|
||||
- `Assets/` folder
|
||||
- `Watchers/` 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 `Identity` Name (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
|
||||
```powershell
|
||||
# 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)
|
||||
```powershell
|
||||
# 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
|
||||
```powershell
|
||||
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 `MainWindowTitle` is 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 `Page` subclass in `VibeProxy.Views/`
|
||||
- Add routing in `NavigateToTag`: `"CustomPage" => typeof(CustomPage)`
|
||||
- Add `NavigationViewItem` programmatically in constructor:
|
||||
```csharp
|
||||
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 `.ps1` script files
|
||||
- **`CurrentUser\Root` cert store is NOT trusted for MSIX** — must use `LocalMachine` (admin) or loose register
|
||||
- **XBF v2.1 XAML not decompilable** — use original `resources.pri`, modify UI programmatically in C#
|
||||
- **`NavView.PaneBackground` doesn't exist in WinUI 3** — use `NavView.Background` instead
|
||||
- **`Window.RequestedTheme` not available** — set theme on child elements
|
||||
- **`Color` is ambiguous** — qualify as `Windows.UI.Color.FromArgb(...)`
|
||||
- **Self-contained publish is mandatory** — FDD fails in MSIX without framework discovery
|
||||
- **`makeappx pack` on 1200+ files takes ~70 seconds** — use async/background
|
||||
- **`Add-AppxPackage` on 300MB MSIX takes minutes** — use loose register instead
|
||||
Reference in New Issue
Block a user