
Glass - eine schnelle und kostenlose IDA-Pro-Alternative
wie in durchsichtig und glatt
Ein schneller, nativer, mobile-app first interaktiver Disassembler. Geistiger Nachfolger von IDA Pro für den Android‑/iOS‑Reverse‑Engineering‑Workflow, aufgebaut um:
smali für APK / DEX / smali‑Handhabungarmv8-encode für AArch64 und ARMv7 (A32 / Thumb) — native .so, iOS Mach‑Ogpui (Zed) für GPU‑beschleunigte native UIredb für inhaltsadressierte Persistenzrquickjs für skriptbare Plugins (geplant)Lizenz: GPL-3.0-only (von smali übernommen).
Wir alle haben IDA Pro benutzt – es ist der Industriestandard für Reverse Engineering und hat jahrelange Plugin-Entwicklung hinter sich, aber es ist langsam, teuer und veraltet. Glass ist zu 100 % nativ in Rust mit einer GPU‑beschleunigten Oberfläche für flüssige Interaktion. Es ist außerdem zu 100 % kostenlos und Open Source – bitte trage bei.
arm64-v8a- als auch armeabi-v7a-Kopien einer Bibliothek in einer einzigen Abfrage durchsucht werden). Byte‑Muster‑Grammatik mit Maskierung + Lücken; getippte Assembly‑Grammatik für AArch64 und ARMv7 mit einem ISA‑bewussten Autovervollständigungs‑Dropdown.Ein Rundgang durch die Hauptansichten – klicke auf ein Vorschaubild, um es in voller Größe zu sehen.
Jede Analyse, die Glass in der GUI durchführt, wird auch als CLI‑Befehl bereitgestellt, der strukturiertes JSON ausgibt. Dieselbe glass-Binärdatei ist der Einstiegspunkt für Automatisierung – wähle einen Unterbefehl und du erhältst ein einmaliges, skriptbares Ergebnis, perfekt für jq-Pipelines und CI.```sh
glass classes ./app.apk --package com.example. --text
glass callers ./libfoo.so --artifact libfoo.so --symbol "glass::main"
onCreate across DEX, machine-readable:glass search ./app.apk onCreate | jq '.data.hits[] | select(.kind=="method")'
glass types ./app.ipa --kind swift-class --text
glass type ./app.ipa --artifact app --name blackjack.ContentView
Pass `--text` für eine menschenlesbare Darstellung, lassen Sie es für JSON weg.
Vollständige Referenz: **[docs/cli-api.md](https://github.com/azw413/glass/blob/main/docs/cli-api.md)**.
Damit können Sie gängige Operationen skripten und automatisieren.
## Fähigkeiten und MCP
Jedes CLI-Verb wird auch als Tool über einen integrierten MCP (Model Context Protocol)-Server bereitgestellt, sodass jeder MCP-fähige Host – Claude Desktop, Cursor, Zed, Ihr eigener Client – Glass direkt zur Unterstützung bei Reverse-Engineering-Aufgaben steuern kann.```sh
# Print the machine-readable skill catalog (one JSON object listing
# every verb with its schema and an example invocation).
glass skills
# Run as an MCP stdio server. Plug into any MCP host's tool list.
glass mcp
Um sich bei Claude Desktop zu registrieren, fügen Sie Glass zu ~/Library/Application Support/Claude/claude_desktop_config.json hinzu:```json
{
"mcpServers": {
"glass": { "command": "/usr/local/bin/glass", "args": ["mcp"] }
}
}
Das Modell kann dann `inspect`, `symbols`, `disasm`, `cfg-of`, `dex-callers`, `search` und jedes andere Verb auf jedem Bundle aufrufen, auf das Sie es richten. Die Ergebnisse der Tools kommen als dasselbe JSON-Envelope zurück, das Sie auch von der CLI erhalten würden.
## Suchen
Drei komplementäre Suchmaschinen, alle verfügbar aus derselben ⌘F-Palette in der GUI und als CLI/MCP-Verben.
### Volltextsuche
Bundle-weite unscharfe Übereinstimmung (fuzzy match) über native Symbole, DEX-Klassen/-Methoden/-Felder und String-Literale in Code- und Datenabschnitten. Live-gefiltert während der Eingabe; Ergebnisse werden an die richtige Ansicht weitergeleitet (Listing für native Adressen, Smali-Viewer für DEX-Ziele, Hex-View für Datentreffer). Indizes werden nach dem Laden in einem Hintergrundthread aufgebaut – ein Fortschritts-Chip zeigt den Fortschritt an.```sh
glass search ./app.apk onCreate # all things named like "onCreate"
glass search ./libfoo.so init --limit 20
CLI-Referenz: search-Befehl in docs/cli-api.md.
Byte-Level-Pattern-Engine. Jedes Atom ist eine 2-Zeichen-Hex-Maske (c0, e?, ?f, ??) oder ein Gap (* = 0..=32 Bytes, *(min..max) für explizite Grenzen). Treffer erstrecken sich nicht über Abschnitte. In der GUI-Palette schaltet ⌘2 in den Binärmodus; das Kontrollkästchen Nur Code (standardmäßig aktiviert) schränkt die Suche auf Textabschnitte ein, damit Sie bei der Suche nach einer Befehlssignatur nicht in Datenhits ertrinken.```sh
mov w0, #1 ; retglass bin-search ./libfoo.so --artifact libfoo.so --pattern '20 00 80 52 c0 03 5f d6'
glass bin-search ./libfoo.so --artifact libfoo.so --pattern '?? ?? ?? 9? ?? ?? 4? 91'
glass bin-search ./libfoo.so --artifact libfoo.so --pattern 'de ad be ef'
Vollständige Grammatik + ausgearbeitete Beispiele: [`docs/BinSearch.md`](https://github.com/azw413/glass/blob/main/docs/BinSearch.md).
### Befehlssuche
Schreiben Sie den Assemblercode, Glass kompiliert ihn in Bytes. Eine durch `;` getrennte Sequenz wird über [armv8-encode](https://github.com/azw413/armv8-encode) kodiert — **AArch64** (`mov w0, #1`, `adrp x1, *`) und **ARMv7** in beiden Modi (Thumb `mov r1, r7` / `bxeq lr` / `push {r4-r7, lr}` und A32). Alle Platzhalter werden in Operanden-Bitmasken übersetzt, bevor die Byte-Engine übernimmt. Der Scan ist global — jedes native Artefakt im Bundle erhält die Atome der richtigen ISA (Android-Apps mit sowohl `arm64-v8a`- als auch `armeabi-v7a`-Bibliotheken werden in einer einzigen Abfrage durchsucht).
Im Binärmodus der GUI schaltet ⌘B zwischen den Grammatiken **Bytes** und **Asm** um; ein ISA-bewusstes Autovervollständigungs-Dropdown zeigt Varianten an, die noch zu dem passen, was Sie eingegeben haben — `r1` filtert AArch64-Kandidaten heraus, `w0` filtert ARMv7-Kandidaten heraus.
Platzhalter:
| Token | Bedeutung |
|---|---|
| `*` | jeder Operand (Art wird vom gewählten Opcode abgeleitet) |
| `#*` | jeder Immediate-Wert (Hinweis für den Opcode-Auswähler) |
| `x`, `w` | jedes AArch64 X- oder W-Klassenregister |
| `r` | jedes ARMv7 GPR (`r0..r15`, `sp`, `lr`, `pc`) |
| `<*>`, `<X>`, `<W>`, `<R>`, `<imm>` | Eingeklammerte Äquivalente, nützlich in anderen Syntaxen verschachtelt (`[x, #*]`, `[r, #*]`) |```sh
# AArch64 — every `mov w0, #N` (any N)
glass insn-search ./libfoo.so --artifact libfoo.so --pattern 'mov w0, #*'
# AArch64 — any ADRP into x1 followed immediately by ADD into the same reg
glass insn-search ./libfoo.so --artifact libfoo.so --pattern 'adrp x1, * ; add x1, x1, #*'
# ARMv7 (Thumb) — `mov r1, r*` followed by a return
glass insn-search ./libfoo.so --artifact libfoo.so --pattern 'mov r1, r* ; bx lr'
# ARMv7 (any cond) — conditional bx in literal-pool callers
glass insn-search ./libfoo.so --artifact libfoo.so --pattern 'bxeq lr'
# every `ret x30` — concrete, no wildcards
glass insn-search ./libfoo.so --artifact libfoo.so --pattern 'ret'
Die Antwort enthält bytes_hex, die die kompilierte Maske anzeigen (z.B. 01/1f ?? ?? 90/9f für adrp x1, *), sodass Sie genau sehen können, welche Bits festgelegt und welche als Wildcard gesetzt sind. Captures (<name:kind>, die auf dasselbe Operand später im Pattern verweisen) sind konzipiert, aber noch nicht implementiert.
Vollständiger Entwurf + Phasen: docs/InsnPattern.md. CLI/MCP-Referenz: insn-search in docs/cli-api.md.
Glass kann heute bereits für das Reverse-Engineering von Android (APK / DEX / native .so) und iOS (IPA / Mach-O) Apps verwendet werden, die auf AArch64 und 32-Bit ARMv7 (armeabi-v7a-Bibliotheken, A32 + Thumb) abzielen.
Dateiladen
.apk, .aab), iOS-Bundles (.ipa) oder eigenständige ELF-/Mach‑O-Binaries (.so, .dylib, rohe Executables) direkt – Glass erkennt das Format automatisch.arm64e wird bevorzugt, reines arm64 ist der Fallback. Funktioniert gleichermaßen bei Bundles und eigenständigen Dateien (z.B. glass gui /usr/lib/dyld).libfoo.so, die in zwei APKs ausgeliefert wird (oder die gleiche libswiftCore.dylib in zwei IPAs), teilt den Analysezustand.smali).iOS — IPA / Mach‑O
Payload/*.app/ finden, Info.plist parsen und den arm64/arm64e-Slice aus einem beliebigen Fat‑Binary innerhalb auswählen.Frameworks/*.framework + *.dylib wird als eigenes natives Artefakt geladen, mit denselben Übersichts- und pro‑Sektion‑Disassembly‑Ansichten wie für Android .so‑Dateien.__objc_classlist – Klassen, Kategorien, Methoden, Ivars, Eigenschaften – mit demangelten Namen (Legacy‑Swift‑Mangling _TtC... inklusive) und klickbaren Sprüngen von Methodenadressen in die Auflistung.__swift5_types – Klassen, Strukturen, Aufzählungen mit ihren Feldern und (bei Klassen) VTables, ebenfalls klickbar in die Auflistung.Android — APK / DEX / nativ
.so‑Dateien unter lib/<abi>/ werden pro ABI geladen; AArch64 (arm64-v8a) und ARMv7 (armeabi-v7a) erhalten beide vollständige Disassembly‑Ansichten. Andere ABIs (x86 / x86_64) werden zur Hex‑Ansicht umgeleitet, bis ein Decoder verfügbar ist.Bearbeitung
r1 zeigt nur ARMv7‑Varianten; w0 zeigt nur AArch64.AArch64 nativ (ELF + dünnes Mach‑O)
.eh_frame‑FDEs und synthetisierten <name>@plt‑Einträgen. C++/Rust/Swift‑Demangling über symbolic-demangle.adrp + add/ldr‑Paare werden zu Datenzielen aufgelöst, einschließlich Stringliteralen, die inline als Kommentare angezeigt werden.ARMv7 nativ (ELF)
00 00 Padding), 32‑Bit Thumb‑2 und A32 zeigen 4..eh_frame und synthetisierte <name>@plt‑Einträge (12‑Byte‑Stubs).movw + movt‑Fusion: movw R, #lo16 ; movt R, #hi16 wird über Befehlspaare hinweg erkannt und die aufgelöste 32‑Bit‑Konstante erhält einen ; "..."‑rodata‑String‑Kommentar in der movt‑Zeile.ldr Rt, [pc, #imm]‑Literal‑Pool‑Ladungen dereferenzieren eine Ebene in rodata für die gleiche Art von Inline‑String‑Kommentar, den AArch64s ADRP+ADD‑Pfad erzeugt.UI
change me findet changeMessage und change_me_count, aber nicht dispatchMenuVisibilityChanged).arm64-v8a + armeabi-v7a erhalten einheitliche Ergebnisse mit dem Artefakt + der Sektion pro Treffer.embedded.mobileprovision.resources.arsc‑Parsing erfordern).r0, lsl #2) und Vor‑/Nach‑Index‑Speicher ([rN, #imm]!, [rN], #imm) werden geparst, aber nur konkret – keine Wildcards innerhalb von Klammern.Glass läuft auf macOS 13+ (primäres Ziel, GPU‑beschleunigt über Metal – kein zusätzliches SDK nötig, das Metal‑Framework ist im Betriebssystem enthalten), Linux (X11 oder Wayland über gpui_linux, Vulkan‑basiert) und Windows 10/11 (Direct3D‑basiert über gpui, erstellt mit dem MSVC‑Toolset).
Es gibt ein vorab erstelltes Binärpaket für macOS unter Releases; wenn Sie jedoch aus dem Quellcode erstellen müssen: die gute Nachricht: Es sind zwei Befehle.
Dies zieht libxkbcommon-dev, die Wayland- und XCB-Header, Vulkan, ALSA und den Rest der Toolchain ein, die gpui_linux zum Linken benötigt. Ohne diese schlägt der Build zur Linkzeit mit fehlenden xkbcommon / wayland-client-Symbolen fehl.
Wenn Sie das Skript nicht ausführen möchten, sind die entsprechenden Pakete auf Debian / Ubuntu (amd64): ```sh
sudo apt-get update && sudo apt-get install -y
build-essential clang cmake pkg-config
libfontconfig-dev libfreetype-dev
libwayland-dev libxkbcommon-x11-dev
libasound2-dev libvulkan-dev
libzstd-dev libsqlite3-dev libssl-dev
libglib2.0-dev
Der Build schlägt früh in einem Abhängigkeits-Build-Skript fehl (`fontconfig was not found in the pkg-config search path`), wenn `libfontconfig-dev` fehlt, und später beim Linken für die X11/Wayland/Vulkan-Bibliotheken. `libglib2.0-dev` wird benötigt, weil der Frida-Treiber GLib unter Linux dynamisch linkt (unter macOS bündelt das Frida-Devkit es statisch) — ohne dies schlägt das Linken mit `undefined symbol: g_object_unref` fehl.
**Nur Windows — native Build-Toolchain installieren.** `gpui` benötigt die MSVC-Toolchain (das GNU/MinGW-Ziel wird nicht unterstützt). Verwendung von [winget](https://learn.microsoft.com/windows/package-manager/winget/): ```powershell
# 1. MSVC compiler, linker, and Windows SDK (the "Desktop development with C++" workload).
winget install --id Microsoft.VisualStudio.2022.BuildTools `
--override "--quiet --wait --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
# 2. CMake — tree-sitter (via the Zed `language` crates) builds wasmtime's C API with it.
winget install --id Kitware.CMake
# 3. LLVM/Clang — `bindgen` (frida-sys, gpui, media) needs libclang.dll.
winget install --id LLVM.LLVM
Der LLVM-Installer fügt sich nicht selbst zu PATH hinzu, also weisen Sie bindgen vor dem Build auf libclang.dll hin (setzen Sie es dauerhaft über System → Umgebungsvariablen oder pro Shell): ```powershell
$env:LIBCLANG_PATH = "C:\Program Files\LLVM\bin"
Ohne diese schlägt der Build in Abhängigkeits-Build-Skripten fehl: `linker 'link.exe' not found` (kein MSVC), `failed to spawn 'cmake'` (kein CMake) oder `Unable to find libclang` (kein `LIBCLANG_PATH`). Die Stack-Reserve der `glass`-Binärdatei wird automatisch auf MSVC erhöht (siehe `crates/glass-cli/build.rs`), sodass die CLI den kleinen Windows-Standard-Hauptthread-Stack nicht überläuft – kein Handlungsbedarf.
3. **Klonen und bauen**: ```sh
git clone https://github.com/azw413/Glass.git
cd glass
cargo build --release -p glass-cli
cp target/release/glass <to somewhere on your PATH>
Der erste Build wird gpui und Freunde kompilieren und einige Minuten dauern. Nachfolgende Builds sind schnell.
Ausführen: ```sh
glass ~/path/to/app.apk glass ~/path/to/app.ipa
glass ~/path/to/libfoo.so glass ~/path/to/libBar.dylib glass /usr/lib/dyld
glass
glass bundle ~/path/to/app.apk
glass db-dump ~/path/to/app.apk
Verwenden Sie stets den Release-Build — Debug-Builds zerlegen um Größenordnungen langsamer.
.app-BundlesUm die Release-Binärdatei in ein Glass.app-Bundle zu verpacken, um sie per Doppelklick aus dem Finder zu starten:```sh cargo build --release -p glass-cli ./packaging/make-app.sh open dist/Glass.app
Das Bundle ist ad-hoc signiert (nicht Developer-ID-signiert / notarized), daher verweigert macOS beim ersten Start das Öffnen; Rechtsklick → **Öffnen** um Gatekeeper einmal zu umgehen.
Zwei Möglichkeiten, ein vorgebautes ZIP zu erhalten, ohne lokal zu bauen:
- **Neuestes `main`** — jeder Push lädt ein `Glass-app-<sha>.zip` als 14-Tage-Workflow-Artefakt hoch. Holen Sie es sich vom [Actions-Tab](https://github.com/azw413/Glass/actions).
- **Getaggtes Release** — das Pushen eines `v*`-Tags (z.B. `v0.1.0`) löst denselben Workflow aus und veröffentlicht zusätzlich ein `Glass-<tag>-macOS.zip` auf der [Releases-Seite](https://github.com/azw413/Glass/releases) mit automatisch generierten Release-Notes.
## Arbeitsbereich
| Crate | Zweck |
|------------------|------------------------------------------------------------------|
| `glass-core` | Gemeinsame Typen (`CodeKind`, IDs) |
| `glass-arch-arm` | AArch64 + ARMv7-Disassembly, Symboltabelle, PLT-Synthese, Demangling |
| `glass-arch-dex` | DEX / smali-Fassade über `smali` |
| `glass-mobile` | APK + IPA-Bundle-Laden, Native-Lib-Extraktion, Manifest |
| `glass-db` | Inhaltsadressierte Persistenz (redb): Bundles, Tabs, Einstellungen |
| `glass-device` | Android (adb) + iOS (usbmux) Geräteerkennung |
| `glass-api` | Analyseverben (Suche, XRefs, CFG, Bearbeitungen), gemeinsam genutzt von CLI + MCP + GUI |
| `glass-ui` | `gpui`-Frontend: Baum, Auflistung, Hex, Manifest, Palette |
| `glass-cli` | Headless-Inspektor + GUI-Starter |
| `glass-mcp` | MCP-Server, der jedes CLI-Verb als Werkzeug bereitstellt |
| `glass-script` | QuickJS-Plugin-Laufzeitumgebung (Platzhalter) |
## Fahrplan
- **iOS tiefergehend** — Berechtigungen und `embedded.mobileprovision`-Parsing. (Der ObjC `__objc_classlist` und der Swift `__swift5_types`-Metadaten-Pass sind eingetroffen — siehe `glass types` / `glass type`.)
- **x86 / x86_64** — Disassembly für Emulator-Builds von Android `.so`-Dateien.
- **Internes Scripting** — QuickJS-Plugin-Host mit einer stabilen API für Analyse-Pässe.
- **Fortgeschritten** — Signiertes APK-Neubauen, Downstream-Shift bei ARMv7-In-Place-Bearbeitungen (so dass 2→4-Byte-Wachstum an benachbarten Code vorbei splißen kann, anstatt abzulehnen).
redb persistiert; beim erneuten Start wird an der Stelle fortgesetzt, an der Sie aufgehört haben.