
Glass - a fast and free IDA Pro alternative
como em transparente e suave
Um desmontador interativo rápido, nativo e focado em aplicativos móveis. Sucessor espiritual do IDA Pro para o fluxo de trabalho de engenharia reversa em Android / iOS, construído em torno de:
smali para manipulação de APK / DEX / smaliarmv8-encode para AArch64 e ARMv7 (A32 / Thumb) — .so nativo, iOS Mach-Ogpui (Zed) para interface nativa acelerada por GPUredb para persistência endereçada por conteúdorquickjs para plugins com script (planejado)Licença: GPL-3.0-only (herdada do smali).
Todos nós já usamos o IDA Pro — é o padrão da indústria para engenharia reversa e tem anos de plugins, mas é lento, caro e desatualizado. O Glass é 100% nativo em Rust com uma interface acelerada por GPU para interação fluida. Também é 100% gratuito e de código aberto — contribua por favor.
arm64-v8a e armeabi-v7a de uma biblioteca são pesquisadas em uma única consulta). Gramática de padrão de bytes com máscara + lacunas; gramática de assembly tipada para AArch64 e ARMv7, com um menu suspenso de preenchimento automático ciente da ISA.Um passeio pelas principais visualizações — clique em qualquer miniatura para vê-la em tamanho real.
Cada análise que o Glass faz na GUI também é exposta como um verbo de CLI que emite JSON estruturado. O mesmo binário glass é o ponto de entrada de automação — escolha um subcomando e você obtém um resultado único e scriptável, perfeito para pipelines jq e 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
Passe `--text` para uma renderização legível por humanos, omita para JSON.
Referência completa: **[docs/cli-api.md](https://github.com/azw413/glass/blob/HEAD/docs/cli-api.md)**.
Isso significa que você pode programar e automatizar operações comuns.
## Habilidades e MCP
Cada verbo da CLI também é exposto como uma ferramenta através de um servidor MCP (Model Context Protocol) embutido, então qualquer host compatível com MCP — Claude Desktop, Cursor, Zed, seu próprio cliente — pode controlar o Glass diretamente para ajudar em tarefas de engenharia reversa.```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
Para se registar com Claude Desktop, adicione Glass a ~/Library/Application Support/Claude/claude_desktop_config.json:```json
{
"mcpServers": {
"glass": { "command": "/usr/local/bin/glass", "args": ["mcp"] }
}
}
O modelo pode então chamar `inspect`, `symbols`, `disasm`, `cfg-of`, `dex-callers`, `search` e todos os outros verbos em qualquer pacote para o qual você o apontar. Os resultados da ferramenta retornam no mesmo envelope JSON que você obteria da CLI.
## Pesquisa
Três mecanismos complementares, todos disponíveis na mesma paleta ⌘F na GUI e como verbos CLI / MCP.
### Pesquisa de texto completo
Correspondência difusa em todo o pacote em símbolos nativos, classes/métodos/campos DEX e literais de string em seções de código e dados. Filtrado ao vivo conforme você digita; os resultados são enviados para a visualização correta (listagem para endereços nativos, visualizador smali para alvos DEX, visualização hexadecimal para resultados de dados). Os índices são construídos em uma thread em segundo plano após o carregamento — um chip de progresso é exibido enquanto está em andamento.```sh
glass search ./app.apk onCreate # all things named like "onCreate"
glass search ./libfoo.so init --limit 20
Referência da CLI: search verbo em docs/cli-api.md.
Motor de padrões de nível de byte. Cada átomo é uma máscara hexadecimal de 2 caracteres (c0, e?, ?f, ??) ou uma lacuna (* = 0..=32 bytes, *(min..max) para limites explícitos). As correspondências não abrangem seções. Na paleta GUI, ⌘2 muda para o modo Binário; a caixa de seleção Somente código (ativada por padrão) restringe a varredura às seções de texto para que você não se afogue em resultados de dados ao procurar uma forma de instrução.```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'
Gramática completa + exemplos práticos: [`docs/BinSearch.md`](https://github.com/azw413/glass/blob/HEAD/docs/BinSearch.md).
### Busca de instruções
Escreva o assembly, Glass o compila para bytes. Uma sequência separada por `;` é codificada via [armv8-encode](https://github.com/azw413/armv8-encode) — **AArch64** (`mov w0, #1`, `adrp x1, *`) e **ARMv7** em ambos os modos (Thumb `mov r1, r7` / `bxeq lr` / `push {r4-r7, lr}` e A32). Quaisquer curingas são traduzidos para máscaras de bits do operando antes que o mecanismo de bytes assuma. A varredura é global — cada artefato nativo no pacote obtém os átomos da ISA correta (aplicativos Android com bibliotecas `arm64-v8a` e `armeabi-v7a` são pesquisados em uma única consulta).
No modo Binário na interface gráfica, ⌘B alterna entre as gramáticas **Bytes** e **Asm**; um menu suspenso de preenchimento automático ciente de ISA mostra variantes que ainda correspondem ao que você digitou — `r1` filtra candidatos AArch64, `w0` filtra os ARMv7.
Curingas:
| Token | Significado |
|---|---|
| `*` | qualquer operando (tipo inferido do opcode escolhido) |
| `#*` | qualquer imediato (dicas para o seletor de opcode) |
| `x`, `w` | qualquer registrador da classe X ou W do AArch64 |
| `r` | qualquer GPR do ARMv7 (`r0..r15`, `sp`, `lr`, `pc`) |
| `<*>`, `<X>`, `<W>`, `<R>`, `<imm>` | equivalentes entre colchetes, úteis aninhados em outra sintaxe (`[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'
A resposta carrega bytes_hex mostrando a máscara compilada (ex.: 01/1f ?? ?? 90/9f para adrp x1, *) para que você possa ver exatamente quais bits são fixos vs. curinga. Capturas (<name:kind> referenciando cruzadamente o mesmo operando mais adiante no padrão) estão projetadas mas ainda não implementadas.
Full design + phases: docs/InsnPattern.md. CLI/MCP reference: insn-search em docs/cli-api.md.
O Glass é utilizável hoje para engenharia reversa de aplicativos Android (APK / DEX / .so nativo) e iOS (IPA / Mach-O) direcionados a AArch64 e ARMv7 de 32 bits (bibliotecas armeabi-v7a, A32 + Thumb).
Carregamento de arquivos
.apk, .aab), bundles iOS (.ipa), ou qualquer binário ELF / Mach-O independente (.so, .dylib, executáveis brutos) diretamente — o Glass detecta automaticamente o formato.arm64e é preferido, arm64 simples é o fallback. Funciona em bundles e em arquivos independentes (ex.: glass gui /usr/lib/dyld).libfoo.so distribuído em dois APKs (ou o mesmo libswiftCore.dylib em dois IPAs) compartilha estado de análise.smali).iOS — IPA / Mach-O
Payload/*.app/, analise Info.plist e escolha a fatia arm64 / arm64e de qualquer binário gordo dentro.Frameworks/*.framework + *.dylib são carregados como seu próprio artefato nativo, com as mesmas visões de Visão Geral + desmontagem por seção usadas para arquivos .so Android.__objc_classlist — classes, categorias, métodos, ivars, propriedades — com nomes desembaralhados (incluindo a desorganização legada _TtC... do Swift) e saltos clicáveis dos endereços dos métodos para a listagem.__swift5_types — classes, structs, enums com seus campos e (para classes) vtables, também clicáveis para a listagem.Android — APK / DEX / nativo
.so nativos em lib/<abi>/ carregados por ABI; AArch64 (arm64-v8a) e ARMv7 (armeabi-v7a) ambos recebem visões completas de desmontagem. Outras ABIs (x86 / x86_64) são direcionadas para a visão hexadecimal até que um decodificador chegue.Edição
r1 mostra apenas variantes ARMv7; w0 mostra apenas AArch64.Nativo AArch64 (ELF + thin Mach-O)
.eh_frame e entradas <name>@plt sintetizadas. Desembaralhamento C++/Rust/Swift via symbolic-demangle.adrp + add/ldr resolvidos para destinos de dados, incluindo literais de string mostrados inline como comentários.Nativo ARMv7 (ELF)
00 00), Thumb-2 e A32 de 32 bits mostram 4..eh_frame e entradas <name>@plt sintetizadas (stubs de 12 bytes).movw + movt: movw R, #lo16 ; movt R, #hi16 é detectado entre pares de instruções e a constante de 32 bits resolvida recebe um comentário ; "..." de string rodata na linha movt.ldr Rt, [pc, #imm] desreferenciam um nível em rodata para o mesmo tipo de comentário inline de string que o caminho ADRP+ADD do AArch64 produz.IU
change me encontra changeMessage e change_me_count mas não dispatchMenuVisibilityChanged).arm64-v8a + armeabi-v7a obtêm resultados unificados com o artefato + seção rotulados por correspondência.embedded.mobileprovision.resources.arsc).r0, lsl #2) e memória pré/pós-índice ([rN, #imm]!, [rN], #imm) analisam mas apenas concretamente — sem curingas dentro de colchetes.O Glass roda em macOS 13+ (o alvo principal, acelerado por GPU via Metal — nenhum SDK extra necessário, o framework Metal vem com o SO), Linux (X11 ou Wayland via gpui_linux, com suporte Vulkan), e Windows 10/11 (com suporte Direct3D via gpui, compilado com a toolchain MSVC).
Há um binário pré-compilado para macOS na seção Releases, mas se você precisar compilar a partir do código fonte: a boa notícia: são dois comandos.
Este comando puxa as dependências libxkbcommon-dev, os cabeçalhos do Wayland e XCB, Vulkan, ALSA e o restante da cadeia de ferramentas que o gpui_linux precisa para linkar. Sem eles, a compilação falha no momento da linkagem com símbolos de xkbcommon / wayland-client ausentes.
Se preferir não executar o script, os pacotes equivalentes no Debian / Ubuntu (amd64) são: ```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
A compilação falha cedo em um script de compilação de dependência (`fontconfig was not found in the pkg-config search path`) se `libfontconfig-dev` estiver ausente, e mais tarde no tempo de linkagem para as bibliotecas X11/Wayland/Vulkan. `libglib2.0-dev` é necessário porque o driver Frida vincula GLib dinamicamente no Linux (no macOS o devkit do Frida o agrupa estaticamente) — sem ele a linkagem falha com `undefined symbol: g_object_unref`.
**Apenas Windows — instale o toolchain de compilação nativo.** `gpui` requer o toolchain MSVC (o alvo GNU/MinGW não é suportado). Usando [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
O instalador do LLVM não se adiciona ao PATH, então aponte bindgen para libclang.dll antes de compilar (defina permanentemente via Sistema → Variáveis de Ambiente, ou por shell): ```powershell
$env:LIBCLANG_PATH = "C:\Program Files\LLVM\bin"
Sem estes, a compilação falha nos scripts de dependência: `linker 'link.exe' not found` (sem MSVC), `failed to spawn 'cmake'` (sem CMake), ou `Unable to find libclang` (sem `LIBCLANG_PATH`). A reserva de pilha do binário `glass` é aumentada automaticamente no MSVC (veja `crates/glass-cli/build.rs`) para que o CLI não estoure a pequena pilha padrão da thread principal do Windows — nenhuma ação necessária.
3. **Clone e compile**: ```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>
A primeira compilação irá compilar gpui e dependências e levará vários minutos. As compilações subsequentes são rápidas.
Executar: ```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
Sempre use a compilação de lançamento — compilações de depuração desmontam ordens de magnitude mais lentamente.
.appPara envolver o binário de lançamento em um pacote Glass.app para inicialização com duplo clique a partir do Finder:```sh cargo build --release -p glass-cli ./packaging/make-app.sh open dist/Glass.app
O bundle é assinado ad-hoc (não assinado com Developer-ID / notarizado), então na primeira execução o macOS se recusará a abri-lo; clique com o botão direito → **Abrir** para contornar o Gatekeeper uma vez.
Duas maneiras de obter um zip pré-construído sem compilar localmente:
- **Último `main`** — cada push envia um `Glass-app-<sha>.zip` como artefato de workflow de 14 dias. Baixe-o da [aba Actions](https://github.com/azw413/Glass/actions).
- **Release com tag** — enviar uma tag `v*` (ex.: `v0.1.0`) aciona o mesmo workflow e adicionalmente publica um `Glass-<tag>-macOS.zip` na [página de Releases](https://github.com/azw413/Glass/releases) com notas de release geradas automaticamente.
## Espaço de Trabalho
| Crate | Propósito |
|------------------|------------------------------------------------------------------|
| `glass-core` | Tipos compartilhados (`CodeKind`, IDs) |
| `glass-arch-arm` | Desmontagem AArch64 + ARMv7, mapa de símbolos, síntese de PLT, desmangling |
| `glass-arch-dex` | Fachada DEX / smali sobre `smali` |
| `glass-mobile` | Carregamento de pacotes APK + IPA, extração de bibliotecas nativas, manifesto |
| `glass-db` | Persistência endereçada por conteúdo (redb): pacotes, abas, configurações |
| `glass-device` | Descoberta de dispositivo Android (adb) + iOS (usbmux) |
| `glass-api` | Verbos de análise (busca, referências cruzadas, CFG, edições) compartilhados por CLI + MCP + GUI |
| `glass-ui` | Front-end `gpui`: árvore, listagem, hex, manifesto, paleta |
| `glass-cli` | Inspetor headless + lançador da GUI |
| `glass-mcp` | Servidor MCP expondo cada verbo da CLI como uma ferramenta |
| `glass-script` | Runtime de plugin QuickJS (placeholder) |
## Roteiro
- **iOS mais profundo** — Análise de Entitlements e `embedded.mobileprovision`. (A passagem de metadados `__objc_classlist` do ObjC e `__swift5_types` do Swift já foram implementadas — veja `glass types` / `glass type`.)
- **x86 / x86_64** — Desmontagem para arquivos `.so` do Android compilados para emulador.
- **Scripts Internos** — Host de plugins QuickJS com uma API estável para passos de análise.
- **Avançado** — Reconstrução de APK assinado, deslocamento downstream em edições in-place no ARMv7 (para que crescimentos de 2→4 bytes possam passar por código adjacente em vez de recusar).
redb; reiniciar reabre onde você parou.