
Glass - une alternative rapide et gratuite à IDA Pro
au sens de transparent et lisse
Un désassembleur interactif rapide, natif et pensé d’abord pour les applications mobiles. Successeur spirituel d’IDA Pro pour le workflow de rétro-ingénierie Android / iOS, construit autour de :
smali pour la gestion des APK / DEX / smaliarmv8-encode pour AArch64 et ARMv7 (A32 / Thumb) — .so natifs, Mach-O iOSgpui (Zed) pour l’interface native accélérée par GPUredb pour la persistance adressée par contenurquickjs pour des plugins scriptables (prévu)Licence : GPL-3.0-only (héritée de smali).
Nous avons tous utilisé IDA Pro — c’est la référence du secteur pour la rétro-ingénierie, avec des années de plugins derrière lui, mais c’est lent, cher et daté. Glass est 100 % natif en Rust avec une interface accélérée par GPU pour une interaction fluide. C’est aussi 100 % gratuit et open source — contribuez.
arm64-v8a et armeabi-v7a d’une bibliothèque sont donc cherchées en une seule requête). Grammaire de motifs d’octets avec masquage + intervalles ; grammaire d’assembleur typée pour AArch64 et ARMv7, avec une liste déroulante d’autocomplétion tenant compte de l’ISA.Un parcours des vues principales — cliquez sur n’importe quelle vignette pour la voir en taille réelle.
Chaque analyse que Glass effectue dans l’interface graphique est également exposée comme verbe CLI émettant du JSON structuré. Le même binaire glass est le point d’entrée de l’automatisation — choisissez une sous-commande et vous obtenez un résultat ponctuel et scriptable, parfait pour les pipelines jq et l’intégration continue.```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
Passez `--text` pour un rendu lisible par un humain, omettez-le pour le JSON.
Référence complète : **[docs/cli-api.md](https://github.com/azw413/glass/blob/HEAD/docs/cli-api.md)**.
Cela signifie que vous pouvez scripter et automatiser les opérations courantes.
## Compétences et MCP
Chaque verbe CLI est également exposé en tant qu'outil via un serveur MCP (Model Context Protocol) intégré, de sorte que tout hôte compatible MCP — Claude Desktop, Cursor, Zed, votre propre client — peut piloter Glass directement pour aider aux tâches de rétro-ingénierie.```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
Pour enregistrer Glass auprès de Claude Desktop, ajoutez Glass à ~/Library/Application Support/Claude/claude_desktop_config.json:```json
{
"mcpServers": {
"glass": { "command": "/usr/local/bin/glass", "args": ["mcp"] }
}
}
Le modèle peut ensuite appeler `inspect`, `symbols`, `disasm`, `cfg-of`, `dex-callers`, `search` et tous les autres verbes sur n'importe quel bundle que vous lui désignez. Les résultats des outils reviennent dans la même enveloppe JSON que celle que vous obtiendriez avec la CLI.
## Recherche
Trois moteurs complémentaires, tous disponibles depuis la même palette ⌘F de l'interface graphique et en tant que verbes CLI / MCP.
### Recherche en texte intégral
Correspondance floue à l'échelle du bundle entre les symboles natifs, les classes / méthodes / champs DEX et les littéraux de chaîne dans les sections de code et de données. Filtrage en direct pendant la saisie ; les résultats sont acheminés vers la vue appropriée (listing pour les adresses natives, visionneuse smali pour les cibles DEX, vue hexadécimale pour les correspondances de données). Les index sont construits sur un thread d'arrière-plan après le chargement — une pastille de progression s'affiche pendant l'opération.```sh
glass search ./app.apk onCreate # all things named like "onCreate"
glass search ./libfoo.so init --limit 20
Référence CLI : verbe search dans docs/cli-api.md.
Moteur de motifs au niveau octet. Chaque atome est un masque hexadécimal de 2 caractères (c0, e?, ?f, ??) ou un écart (* = 0..=32 octets, *(min..max) pour des bornes explicites). Les correspondances ne traversent pas les sections. Dans la palette de l'interface graphique, ⌘2 bascule en mode binaire ; la case Code only (activée par défaut) limite l'analyse aux sections de texte afin de ne pas être submergé par les résultats de données lorsqu'on recherche une forme d'instruction.```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'
Grammaire complète + exemples détaillés : [`docs/BinSearch.md`](https://github.com/azw413/glass/blob/HEAD/docs/BinSearch.md).
### Recherche d'instructions
Écrivez le code assembleur, Glass le compile en octets. Une séquence séparée par `;` est encodée via [armv8-encode](https://github.com/azw413/armv8-encode) — **AArch64** (`mov w0, #1`, `adrp x1, *`) et **ARMv7** dans les deux modes (Thumb `mov r1, r7` / `bxeq lr` / `push {r4-r7, lr}` et A32). Tous les jokers sont traduits en masques de bits d'opérande avant que le moteur d'octets ne prenne le relais. L'analyse est globale — chaque artefact natif du bundle reçoit les atomes de la bonne ISA (les applications Android contenant à la fois des bibliothèques `arm64-v8a` et `armeabi-v7a` sont recherchées en une seule requête).
Dans le mode binaire de l'interface graphique, ⌘B bascule entre les grammaires **Bytes** et **Asm** ; une liste déroulante d'autocomplétion sensible à l'ISA affiche les variantes qui correspondent encore à ce que vous avez saisi — `r1` filtre les candidats AArch64, `w0` filtre ceux ARMv7.
Jokers :
| Jeton | Signification |
|---|---|
| `*` | tout opérande (type déduit de l'opcode choisi) |
| `#*` | tout immédiat (suggère le sélecteur d'opcode) |
| `x`, `w` | tout registre AArch64 de classe X ou W |
| `r` | tout GPR ARMv7 (`r0..r15`, `sp`, `lr`, `pc`) |
| `<*>`, `<X>`, `<W>`, `<R>`, `<imm>` | équivalents entre chevrons, utiles imbriqués dans d'autres syntaxes (`[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'
La réponse contient bytes_hex affichant le masque compilé (par ex. 01/1f ?? ?? 90/9f pour adrp x1, *) afin que vous puissiez voir exactement quels bits sont épinglés par rapport aux jokers. Les captures (<name:kind> référençant la même opérande plus loin dans le motif) sont conçues mais pas encore implémentées.
Conception complète + phasage : docs/InsnPattern.md. Référence CLI/MCP : insn-search dans docs/cli-api.md.
Glass est utilisable aujourd'hui pour le reverse engineering d'applications Android (APK / DEX / .so natif) et iOS (IPA / Mach-O) ciblant AArch64 et ARMv7 32 bits (bibliothèques armeabi-v7a, A32 + Thumb).
Chargement de fichiers
.apk, .aab), les bundles iOS (.ipa) ou tout binaire ELF / Mach-O autonome (.so, .dylib, exécutables bruts) — Glass détecte automatiquement le format.arm64e est privilégié, arm64 classique est la solution de repli. Fonctionne aussi bien sur les bundles que sur les fichiers autonomes (par ex. glass gui /usr/lib/dyld).libfoo.so embarqué dans deux APK (ou le même libswiftCore.dylib dans deux IPA) partage l'état d'analyse.smali).iOS — IPA / Mach-O
Payload/*.app/, analysez Info.plist et choisissez la tranche arm64 / arm64e dans tout binaire gras présent.Frameworks/*.framework + *.dylib sont chargés comme leur propre artefact natif, avec les mêmes vues Vue d'ensemble + désassemblage par section que pour les fichiers .so Android.__objc_classlist — classes, catégories, méthodes, ivars, propriétés — avec noms démasqués (mangling Swift _TtC... hérité inclus) et sauts cliquables depuis les adresses de méthodes vers le listing.__swift5_types — classes, structures, énumérations avec leurs champs et (pour les classes) les vtables, également cliquables vers le listing.Android — APK / DEX / natif
.so natifs sous lib/<abi>/ sont chargés par ABI ; AArch64 (arm64-v8a) et ARMv7 (armeabi-v7a) obtiennent tous deux des vues de désassemblage complètes. Les autres ABI (x86 / x86_64) sont routées vers la vue hexadécimale jusqu'à ce qu'un décodeur soit disponible.Édition
r1 n'affiche que les variantes ARMv7 ; w0 n'affiche que l'AArch64.AArch64 natif (ELF + thin Mach-O)
.eh_frame et des entrées <name>@plt synthétisées. Démangling C++/Rust/Swift via symbolic-demangle.adrp + add/ldr sont résolues vers des cibles de données, y compris les littéraux de chaînes affichés en ligne sous forme de commentaires.ARMv7 natif (ELF)
00 00), les Thumb-2 32 bits et A32 en affichent 4..eh_frame et entrées <name>@plt synthétisées (stubs de 12 octets).movw + movt : movw R, #lo16 ; movt R, #hi16 est détecté à travers les paires d'instructions et la constante 32 bits résolue reçoit un commentaire ; "..." de chaîne rodata sur la ligne movt.ldr Rt, [pc, #imm] déréférencent un niveau dans rodata pour le même type de commentaire de chaîne en ligne que le chemin ADRP+ADD d'AArch64 produit.UI
change me trouve changeMessage et change_me_count mais pas dispatchMenuVisibilityChanged).arm64-v8a + armeabi-v7a obtiennent des résultats unifiés avec l'artefact + la section étiquetés pour chaque correspondance.embedded.mobileprovision.resources.arsc).r0, lsl #2) et la mémoire pré/post-indexée ([rN, #imm]!, [rN], #imm) sont analysés mais uniquement de manière concrète — pas de jokers entre crochets.Glass fonctionne sur macOS 13+ (la cible principale, accélérée GPU via Metal — aucun SDK supplémentaire requis, le framework Metal est fourni avec le système), Linux (X11 ou Wayland via gpui_linux, support Vulkan) et Windows 10/11 (support Direct3D via gpui, compilé avec la chaîne d'outils MSVC).
Il existe un binaire précompilé pour macOS dans Releases mais si vous devez compiler depuis les sources : la bonne nouvelle : deux commandes suffisent.
Cela installe libxkbcommon-dev, les en-têtes Wayland et XCB, Vulkan, ALSA, ainsi que le reste de la chaîne d'outils dont gpui_linux a besoin pour lier. Sans eux, la compilation échoue à l'édition de liens avec des symboles xkbcommon / wayland-client manquants.
Si vous préférez ne pas exécuter le script, les paquets équivalents sur Debian / Ubuntu (amd64) sont : ```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
La compilation échoue tôt dans un script de construction de dépendance (`fontconfig was not found in the pkg-config search path`) si `libfontconfig-dev` est manquant, puis plus tard à l'édition de liens pour les bibliothèques X11/Wayland/Vulkan. `libglib2.0-dev` est nécessaire car le pilote Frida lie GLib dynamiquement sous Linux (sur macOS, le devkit Frida l'inclut statiquement) — sans lui, l'édition de liens échoue avec `undefined symbol: g_object_unref`.
**Windows uniquement — installer la chaîne d'outils de compilation native.** `gpui` nécessite la chaîne d'outils MSVC (la cible GNU/MinGW n'est pas prise en charge). Avec [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
L'installateur de LLVM ne s'ajoute pas à PATH, pointez donc bindgen vers libclang.dll avant de compiler (définissez-la de manière permanente via Système → Variables d'environnement, ou par session shell) : ```powershell
$env:LIBCLANG_PATH = "C:\Program Files\LLVM\bin"
Sans ces éléments, la compilation échoue dans les scripts de compilation des dépendances : `linker 'link.exe' not found` (pas de MSVC), `failed to spawn 'cmake'` (pas de CMake), ou `Unable to find libclang` (pas de `LIBCLANG_PATH`). La réserve de pile du binaire `glass` est augmentée automatiquement sur MSVC (voir `crates/glass-cli/build.rs`) afin que la CLI ne fasse pas déborder la petite pile du thread principal par défaut de Windows — aucune action requise.
3. **Cloner et compiler**: ```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>
The first build will compile gpui and friends and will take several minutes. Subsequent builds are fast.
La première compilation compilera gpui et consorts et prendra plusieurs minutes. Les compilations suivantes sont rapides.
Lancez-le : ```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
Utilisez toujours la version release — les versions de débogage désassemblent des ordres de grandeur plus lentement.
.appPour envelopper le binaire release dans un bundle Glass.app afin de le lancer en double-cliquant depuis Finder :```sh cargo build --release -p glass-cli ./packaging/make-app.sh open dist/Glass.app
Le bundle est signé ad hoc (non signé avec Developer-ID / non notarisé), donc au premier lancement macOS refusera de l'ouvrir ; clic droit → **Ouvrir** pour contourner Gatekeeper une fois.
Deux façons d'obtenir un zip précompilé sans avoir à compiler localement :
- **Dernier `main`** — chaque push téléverse un `Glass-app-<sha>.zip` comme artefact de workflow conservé 14 jours. Récupérez-le depuis l'[onglet Actions](https://github.com/azw413/Glass/actions).
- **Version taguée** — pousser un tag `v*` (par ex. `v0.1.0`) déclenche le même workflow et publie également un `Glass-<tag>-macOS.zip` sur la [page Releases](https://github.com/azw413/Glass/releases) avec des notes de version générées automatiquement.
## Espace de travail
| Crate | Rôle |
|------------------|------------------------------------------------------------------|
| `glass-core` | Types partagés (`CodeKind`, ID) |
| `glass-arch-arm` | Désassemblage AArch64 + ARMv7, carte des symboles, synthèse PLT, démangling |
| `glass-arch-dex` | Façade DEX / smali sur `smali` |
| `glass-mobile` | Chargement de bundles APK + IPA, extraction des libs natives, manifeste |
| `glass-db` | Persistance adressée par contenu (redb) : bundles, onglets, paramètres |
| `glass-device` | Découverte d'appareils Android (adb) + iOS (usbmux) |
| `glass-api` | Verbes d'analyse (recherche, xrefs, CFG, modifications) partagés par CLI + MCP + GUI |
| `glass-ui` | Front-end `gpui` : arborescence, liste, hex, manifeste, palette |
| `glass-cli` | Inspecteur headless + lanceur GUI |
| `glass-mcp` | Serveur MCP exposant chaque verbe CLI comme un outil |
| `glass-script` | Runtime de plugins QuickJS (provisoire) |
## Feuille de route
- **iOS plus en profondeur** — Analyse des entitlements et de `embedded.mobileprovision`. (La passe de métadonnées ObjC `__objc_classlist` et Swift `__swift5_types` a été intégrée — voir `glass types` / `glass type`.)
- **x86 / x86_64** — Désassemblage pour les builds émulateur des fichiers `.so` Android.
- **Scripting interne** — Hôte de plugins QuickJS avec une API stable pour les passes d'analyse.
- **Avancé** — Reconstruction d'APK signés, downstream-shift sur les modifications en place ARMv7 (afin que les agrandissements 2→4 octets puissent s'insérer au-delà du code adjacent plutôt que d'être refusés).
redb ; le relancement rouvre là où vous vous étiez arrêté.