reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
70
our-skills/attio-reverse-engineering/SKILL.md
Normal file
70
our-skills/attio-reverse-engineering/SKILL.md
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
name: attio-reverse-engineering
|
||||
description: "Reverse-engineer and integrate Attio CRM (AI models, API, MCP) into OMP — covers internal endpoints, auth, gateway, and provider wiring"
|
||||
---
|
||||
|
||||
# Attio Reverse Engineering & OMP Integration
|
||||
|
||||
## Architecture
|
||||
```
|
||||
Attio Web App (app.attio.com)
|
||||
├── Public API: api.attio.com/v2 (Bearer token from Settings → Developers → API Keys)
|
||||
├── Internal AI: app.attio.com/api/internal/chat/completions (session cookie auth, Cloudflare-protected)
|
||||
├── MCP: mcp.attio.com/mcp (OAuth: openid offline_access mcp)
|
||||
└── SPA: React, all /api/* GET routes return HTML (not API JSON)
|
||||
|
||||
OMP Integration:
|
||||
├── attio-gateway.py :8312 — FastAPI, round-robin API key pool, proxies api.attio.com/v2
|
||||
├── attio-api-provider.py :8313 — OpenAI-compatible, /v1/models + /v1/chat/completions + tools
|
||||
├── attio_mcp.py — MCP stdio server, 3 tools (list_workspaces, search_people, get_record)
|
||||
└── mcp.json — attio (remote http OAuth) + attio-farm (local stdio)
|
||||
```
|
||||
|
||||
## Auth Methods
|
||||
1. **API Key** (for api.attio.com/v2): `Authorization: Bearer att_...` — works from any client
|
||||
2. **Session Cookies** (for app.attio.com/internal): requires real browser — Cloudflare blocks urllib/requests
|
||||
3. **OAuth JWT** (for mcp.attio.com/mcp): obtained via OAuth consent flow, stored in mcp.json
|
||||
|
||||
## Internal AI Endpoint
|
||||
- URL: `POST https://app.attio.com/api/internal/chat/completions`
|
||||
- Auth: session cookies (`attio-session`, `attio-app-session`, `attio-session-id`)
|
||||
- Blocked by Cloudflare Error 1010 for non-browser requests
|
||||
- Models available: Claude Opus 5, Claude Sonnet 5 (names in Attio: "Opus 5", "Claude Sonnet 5")
|
||||
- Other probe results: `/{workspace}/api/chat` returns 405 (exists but different method)
|
||||
|
||||
## OMP Provider Wiring (3 files)
|
||||
1. `providers.yml`: under `providers:`, add entry with `apiKey: ""`, `baseUrl`, `models`, `provider: openai`
|
||||
2. `models.yml`: detailed config per model (api, contextWindow, maxTokens, compat flags)
|
||||
3. `config.yml`: add `provider/*` to `enabledModels` AND provider to `modelProviderOrder`
|
||||
- **Without enabledModels, /model won't show the provider at all**
|
||||
- OMP restart required after changes
|
||||
|
||||
## Pool Format (attio_accounts.json)
|
||||
```json
|
||||
[{
|
||||
"email": "...",
|
||||
"api_key": "att_...",
|
||||
"api_workspace_id": "uuid",
|
||||
"api_workspace_slug": "slug",
|
||||
"cookies": [
|
||||
{"name": "attio-session", "value": "jwt...", "domain": ".attio.com"},
|
||||
{"name": "attio-app-session", "value": "jwt...", "domain": ".attio.com"},
|
||||
{"name": "attio-session-id", "value": "uuid", "domain": ".attio.com"}
|
||||
],
|
||||
"status": "active_pro_trial"
|
||||
}]
|
||||
```
|
||||
|
||||
## Browser Automation Issues
|
||||
- Camoufox: launch hangs (GeoIP lookup or binary issue on Windows)
|
||||
- Playwright: chromium binary missing, install needed; node.exe must be copied to driver/
|
||||
- Patchright: driver node.exe missing
|
||||
- curl_cffi: fails to compile on Windows CPython 3.11
|
||||
- Browser relay (OMP): times out, extension may not be connected
|
||||
- Chrome CDP: port 9224 listening but OMP browser tool can't connect (503)
|
||||
|
||||
## Working Tools
|
||||
- `attio_list_workspaces` — reads pool from JSON, no API call needed
|
||||
- `attio_search_people` — POST /v2/objects/people/records/query with filter
|
||||
- `attio_create_person` — POST /v2/objects/people/records with values
|
||||
- `attio_get_record` — GET /v2/objects/{type}/records/{id}
|
||||
60
our-skills/devin-architecture-reverse/SKILL.md
Normal file
60
our-skills/devin-architecture-reverse/SKILL.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
name: devin-architecture-reverse
|
||||
description: "Devin AI agent architecture reverse engineering — binary structure, permission modes, hooks, slash commands, OMP mapping"
|
||||
---
|
||||
|
||||
# Devin Architecture — Reverse Engineering Notes
|
||||
|
||||
## Binary Location
|
||||
`C:/Users/User/AppData/Local/Programs/Devin/` — Electron/VSCode fork with Windsurf/Codeium extension.
|
||||
|
||||
## Key Components
|
||||
```
|
||||
Devin.exe (Electron, 216MB)
|
||||
└── resources/app/extensions/windsurf/ ← Codeium agent extension
|
||||
└── devin/
|
||||
├── bin/devin.exe (151MB) ← Go/Rust agent binary
|
||||
└── share/devin/docs/ ← Documentation
|
||||
├── essential-commands.mdx ← 5 permission modes, 30+ slash commands
|
||||
├── sandbox.mdx ← OS-level isolation (bubblewrap)
|
||||
├── adaptive.mdx ← Auto model routing
|
||||
├── handoff.mdx ← Transfer to cloud Devin
|
||||
└── acp/ ← Agent Communication Protocol
|
||||
```
|
||||
|
||||
## Permission Modes
|
||||
1. **Normal** — auto-approves read-only tools, asks for write/execute
|
||||
2. **Accept Edits** — auto-approves file edits, prompts for shell
|
||||
3. **Smart** — fast model decides safety of each action
|
||||
4. **Bypass (YOLO)** — auto-approves everything
|
||||
5. **Autonomous** — requires `--sandbox`, OS-level isolation
|
||||
|
||||
## Slash Commands
|
||||
/plan, /ask, /mode, /model, /loop, /compact, /handoff, /resume, /workspace, /hooks, /clear, /exit, /ls, /rm-session
|
||||
|
||||
## Hook System (8 event types)
|
||||
SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PermissionRequest, PostCompaction, SessionEnd, Stop
|
||||
|
||||
## OMP Equivalent
|
||||
| Devin | OMP |
|
||||
|---|---|
|
||||
| Bypass mode | approvalMode: yolo |
|
||||
| /plan | plan: deepseek-reasoner:xhigh |
|
||||
| /ask | advisor: deepseek-v4-pro:max |
|
||||
| /loop | verification-loop skill |
|
||||
| Adaptive routing | modelFallback + usageAwareFallback |
|
||||
| Sandbox | task.isolation: projfs |
|
||||
| Sessions | checkpoint + remember skill |
|
||||
| /compact | compaction.autoContinue |
|
||||
| MCP | 20+ MCP servers |
|
||||
| 30 workers | maxConcurrency: 30 |
|
||||
| Hooks | extensions (6 .ts files) |
|
||||
|
||||
## Devin Suite — OMP Implementation
|
||||
Devin Suite lives at `C:/Users/User/.omp/agent/tools/devin_suite/` and provides:
|
||||
- FastAPI server with planning, search, agents, sandbox, WebSocket
|
||||
- 5 permission modes with per-agent state
|
||||
- 8-event hook system with registry
|
||||
- Slash command parser and handlers
|
||||
- Dashboard with 4 tabs (Agents, Plans, Search, Sandbox)
|
||||
- OMP extension integration
|
||||
92
our-skills/dotnet-winui3-reverse-engineering/SKILL.md
Normal file
92
our-skills/dotnet-winui3-reverse-engineering/SKILL.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
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\<version>\x64\makepri.exe`)
|
||||
- Target app installed as MSIX (in `C:\Program Files\WindowsApps\`)
|
||||
|
||||
## Procedure
|
||||
|
||||
### 1. Locate the app
|
||||
```powershell
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
79
our-skills/re-roast-2026/SKILL.md
Normal file
79
our-skills/re-roast-2026/SKILL.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
name: re-roast-2026
|
||||
description: "Use when roasting/verifying a reverse-engineering guide, post, or list of RE tools; fact-checking stars/tool counts; link liveness sweep; cutting hyperbole; splitting content into Telegram messages (4096 limit); or when building/evaluating any 2026 RE stack content: IDA/Ghidra/Binary Ninja, Qiling, OGhidra, AI-RE pipeline, IDA licensing. Triggers: прожарка, реверс, реверсинг, RE, reverse engineering, бинарь, дизассемблер, декомпилятор, проверь ссылки, гайд по реверсу, проверить факты в посте."
|
||||
---
|
||||
|
||||
# Что делает
|
||||
|
||||
Прожарка RE-контента: факт-чек против первоисточников, свип живости ссылок, срезка гипербол, разбивка под Telegram. Второй контур — канонный верифицированный стек реверс-инжиниринга 2026 (проверен 26.09.2026, 102/102 ссылки живы).
|
||||
|
||||
## When to use
|
||||
|
||||
- Прожарка/разбор чужого гайда по реверсу перед репостом в канал
|
||||
- Факт-чек цифр (звёзды GitHub, число тулов, доменов, статей) и названий репо/книг
|
||||
- Свип живости ссылок в MD (102+ ссылок)
|
||||
- Составление нового RE-материала на проверенном стеке
|
||||
- Оценка инструмента: лицензия и цена (бесплатно/ограниченно/платно)
|
||||
|
||||
## When NOT to use
|
||||
|
||||
- Сам разбор бинарника, malware, crackme (это другие скиллы: reverse-engineering, malware-analysis)
|
||||
- Общая редактура текста без RE-темы
|
||||
- Если не нужно ничего проверять — только писать свежий контент без фактов
|
||||
|
||||
## Workflow (прожарка RE-гайда)
|
||||
|
||||
1. **Триаж ссылок**: извлечь все URL из текста, прогнать `scripts/linkcheck.py`. 403/405 = бот-волл (сайт жив), не мёртвый. 404/сетевая ошибка = кандидат на удаление/замену.
|
||||
2. **Цифры**: каждое число — против первоисточника (GitHub API/search, README репо). Звёзды, число тулов в описании, число статей/доменов. Несколько источников, если неоднозначно.
|
||||
3. **Названия**: репо и книги сверять дословно; репо могло переехать (PMAT-course → PMAT-labs).
|
||||
4. **Лицензии и цены**: пометить каждое ограничение. IDA Pro / Binary Ninja — платные, фраза «всё бесплатное» при них ложь; de4py = CC BY-NC; disrobe = платно для компаний.
|
||||
5. **Гиперболы**: срезать «инструменты бесполезны», «свободно читаешь», «лучший способ», «от запуска до ответа», «~20 новых 0-day» (тавтология).
|
||||
6. **Техническая точность**: Qiling исполняет в эмуляции → «без запуска на живой системе»; OGhidra поддерживает и облачные API (приватность только в локальном режиме); промпт-инъекция в бинарнике = «встраивает команды в строки», не «учится разговаривать».
|
||||
7. **Атрибуция**: при репосте сохранять автора («[REDACTED] ([REDACTED])»), убирать промо-футеры автора (боты/платные ссылки).
|
||||
8. **Разбивка**: сообщения ≤ 4096 символов, каждое самодостаточно, маркеры `===MSG N/4===`.
|
||||
9. **Лицензия IDA**: при упоминании IDA Pro добавить раздел про легальные пути (IDA Free, Ghidra, студенческая Hex-Rays) — иначе аудитория идёт за кейгенами и тянет малварь.
|
||||
|
||||
## Success criteria
|
||||
|
||||
- Все ссылки проверены: 0 DEAD, BOTWALL задокументирован
|
||||
- Каждая цифра текста сходится с первоисточником (с датой проверки)
|
||||
- Каждое языковое/лицензионное утверждение без гипербол
|
||||
- Все блоки ≤ 4096 символов
|
||||
- Под-пост готов, если пользователь просил («под пост» = сообщение-компаньон, в канал не отправлять)
|
||||
|
||||
## Failure modes
|
||||
|
||||
- **Сервер режет HEAD** → GET fallback в linkcheck; 403 Cloudflare/Anubis = живой, не ошибка
|
||||
- **Цифры устарели между проверками** → писать дату проверки рядом с цифрой
|
||||
- **Репозиторий переехал** → искать новый owner/название (labs/archive суффиксы), не удалять секцию вслепую
|
||||
- **Ссылка отдаёт 200 на сайте, но бот-волл браузеру** → не удалять, пометить «жив, отдаёт 403 ботам»
|
||||
|
||||
## Gotchas (проверено 26.09.2026)
|
||||
|
||||
| Факт | Значение |
|
||||
|---|---|
|
||||
| binary-ninja-headless-mcp | 181 тул (не 180) |
|
||||
| firefox-reverse | 857 звёзд (не 855) |
|
||||
| shannon | 48к звёзд (не 47к) |
|
||||
| Anthropic-Cybersecurity-Skills | 34 домена (не 29) |
|
||||
| open-reverselab | 180+ статей (не 194) |
|
||||
| PMAT | репо PMAT-labs (не PMAT-course) |
|
||||
| Книга Нарвахи | «Введение в реверсинг с нуля, используя IDA PRO» (перевод на gitbook yutewiyof) |
|
||||
| Qiling | исполняет код в эмуляции — «без запуска на живой системе», не «без запуска» |
|
||||
| OGhidra | LLM через Ollama или облачные API; приватность только в локальном режиме |
|
||||
| de4py | CC BY-NC (некоммерческая) |
|
||||
| disrobe | платно для компаний |
|
||||
| Промпт-инъекция в строках бинарника | arxiv 2605.30667 — встраивает команды в строки |
|
||||
| Гиперболы интро | «свободно читаешь» → «читаешь»; godbolt «лучший способ» — снять |
|
||||
| IDA лицензия | .hexlic офлайн, JSON+подпись, ключ в бинаре; keygen с приватным ключом публично не подтверждён; пропатченная сборка = вектор малвари |
|
||||
|
||||
## Available scripts
|
||||
|
||||
- `scripts/linkcheck.py` — свип живости ссылок из MD. Запуск из корня скилла: `python scripts/linkcheck.py <file.md> [--workers N] [--timeout S]`. Stdlib only, exit 0 всегда (отчёт в stdout, формат `CHECK <status> <url>`).
|
||||
|
||||
## References
|
||||
|
||||
- Канон v4.1: `C:/Users/User/tmp/rev-guide-v4.md` (4 сообщения, 3854/3679/3875/1934 симв.)
|
||||
- Под-пост: `C:/Users/User/tmp/rev-guide-v4-subpost.md` (1363 симв.)
|
||||
- Автор оригинала: [REDACTED] (https://[REDACTED])
|
||||
- Воркфлоу владельца: посты в TG ботом НЕ отправлять, инфу выдавать в чат; «под пост» = сообщение-компаньон
|
||||
94
our-skills/re-roast-2026/scripts/linkcheck.py
Normal file
94
our-skills/re-roast-2026/scripts/linkcheck.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Link liveness sweep for Markdown files (stdlib only).
|
||||
|
||||
Usage:
|
||||
python linkcheck.py <file.md> [<file2.md> ...] [--workers N] [--timeout S]
|
||||
|
||||
Checks every http(s) URL found in the markdown files.
|
||||
- 403/405 are reported as BOTWALL (bot wall — site is alive, not dead)
|
||||
- Other HTTP errors are reported with their code
|
||||
- Network errors/timeouts are reported as DEAD
|
||||
|
||||
Output line format: CHECK <status> <url>
|
||||
Exit code is always 0; the report is the output. Diagnostics go to stderr.
|
||||
"""
|
||||
import argparse
|
||||
import concurrent.futures
|
||||
import re
|
||||
import ssl
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
URL_RE = re.compile(r"https?://[^\s()<>{}|\"'`]+")
|
||||
UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||||
"(KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36")
|
||||
|
||||
|
||||
def probe(url, method, timeout, ctx):
|
||||
req = urllib.request.Request(url, headers={"User-Agent": UA}, method=method)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as resp:
|
||||
return resp.status
|
||||
except urllib.error.HTTPError as e:
|
||||
return e.code
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def check(url, timeout):
|
||||
url = url.rstrip(".,;:!?)]}")
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
for method in ("HEAD", "GET"):
|
||||
status = probe(url, method, timeout, ctx)
|
||||
if status is not None and status != 999:
|
||||
if status in (403, 405):
|
||||
return f"CHECK BOTWALL {status} {url}"
|
||||
if status < 400:
|
||||
return f"CHECK {status} {url}"
|
||||
# 4xx/5xx from HEAD could be server refusing HEAD; try GET first
|
||||
if method == "GET":
|
||||
return f"CHECK {status} {url}"
|
||||
continue
|
||||
if method == "GET":
|
||||
break
|
||||
return f"CHECK DEAD {url}"
|
||||
|
||||
|
||||
def collect_urls(files):
|
||||
urls, seen = [], set()
|
||||
for path in files:
|
||||
try:
|
||||
text = open(path, encoding="utf-8").read()
|
||||
except OSError as e:
|
||||
print(f"ERR cannot read {path}: {e}", file=sys.stderr)
|
||||
continue
|
||||
for u in URL_RE.findall(text):
|
||||
if u not in seen:
|
||||
seen.add(u)
|
||||
urls.append(u)
|
||||
return urls
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Link liveness sweep for Markdown files.")
|
||||
ap.add_argument("files", nargs="+", metavar="file.md")
|
||||
ap.add_argument("--workers", type=int, default=24, help="parallel workers (default: 24)")
|
||||
ap.add_argument("--timeout", type=float, default=15.0, help="per-request timeout in s (default: 15)")
|
||||
args = ap.parse_args()
|
||||
|
||||
urls = collect_urls(args.files)
|
||||
if not urls:
|
||||
print("CHECK NONE (no URLs found)")
|
||||
return 0
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=args.workers) as pool:
|
||||
for result in pool.map(lambda u: check(u, args.timeout), urls):
|
||||
print(result)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
130
our-skills/rea-full-course/SKILL.md
Normal file
130
our-skills/rea-full-course/SKILL.md
Normal file
@@ -0,0 +1,130 @@
|
||||
---
|
||||
name: rea-full-course
|
||||
description: REA (Reverse Engineer Anything, morluto/rea) — полный практический курс. Установка, движки (Ghidra/IDA/Hopper/JADX), guided-воркфлоу, пак промтов, ограничения. Использовать для реверса Electron/JS, .NET, APK, бинарников, EVM-байткода через AI-агента.
|
||||
---
|
||||
|
||||
# REA — Reverse Engineer Anything (полный курс)
|
||||
|
||||
REA = MCP-сервер + CLI (npm `rea-agents`), который даёт AI-агенту (Claude Code, Codex, Cursor, Gemini CLI, Hermes) навык реверс-инжиниринга с доказательствами: функция, файл, вызов + что осталось неизвестным. MIT, работает локально, ничего не загружает наружу. Первый релиз 12.07.2026, 100K+ звёзд за 3 месяца.
|
||||
|
||||
Полный текст курса-источника: `research-what-we-did/rea-full-course-source.md`.
|
||||
|
||||
## Установка
|
||||
|
||||
```bash
|
||||
node -v # нужен Node 22.19+ / 24.11+ / 26+ (23 и 25 НЕ поддерживаются)
|
||||
npx rea-agents@latest setup # интерактивно: выбор агента → план изменений → approval → бэкап конфигов
|
||||
npx -y rea-agents@latest doctor --client claude_code --json # только проверка
|
||||
npm install --global rea-agents && rea --help # глобальная команда
|
||||
rea update # фиксы выходят почти ежедневно
|
||||
```
|
||||
|
||||
Промт для авто-установки агентом:
|
||||
```
|
||||
Install REA and connect it to this coding agent using npx rea-agents@latest setup. Show me the setup plan for approval, then verify the installation.
|
||||
```
|
||||
|
||||
После установки — ПОЛНЫЙ рестарт агента (для desktop-приложений недостаточно закрыть окно).
|
||||
|
||||
## Что читает и какие движки нужны
|
||||
|
||||
| Цель | Движок |
|
||||
|---|---|
|
||||
| Electron/JS desktop (Notion, Slack, Discord, Obsidian) | ничего, из коробки |
|
||||
| Сайты (структура, скрипты, сеть) | любой Chrome-family браузер |
|
||||
| HAR-файлы | ничего |
|
||||
| .exe / Mach-O / DOS-игры (псевдокод, asm, строки) | Ghidra 12.1.x + JDK 21 (GHIDRA_INSTALL_DIR, JAVA_HOME) или Hopper или IDA |
|
||||
| .NET (включая Unity-игры — игровая логика часто .NET) | ничего |
|
||||
| Android APK | JDK 17+ и jadx-headless-mcp 0.7.1 (REA_JADX_MCP_JAR) |
|
||||
| EVM-байткод смарт-контрактов | только Linux x64 |
|
||||
| Прошивки, WASM, Go-бинарники | встроенные парсеры |
|
||||
|
||||
Electron-приложения лежат: Win `C:\Users\<ty>\AppData\Local\Programs\<App>\resources\app.asar`, Mac `<App>.app/Contents/Resources/app.asar`, Linux `/opt/<App>/resources/app.asar`.
|
||||
|
||||
Анализ без запуска приложения:
|
||||
```bash
|
||||
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
|
||||
```
|
||||
|
||||
## Guided-воркфлоу (зашиты в MCP, почти никто не знает)
|
||||
|
||||
- `investigate_feature` — фича от обнаружения до конкретных функций
|
||||
- `compare_application_versions` — что реально изменилось в апдейте
|
||||
- `verify_reconstruction` — сверка своей пересборки с сохранёнными доказательствами
|
||||
- `trace_crash` — креш → пути кода
|
||||
- `audit_residual_unknowns` — что ещё не доказано
|
||||
- `prepare_bounded_process_capture` — план безопасного runtime-эксперимента
|
||||
|
||||
Цикл профи: **investigate → spec → build → verify**
|
||||
```
|
||||
Use REA to investigate how [feature] works in [app]. Write SPEC.md: behavior, inputs, outputs, edge cases, no copied code. Then build it from SPEC.md in ./my-version, write tests from the observed behavior, and run them until they pass.
|
||||
```
|
||||
|
||||
## Пак промтов (копипаст в агент с установленной REA)
|
||||
|
||||
Первый тест (2 минуты, официальное training-приложение):
|
||||
```
|
||||
Download https://rea.tools/examples/notes-example.zip into a new example folder and unpack it. Use REA to find what happens when I click Export notes.
|
||||
Show where notes.csv is written, which fields it contains, and the relevant files and lines.
|
||||
```
|
||||
|
||||
Аудит APK:
|
||||
```
|
||||
Use REA on this APK. List every permission, every analytics or tracking SDK, and every domain the app talks to. Show the class and method for each finding.
|
||||
```
|
||||
|
||||
Проверка токена (байткод → state-функции):
|
||||
```
|
||||
Use REA on this contract bytecode. List every function that can change state. Flag anything that looks like mint, blacklist, pause, fee change or owner-only transfer. Mark what is confirmed and what is inferred.
|
||||
```
|
||||
(`rea inspect-evm-interface ./runtime.hex hex --json`; имена функций — догадки из байткода, красный флаг = «проверь глубже»)
|
||||
|
||||
Дифф версий:
|
||||
```
|
||||
Use REA's compare_application_versions workflow on [old version] and [new version] of [app]. Tell me what actually changed, with evidence.
|
||||
```
|
||||
|
||||
Реал-тайм фичи:
|
||||
```
|
||||
Figure out how Discord shows who's typing in real time, show me the proof, and build something similar for my project.
|
||||
```
|
||||
|
||||
Реконструкция игры:
|
||||
```
|
||||
Reconstruct a game from its executable and test it against the original.
|
||||
```
|
||||
|
||||
## Ограничения (честно)
|
||||
|
||||
- Сервер не трогает — читается только то, что на твоей машине. Банк не взломает.
|
||||
- Декомпилированный код — реконструкция, не оригинальный исходник → шаг verify обязателен.
|
||||
- Стрипанные C++-бинарники намного жёстче, чем Unity .NET-игры.
|
||||
- Агент может отказаться на прошивках/консолях (правила безопасности модели).
|
||||
- IDA/Hopper/JEB — свои лицензии, крякнутые копии запрещены.
|
||||
|
||||
## Юридическая рамка (clean room)
|
||||
|
||||
Учись на оригинале → пиши СПЕК (поведение, не код) → собирай своё с нуля. Так работали Compaq (BIOS IBM, ~$1M), Sega v. Accolade (1992, fair use), Sony v. Connectix (2000, 3-0). За копирование чужого кода/кряк платных фич/публикацию декомпилята — прилетает иск (Sony v. geohot 2011).
|
||||
|
||||
## Эталонные кейсы
|
||||
|
||||
- Aegis authenticator: 3077 классов → найден генератор 6-значных кодов → пересборка прошла 133/133 теста
|
||||
- DX-Ball (1996): sound-pan восстановлен на C, 3205 тест-кейсов оригинала, 63/63 байта компиляции
|
||||
- Touhou: 697 функций, 696 точных совпадений, играбельно за ~12 дней
|
||||
- Super Mario Sunshine PC-порт: ~365 агенто-часов, 17.3B токенов
|
||||
- ArtCraft: 7 приложений Adobe как clean-room Rust-альтернативы (альфа)
|
||||
|
||||
## Уроки из практики (пересборка Touhou)
|
||||
|
||||
- Чёткая цель + чёткие критерии приёмки для агента.
|
||||
- Заметки и проверки — в git, чтобы следующая сессия продолжила.
|
||||
- Любое объяснение агента = гипотеза, проверять.
|
||||
- Тестируй свои тесты: сломанное сравнение однажды пропустило неправильную функцию.
|
||||
|
||||
## Локальная практика (наш Windows-стенд, 14.10.2026)
|
||||
|
||||
- rea 6.4.0: `tools/node-26.7.0-win32-x64/rea.cmd`; MCP `rea` в Hermes config = 170 tools.
|
||||
- IDA attached-режим: env `REA_IDA_MCP_CONFIG` → ida-mcp.json (ida-pro-mcp 1.4.0 legacy, IDA GUI с плагином на :13337). Native-анализ бинарей — ТОЛЬКО через attached IDA.
|
||||
- Windows-лимиты: binary-layout/pwntools = Linux-only; Go/Rust/WASM/EVM/SQLite-парсеры встроенные.
|
||||
- Прогнано: `analyze-javascript-application` на TeleSender (90MB Electron) → Evidence-бандл 41878 узлов, JSON.
|
||||
- Монетизация навыка: bug bounty (пайплайны 8 MCP + 300 инструментов + Ghidra/radare2/Frida окупаются), перенос легаси-софта, связывание тулов, восстановление утраченных исходников для компаний.
|
||||
130
our-skills/reverse-winui3-app/SKILL.md
Normal file
130
our-skills/reverse-winui3-app/SKILL.md
Normal file
@@ -0,0 +1,130 @@
|
||||
---
|
||||
name: reverse-winui3-app
|
||||
description: "Use when reverse engineering a WinUI 3 / .NET 8 MSIX-packaged Windows application — covers ILSpy decompilation, PRI/XBF extraction, and pkg-compiled Node.js backend identification"
|
||||
---
|
||||
|
||||
# Reverse Engineering WinUI 3 + pkg-compiled Node.js Applications
|
||||
|
||||
## When to use
|
||||
- Target is a Windows MSIX-packaged app (WinUI 3 / Windows App SDK)
|
||||
- App has a separate backend executable compiled with `pkg`
|
||||
- Need to extract C# source, XAML (XBF), and JS backend code
|
||||
|
||||
## Phase 1: Locate and identify the target
|
||||
|
||||
```powershell
|
||||
# Find running process
|
||||
Get-Process <name> | Select Id,Path
|
||||
# Or search MSIX install
|
||||
Get-ChildItem "C:\Program Files\WindowsApps" -Directory -Filter "*<name>*"
|
||||
```
|
||||
|
||||
Identify app type by inspecting install directory:
|
||||
- `coreclr.dll`, `hostfxr.dll`, `*.dll` (managed) → .NET / WinUI 3
|
||||
- `VibeProxy.exe` (small, ~400KB) = native launcher; `VibeProxy.dll` (large) = main logic
|
||||
- `Watchers\*.exe` (large, 100MB+) = likely pkg-compiled Node.js backend
|
||||
|
||||
## Phase 2: Decompile .NET frontend (ILSpy)
|
||||
|
||||
```bash
|
||||
# Install ILSpy CLI
|
||||
dotnet tool install --global ilspycmd
|
||||
|
||||
# Decompile with BAML support and reference path
|
||||
ilspycmd "target.dll" -p -o "output_dir" --decompile-baml -r "install_dir"
|
||||
|
||||
# Fix csproj: LangVersion=preview, add HintPath for all references
|
||||
# Copy dependency DLLs to libs/ folder (include large ones >15MB separately)
|
||||
# Fix CS0136 (duplicate variable names) by renaming
|
||||
# Build: dotnet build -c Release
|
||||
```
|
||||
|
||||
Key limitations:
|
||||
- WinUI 3 XAML compiles to XBF (not BAML) — `--decompile-baml` won't extract it
|
||||
- `Unknown result type` comments in 60+ files = WinRT projection IL artifacts
|
||||
- Smoke-launch fails: WinRT activation requires MSIX package identity
|
||||
|
||||
## Phase 3: Extract XBF from resources.pri
|
||||
|
||||
```bash
|
||||
# Find makepri.exe in Windows SDK
|
||||
# Dump PRI to XML (detailed format for Base64 data)
|
||||
makepri.exe dump /if "install_dir\resources.pri" /of "dump.xml" /dt detailed /o
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Extract XBF binaries from PRI dump XML
|
||||
[xml]$xml = Get-Content "dump.xml" -Raw
|
||||
$xbfNodes = $xml.SelectNodes("//NamedResource[contains(@name,'.xbf')]")
|
||||
foreach ($node in $xbfNodes) {
|
||||
$name = $node.GetAttribute("name")
|
||||
$uri = $node.GetAttribute("uri")
|
||||
$pathPart = $uri -replace "ms-resource://[^/]+/Files/", ""
|
||||
$candidate = $node.SelectSingleNode("Candidate")
|
||||
if ($candidate.GetAttribute("type") -eq "EmbeddedData") {
|
||||
$b64 = $candidate.SelectSingleNode("Base64Value")
|
||||
$bytes = [System.Convert]::FromBase64String($b64.InnerText)
|
||||
[System.IO.File]::WriteAllBytes($outPath, $bytes)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
XBF v2.1 format notes:
|
||||
- Header: magic(4) + metaSize(uint32) + nodeSize(uint32) = 12 bytes
|
||||
- Metadata at byte 12: version(2x uint32) + 6 table offsets (uint64, relative to byte 12) + hash (64 bytes)
|
||||
- Table entries are 12 bytes each (not 8 as in v1.0)
|
||||
- Node encoding differs from v1.0 — no existing tool supports v2.1
|
||||
- Best path to XAML: runtime-hook `LoadComponent` in live app, serialize visual tree
|
||||
|
||||
## Phase 4: Identify and extract pkg-compiled backend
|
||||
|
||||
### Identify pkg binary
|
||||
```
|
||||
PE header: NOT .NET (no CLR header)
|
||||
Search for: "process.versions.pkg", "pkg/prelude", "/snapshot/"
|
||||
NODE_SEA_FUSE:0 = disabled (stock Node, not SEA)
|
||||
pkg version found in binary (e.g., '6.22.0')
|
||||
```
|
||||
|
||||
### Extract via runtime unpacking
|
||||
pkg extracts itself to `%TEMP%\<ServiceName>\<package-name>\<version>\dist` at runtime.
|
||||
Check if the app has been run:
|
||||
```powershell
|
||||
Get-ChildItem "$env:TEMP" -Directory -Filter "*<ServiceName>*"
|
||||
Get-ChildItem "$env:TEMP\*<ServiceName>*\*" -Recurse
|
||||
```
|
||||
|
||||
If found, copy the `dist` directory — it contains:
|
||||
- `server.js` / `server-ws.mjs` (entry points, readable)
|
||||
- `.build/next/` (Next.js standalone build)
|
||||
- `.build/next/server/chunks/` (minified but readable JS, 3000+ files)
|
||||
- `.build/next/server/app/api/` (API routes)
|
||||
- `package.json` (identifies upstream package + version)
|
||||
|
||||
### Match with upstream
|
||||
Check `package.json` name + version against GitHub:
|
||||
- If MIT/Apache licensed → full source available upstream
|
||||
- Clone the repo for complete TypeScript source (2,600+ .ts/.tsx files)
|
||||
- Compare extracted dist with git clone to find local modifications
|
||||
|
||||
## Phase 5: Full inventory checklist
|
||||
|
||||
| Item | Source | Method |
|
||||
|------|--------|--------|
|
||||
| C# source | VibeProxy.dll | ILSpy decompile |
|
||||
| XBF (compiled XAML) | resources.pri | makepri dump + extract |
|
||||
| Assets/icons | MSIX install dir | Copy |
|
||||
| Locales | MSIX install dir | Copy (check all dirs) |
|
||||
| config.yaml | Watchers/ | Copy |
|
||||
| Backend dist | %TEMP% (runtime) | Copy after app run |
|
||||
| Backend source | GitHub (if MIT) | git clone |
|
||||
| Build verification | dotnet build | Must be GREEN |
|
||||
| Sourcemaps | .build/next/ | Usually absent in prod |
|
||||
|
||||
## Common pitfalls
|
||||
- Don't claim "full source" without building and smoke-testing
|
||||
- XBF v2.1 ≠ BAML — `--decompile-baml` produces nothing for WinUI 3
|
||||
- SEA fuse `:0` means stock Node.js, not SEA — look for `process.versions.pkg` instead
|
||||
- 210MB gzip trailing data in PE = pkg payload, not SEA blob
|
||||
- Sourcemaps in production Next.js builds are typically empty (`{"sources":[],"sections":[]}`)
|
||||
- WinUI 3 apps cannot launch standalone without MSIX registration
|
||||
134
our-skills/reverse-winui3-pkg-app/SKILL.md
Normal file
134
our-skills/reverse-winui3-pkg-app/SKILL.md
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
name: reverse-winui3-pkg-app
|
||||
description: "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
|
||||
|
||||
```powershell
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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.
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```powershell
|
||||
# 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
|
||||
|
||||
```powershell
|
||||
# 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
|
||||
145
our-skills/vibeproxy-reverse-engineering/SKILL.md
Normal file
145
our-skills/vibeproxy-reverse-engineering/SKILL.md
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
name: vibeproxy-reverse-engineering
|
||||
description: "Reverse engineer VibeProxy (WinUI 3 .NET 8 MSIX app) — ILSpy decompile, self-contained publish, MSIX repackage, and fork 9router backend"
|
||||
---
|
||||
|
||||
# VibeProxy Reverse Engineering Pipeline
|
||||
|
||||
## Target
|
||||
VibeProxy = WinUI 3 / .NET 8 MSIX app (`AtC.VibeProxy_3.7.2.0_x64__g8zz5t3ayajdt`).
|
||||
Backend = `VibeProxyServices.exe` = pkg-compiled OmniRoute v3.8.50 (MIT).
|
||||
9router = separate npm package (`9router@0.5.50`, MIT, `github.com/decolua/9router`).
|
||||
|
||||
## Phase 1: Decompile C# (ILSpy)
|
||||
|
||||
```powershell
|
||||
# Locate MSIX install
|
||||
$pkg = Get-AppxPackage -Name "AtC.VibeProxy"
|
||||
$installDir = $pkg.InstallLocation # C:\Program Files\WindowsApps\AtC.VibeProxy_3.7.2.0_x64__g8zz5t3ayajdt
|
||||
|
||||
# Decompile VibeProxy.dll with ILSpy CLI
|
||||
ilspycmd -p --decompile-baml "$installDir\VibeProxy.dll" -o C:\Users\User\tmp\VibeProxy_src2\
|
||||
```
|
||||
|
||||
### Build fixes required
|
||||
- `LangVersion=preview` in csproj
|
||||
- HintPaths to `libs/` directory (copy 244 DLLs from MSIX)
|
||||
- Fix `CS0136` duplicate variables (rename `upd` → `ins` in SqliteStatsService.cs)
|
||||
- Fix inline literal `FindOrRegisterForKey("VibeProxy_SingleInstance")` → use const
|
||||
|
||||
### Self-contained publish (NOT framework-dependent)
|
||||
```powershell
|
||||
dotnet publish VibeProxy.csproj -c Release -r win-x64 --self-contained true
|
||||
```
|
||||
Original runtimeconfig uses `includedFrameworks` (self-contained). Rebuilt uses `framework` (FDD). Must publish self-contained or app crashes with "No frameworks were found".
|
||||
|
||||
## Phase 2: MSIX Repackage
|
||||
|
||||
### Staging (CRITICAL — never pack from output dir directly)
|
||||
1. Copy from `bin\Release\net8.0\win-x64\publish\` (NOT `bin\Release\net8.0\`)
|
||||
2. Overlay original `resources.pri`, `Assets/`, `Watchers/`, `Microsoft.UI.Xaml/`, locale dirs, native WinUI DLLs
|
||||
3. EXCLUDE stale `AppxSignature.p7x`, `AppxBlockMap.xml`, `AppxMetadata/CodeIntegrity.cat`
|
||||
4. Write new `AppxManifest.xml` with bumped version and `Publisher` matching cert Subject exactly
|
||||
|
||||
### Cert + Sign + Install
|
||||
```powershell
|
||||
# Create self-signed cert
|
||||
$cert = New-SelfSignedCertificate -Subject "CN=<ORIGINAL_PUBLISHER_CN>" -KeyUsage DigitalSignature -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3","2.5.29.19={text}")
|
||||
|
||||
# Add to Trusted Root + Trusted People (LocalMachine)
|
||||
# Export PFX
|
||||
# Pack
|
||||
& makeappx pack /d $staging /p $msixPath /nv
|
||||
# Sign
|
||||
& signtool sign /fd SHA256 /a /f $certPath /p $password $msixPath
|
||||
# Install
|
||||
Add-AppxPackage -Path $msixPath
|
||||
```
|
||||
|
||||
### Launch via AppsFolder
|
||||
```powershell
|
||||
Start-Process explorer.exe -ArgumentList 'shell:AppsFolder\<PackageFamilyName>!App'
|
||||
```
|
||||
`Start-Process` cannot launch `shell:AppsFolder` URIs directly — use `explorer.exe`.
|
||||
|
||||
### Verification
|
||||
- `Get-AppxPackage` shows correct version + InstallLocation
|
||||
- Hash installed `VibeProxy.dll` == publish hash
|
||||
- Process alive ≥5s with growing RAM
|
||||
- `MainWindowTitle` = custom title (not "VibeProxy.exe")
|
||||
- UI Automation confirms text elements
|
||||
- Pixel sampling confirms color changes
|
||||
|
||||
### CLEANUP (mandatory after install)
|
||||
Remove self-signed cert from `LocalMachine\Root`, `LocalMachine\TrustedPeople`, `CurrentUser\My`. Delete PFX file. Trusted root + accessible private key = arbitrary code signing.
|
||||
|
||||
## Phase 3: Design changes (code-behind only)
|
||||
|
||||
XAML is compiled to XBF v2.1 in `resources.pri` — NOT decompilable. Changes only via C# code-behind in `MainWindow.cs` constructor after `InitializeComponent()`:
|
||||
|
||||
```csharp
|
||||
AppTitleTextBlock.Text = "VibeProxy [ENI]";
|
||||
AppTitleTextBlock.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 168, 85, 247));
|
||||
NavView.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 20, 15, 35));
|
||||
ContentFrame.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 168, 85, 247));
|
||||
ContentFrame.BorderThickness = new Thickness(2);
|
||||
```
|
||||
|
||||
**Gotchas:**
|
||||
- `Color` is ambiguous between `System.Drawing.Color` and `Windows.UI.Color` — qualify as `Windows.UI.Color.FromArgb(...)`
|
||||
- `NavigationView.PaneBackground` doesn't exist in WinUI 3 — use `NavView.Background`
|
||||
- `Window.RequestedTheme` not available in WinUI 3 — set on child elements
|
||||
- `NavView.SelectedItem = NavView.MenuItems[0]` MUST be preserved (don't accidentally replace with design code)
|
||||
|
||||
## Phase 4: 9router fork (backend)
|
||||
|
||||
### Clone real upstream (NOT npm pack)
|
||||
```bash
|
||||
git clone https://github.com/decolua/9router.git 9router_fork
|
||||
cd 9router_fork
|
||||
git checkout -b eni-custom
|
||||
```
|
||||
|
||||
### Build
|
||||
```bash
|
||||
npm install # WITH devDependencies (next build needs them)
|
||||
npx next build --webpack # or: npm run build
|
||||
```
|
||||
|
||||
### Run dev (no build needed)
|
||||
```bash
|
||||
PORT=20130 API_KEY_SECRET=eni-test-key DATA_DIR=./data node node_modules/next/dist/bin/next dev --port 20130
|
||||
```
|
||||
|
||||
### API endpoints
|
||||
- `/api/health` → `{"ok":true}` (no auth)
|
||||
- `/v1/models` → 679 models (Bearer auth)
|
||||
- `/api/v1/chat/completions` → POST (needs configured providers in DB)
|
||||
- `/api/monitoring/health` → VibeProxy health check endpoint
|
||||
|
||||
### API key generation
|
||||
```javascript
|
||||
// Format: {prefix}-{machineId}-{keyId}-{crc8}
|
||||
// prefix: "sk" (default) or "eni" (custom)
|
||||
// CRC = HMAC-SHA256(API_KEY_SECRET, machineId + keyId).slice(0,8)
|
||||
```
|
||||
|
||||
### VibeProxy ↔ 9router integration
|
||||
VibeProxy expects OmniRoute API (`/api/monitoring/health`, `/api/providers/{id}/login`, `/api/oauth/`).
|
||||
9router has different API (`/api/health`, `/api/v1/chat/completions`).
|
||||
Direct swap of VibeProxyServices.exe with 9router won't work — API incompatible.
|
||||
VibeProxyServices.exe = pkg-compiled OmniRoute, NOT 9router.
|
||||
OmniRoute installs 9router as embedded service via `npm install 9router`.
|
||||
|
||||
## Key paths
|
||||
- ILSpy output: `C:\Users\User\tmp\VibeProxy_src2\`
|
||||
- OmniRoute clone: `C:\Users\User\Projects\OmniRoute_fork\` (v3.8.50, MIT)
|
||||
- 9router clone: `C:\Users\User\Projects\9router_fork\` (v0.5.50, MIT)
|
||||
- MakeAppx: `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\makeappx.exe`
|
||||
- Signtool: `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe`
|
||||
|
||||
## What's NOT recovered
|
||||
- XAML markup (24 XBF v2.1 files in resources.pri — format undocumented)
|
||||
- ILSpy artifacts (`Unknown result type` in 61+ files — WinRT projection IL)
|
||||
- Sourcemaps (production build, all empty)
|
||||
- VibeProxy-specific backend delta (diff between OmniRoute git and extracted dist not proven)
|
||||
73
our-skills/vibeproxy-reverse-pipeline/SKILL.md
Normal file
73
our-skills/vibeproxy-reverse-pipeline/SKILL.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
name: vibeproxy-reverse-pipeline
|
||||
description: "Reverse engineer a WinUI 3 MSIX app: ILSpy decompile, self-contained publish, MSIX staging/sign/install, and design modification with pixel verification"
|
||||
---
|
||||
|
||||
# VibeProxy Reverse Engineering Pipeline
|
||||
|
||||
## Architecture
|
||||
- VibeProxy = WinUI 3 (.NET 8) MSIX app, C# code-behind + XAML (XBF v2.1 compiled)
|
||||
- VibeProxyServices.exe = pkg-compiled OmniRoute v3.8.50 (Node.js Next.js standalone)
|
||||
- VibeProxy launches VibeProxyServices.exe as child process on internal port (8316), proxies via external port (8317)
|
||||
- Backend API: `/api/monitoring/health`, `/api/providers/{id}/login`, `/api/oauth/` — OmniRoute endpoints, NOT 9router
|
||||
- 9router = separate npm package (v0.5.50), installed by OmniRoute's service manager, NOT the same as OmniRoute
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Decompile
|
||||
```bash
|
||||
ilspycmd -p --decompile-baml "C:\Program Files\WindowsApps\AtC.VibeProxy_3.7.2.0_x64__g8zz5t3ayajdt\VibeProxy.dll" -o VibeProxy_src2
|
||||
```
|
||||
- Fix CS0136 duplicate variables, inline literals, LangVersion=preview in csproj
|
||||
- HintPaths to libs/ directory with 244 DLLs
|
||||
|
||||
### 2. Publish self-contained
|
||||
```bash
|
||||
dotnet publish VibeProxy.csproj -c Release -r win-x64 --self-contained true
|
||||
```
|
||||
- Framework-dependent build fails in MSIX (no framework found)
|
||||
- Self-contained bundles .NET runtime in package
|
||||
|
||||
### 3. Stage MSIX
|
||||
- Copy publish output to staging dir
|
||||
- Overlay original resources.pri, Assets/, Watchers/, locale dirs, Microsoft.UI.Xaml/, native WinUI DLLs
|
||||
- EXCLUDE: AppxSignature.p7x, AppxBlockMap.xml, AppxMetadata/ from staging
|
||||
- Write AppxManifest.xml with new Identity (Name=AtC.VibeProxyRev, bumped Version, Publisher=CN=...)
|
||||
- Publisher MUST exactly match cert Subject
|
||||
|
||||
### 4. Sign and install
|
||||
```powershell
|
||||
New-SelfSignedCertificate -Subject "CN=..." -KeyUsage DigitalSignature -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3","2.5.29.19={text}")
|
||||
# Add to Trusted Root + Trusted People (LocalMachine)
|
||||
makeappx pack /d staging /p output.msix /nv
|
||||
signtool sign /fd SHA256 /a /f cert.pfx /p password output.msix
|
||||
Add-AppxPackage -Path output.msix
|
||||
```
|
||||
|
||||
### 5. Launch and verify
|
||||
```powershell
|
||||
Start-Process explorer.exe -ArgumentList 'shell:AppsFolder\PackageFamilyName!App'
|
||||
# Wait 8+ seconds, check PID path matches Rev package
|
||||
# Verify via UI Automation (System.Windows.Automation) for text elements
|
||||
# Verify via pixel sampling (System.Drawing.Bitmap.GetPixel) for color changes
|
||||
```
|
||||
|
||||
### 6. Cleanup
|
||||
- Remove self-signed cert from LocalMachine\Root, TrustedPeople, CurrentUser\My
|
||||
- Delete PFX file
|
||||
- Installed MSIX continues to work without cert in store
|
||||
|
||||
## Key gotchas
|
||||
- PowerShell `$_` variables get stripped through bash inline — use .ps1 script files
|
||||
- `RequestedTheme` not available on Window in WinUI 3
|
||||
- `NavigationView.PaneBackground` doesn't exist in WinUI 3
|
||||
- `Color` is ambiguous between System.Drawing.Color and Windows.UI.Color — qualify as Windows.UI.Color
|
||||
- NavView.SelectedItem must be preserved when adding design changes
|
||||
- XBF v2.1 format not decompilable — XAML structure uses original resources.pri
|
||||
- ILSpy artifacts (Unknown result type, _003C compiler classes) in 61+ files — code compiles but WinRT projection incomplete
|
||||
|
||||
## What's NOT reversible
|
||||
- XAML markup (24 XBF files) — format v2.1, node encoding unknown
|
||||
- ILSpy WinRT projection artifacts
|
||||
- Backend sourcemaps (production build, empty .js.map)
|
||||
- VibeProxy-specific OmniRoute delta (diff between git clone and extracted dist not proven)
|
||||
86
our-skills/winui3-msix-reverse-rebuild/SKILL.md
Normal file
86
our-skills/winui3-msix-reverse-rebuild/SKILL.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
name: winui3-msix-reverse-rebuild
|
||||
description: "Reverse engineer a WinUI 3 MSIX app: ILSpy decompile, self-contained publish, MSIX repackage with self-signed cert, and launch via AppsFolder"
|
||||
---
|
||||
|
||||
# WinUI 3 MSIX Reverse & Rebuild Pipeline
|
||||
|
||||
## When to use
|
||||
Reverse engineering an installed WinUI 3 / .NET 8 MSIX application: decompile C#, rebuild, repackage as MSIX, and launch side-by-side with the original.
|
||||
|
||||
## Prerequisites
|
||||
- ILSpy CLI (`ilspycmd`) installed
|
||||
- .NET 8 SDK
|
||||
- Windows SDK (makeappx.exe, signtool.exe) at `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\`
|
||||
- Target MSIX installed (to access original files in `C:\Program Files\WindowsApps\`)
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Locate & decompile
|
||||
```powershell
|
||||
# Find installed MSIX
|
||||
Get-AppxPackage -Name "*TargetApp*"
|
||||
|
||||
# Decompile main DLL
|
||||
ilspycmd -p --decompile-baml "C:\Program Files\WindowsApps\<Package>\TargetApp.dll" -o C:\Users\User\tmp\TargetApp_src\
|
||||
```
|
||||
|
||||
### 2. Fix build errors
|
||||
- Set `<LangVersion>preview</LangVersion>` in .csproj
|
||||
- Add `<HintPath>` entries for all DLLs from the MSIX package
|
||||
- Fix `CS0136` duplicate variables (rename)
|
||||
- Fix `CS0104` ambiguous references (qualify with `Windows.UI.Color` not `System.Drawing.Color`)
|
||||
- Fix inline literals (e.g. `FindOrRegisterForKey("...")` → use const)
|
||||
|
||||
### 3. Self-contained publish
|
||||
```powershell
|
||||
dotnet publish TargetApp.csproj -c Release -r win-x64 --self-contained true
|
||||
```
|
||||
**Critical**: Framework-dependent build fails inside MSIX — must use `--self-contained true`.
|
||||
|
||||
### 4. Stage MSIX payload
|
||||
- Copy publish output to staging dir
|
||||
- Overlay original `resources.pri`, `Assets/`, `Watchers/`, locale dirs, `Microsoft.UI.Xaml/`
|
||||
- Overlay native WinUI DLLs (whitelist, never overwrite published exe/dll)
|
||||
- Write new `AppxManifest.xml` with bumped version and same Publisher CN
|
||||
|
||||
### 5. Cert & sign
|
||||
```powershell
|
||||
# Create self-signed cert matching original Publisher CN
|
||||
$cert = New-SelfSignedCertificate -Subject "CN=<ORIGINAL_PUBLISHER_CN>" -KeyUsage DigitalSignature -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3","2.5.29.19={text}")
|
||||
|
||||
# Add to Trusted Root and Trusted People (LocalMachine)
|
||||
# Export PFX
|
||||
# Pack with makeappx /nv
|
||||
# Sign with signtool /fd SHA256
|
||||
```
|
||||
|
||||
### 6. Install & launch
|
||||
```powershell
|
||||
Add-AppxPackage -Path TargetAppRev.msix
|
||||
# Launch via AppsFolder (NOT Start-Process directly)
|
||||
Start-Process explorer.exe -ArgumentList 'shell:AppsFolder\<PackageFamilyName>!App'
|
||||
```
|
||||
|
||||
### 7. Verify
|
||||
- Check `Get-AppxPackage` shows new version
|
||||
- Check process path starts with Rev package InstallLocation
|
||||
- Check MainWindowTitle and RAM growing (not stuck at 17MB)
|
||||
- Use UI Automation to verify text elements inside window
|
||||
- Sample pixel colors from screenshot for design changes
|
||||
|
||||
### 8. Cleanup (IMPORTANT)
|
||||
- Remove self-signed cert from `LocalMachine\Root`, `LocalMachine\TrustedPeople`, `CurrentUser\My`
|
||||
- Delete PFX file
|
||||
- Trusted root + accessible private key = arbitrary code signing capability
|
||||
|
||||
## Gotchas
|
||||
- `RequestedTheme` not available on `Window` in WinUI 3 — use `ElementTheme` on child elements
|
||||
- `NavigationView.PaneBackground` doesn't exist in WinUI 3 — use `NavView.Background`
|
||||
- `base.Title` changes Windows title bar but custom title bar uses `AppTitleTextBlock.Text`
|
||||
- XBF v2.1 (XAML binary) is NOT decompilable — UI structure stays from original `resources.pri`
|
||||
- `NavView.SelectedItem = NavView.MenuItems[0]` must be preserved or dashboard won't load
|
||||
- PowerShell `$` variables get stripped through bash inline — use `.ps1` script files
|
||||
- `Start-Process 'shell:AppsFolder\...'` fails — use `explorer.exe` as intermediary
|
||||
- Process alive at 17MB RAM with title "AppName.exe" = crashed (.NET framework not found)
|
||||
- Process alive at 200MB+ RAM with proper title = working
|
||||
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
|
||||
133
our-skills/winui3-reverse-engineering/SKILL.md
Normal file
133
our-skills/winui3-reverse-engineering/SKILL.md
Normal file
@@ -0,0 +1,133 @@
|
||||
---
|
||||
name: winui3-reverse-engineering
|
||||
description: "Reverse engineer WinUI 3 / .NET 8 MSIX applications: ILSpy decompilation, self-contained publish, MSIX packaging with self-signed cert, and side-by-side launch with modified code"
|
||||
---
|
||||
|
||||
# WinUI 3 Reverse Engineering Pipeline
|
||||
|
||||
## When to use
|
||||
Reverse engineering a WinUI 3 / Windows App SDK / .NET 8 MSIX-packaged desktop application. Produces editable C# source, rebuildable MSIX, and a running modified app side-by-side with the original.
|
||||
|
||||
## Prerequisites
|
||||
- ILSpy CLI (`dotnet tool install --global ilspycmd`)
|
||||
- .NET 8 SDK
|
||||
- Windows SDK (makeappx.exe, signtool.exe, makepri.exe)
|
||||
- PowerShell 5+
|
||||
- Target app installed as MSIX (in `C:\Program Files\WindowsApps\`)
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Locate the app
|
||||
```powershell
|
||||
Get-Process <AppName> | Select-Object Id,Path
|
||||
# Path will be like C:\Program Files\WindowsApps\<PackageFullName>\<App>.exe
|
||||
```
|
||||
|
||||
### 2. Identify the stack
|
||||
- `.dll` next to `.exe` = .NET app (check for `coreclr.dll`, `hostfxr.dll`)
|
||||
- Main `.dll` (3+ MB) = application logic; `.exe` (small) = native loader
|
||||
- `resources.pri` = XAML binary (XBF) + strings + images
|
||||
- `Watchers\` or similar = backend services (may be pkg-compiled Node.js)
|
||||
|
||||
### 3. Decompile C#
|
||||
```bash
|
||||
ilspycmd "C:\path\to\App.dll" -p -o "C:\output\src" --decompile-baml -r "C:\path\to\install\dir"
|
||||
```
|
||||
- `--decompile-baml` may not work for WinUI 3 (XBF v2.1, not BAML)
|
||||
- `-r` provides reference path for dependency resolution
|
||||
|
||||
### 4. Fix csproj
|
||||
- ILSpy generates bare `<Reference>` without HintPath for WinRT projections
|
||||
- Copy all DLLs from install dir to `libs/` folder
|
||||
- Add `<HintPath>libs\*.dll</HintPath>` for each reference
|
||||
- Set `<LangVersion>preview</LangVersion>` (ILSpy may emit unsupported version)
|
||||
- Set `<GenerateAssemblyInfo>False</GenerateAssemblyInfo>`
|
||||
|
||||
### 5. Fix common compile errors
|
||||
- **CS0136** (duplicate variable): rename one occurrence
|
||||
- **CS0104** (ambiguous `Color`): qualify as `Windows.UI.Color.FromArgb(...)`
|
||||
- **CS1061** (`PaneBackground` not on NavView): use `Background` instead
|
||||
- **CS1061** (`RequestedTheme` not on Window): set on `Content` element instead
|
||||
- ILSpy inlines `const` values — fix inline literals (e.g., `FindOrRegisterForKey("OriginalKey")` → `FindOrRegisterForKey(AppInstanceKey)`)
|
||||
|
||||
### 6. Publish self-contained
|
||||
```bash
|
||||
dotnet publish App.csproj -c Release -r win-x64 --self-contained true
|
||||
```
|
||||
- Framework-dependent publish fails in MSIX (no global .NET runtime visible)
|
||||
- Self-contained bundles .NET runtime into the package
|
||||
|
||||
### 7. Overlay original assets
|
||||
Copy from original MSIX to publish output (whitelist only, never overwrite published exe/dll):
|
||||
- `resources.pri` (XBF, strings, images)
|
||||
- `Assets/` folder
|
||||
- `Watchers/` folder (backend)
|
||||
- Locale directories (`xx-XX/`)
|
||||
- `Microsoft.UI.Xaml/` folder
|
||||
- Native WinUI DLLs (Microsoft.UI.Xaml.Controls.dll, CoreMessagingXP.dll, etc.)
|
||||
- `Microsoft.WindowsAppRuntime.dll`, `.Bootstrap.dll`, `.Bootstrap.Net.dll`
|
||||
|
||||
### 8. Create AppxManifest with new identity
|
||||
```xml
|
||||
<Identity Name="<OriginalName>Rev" Publisher="<OriginalPublisher>" Version="3.7.2.7" ProcessorArchitecture="x64" />
|
||||
```
|
||||
- Use same Publisher CN as original (for cert matching)
|
||||
- Bump version on each rebuild
|
||||
- Keep `runFullTrust` capability
|
||||
|
||||
### 9. Self-signed cert + MSIX packaging
|
||||
```powershell
|
||||
# Create cert matching manifest Publisher
|
||||
$cert = New-SelfSignedCertificate -Subject "CN=<PublisherCN>" -KeyUsage DigitalSignature -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3","2.5.29.19={text}")
|
||||
|
||||
# Add to Trusted Root and Trusted People
|
||||
# Export PFX, sign MSIX with signtool
|
||||
# Register with Add-AppxPackage
|
||||
|
||||
# CRITICAL: Remove cert from all stores and delete PFX after install
|
||||
# See cleanup section below
|
||||
```
|
||||
|
||||
### 10. Launch and verify
|
||||
```powershell
|
||||
Start-Process explorer.exe -ArgumentList 'shell:AppsFolder\<PackageFamilyName>!App'
|
||||
Start-Sleep -Seconds 10 # WinUI 3 needs time to initialize
|
||||
# Verify: PID, Path (must be Rev package), MainWindowTitle, RAM > 100MB
|
||||
# UI Automation: [System.Windows.Automation.AutomationElement]::FromHandle()
|
||||
# Screenshot: System.Drawing.Bitmap + CopyFromScreen + GetPixel for color verification
|
||||
```
|
||||
|
||||
## Key gotchas
|
||||
- WinUI 3 XAML is compiled to XBF v2.1 in `resources.pri`, NOT BAML — ILSpy `--decompile-baml` won't extract it
|
||||
- `copy_all.ps1` that copies ALL MSIX files will overwrite rebuilt exe/dll with originals — always whitelist
|
||||
- `NODE_SEA_FUSE:0` = disabled SEA; check for `pkg` markers (`PRELUDE_POSITION`, `process.versions.pkg`) instead
|
||||
- pkg auto-extracts to `%TEMP%\<AppName>\<version>\dist` — check there before manual extraction
|
||||
- Cert in LocalMachine\Root with accessible PFX = code signing security risk — always cleanup after
|
||||
- `Start-Process` cannot launch `shell:AppsFolder` URIs directly — use `explorer.exe` as intermediary
|
||||
- Process may show 0x0 window for 10+ seconds before UI initializes — wait before screenshot
|
||||
|
||||
## XBF extraction (if needed)
|
||||
```powershell
|
||||
# Dump PRI
|
||||
makepri.exe dump /if "resources.pri" /of "dump.xml" /dt detailed /o
|
||||
# Extract XBF from Base64 in XML
|
||||
# XBF v2.1 offsets are relative to metadata start (byte 12), not absolute
|
||||
# Table entries are 12 bytes each (not 8 as in v1.0)
|
||||
# Node encoding differs from v1.0 — no working open-source parser exists
|
||||
```
|
||||
|
||||
## pkg-compiled Node.js backend detection
|
||||
- PE header: no CLR header (not .NET)
|
||||
- Search for `NODE_SEA_FUSE`, `pkg/prelude`, `process.versions.pkg`
|
||||
- `process.versions.pkg = '6.22.0'` confirms pkg version
|
||||
- Trailing data after PE sections (gzip compressed) = pkg payload
|
||||
- Auto-extraction: check `%TEMP%\<AppName>\` for already-extracted dist
|
||||
|
||||
## Security cleanup (MANDATORY after install)
|
||||
```powershell
|
||||
# Remove self-signed cert from all stores
|
||||
$certSubject = "CN=<PublisherCN>"
|
||||
# Remove from LocalMachine\Root, LocalMachine\TrustedPeople, CurrentUser\My
|
||||
# Delete PFX file
|
||||
# Verify: Get-ChildItem Cert:\... | Where-Object { $_.Subject -eq $certSubject } returns empty
|
||||
```
|
||||
Reference in New Issue
Block a user