
Glass - a fast and free IDA Pro alternative
как прозрачный и гладкий
Быстрый, нативный, в первую очередь для мобильных приложений интерактивный дизассемблер. Духовный преемник IDA Pro для рабочего процесса реверс-инжиниринга Android / iOS, построенный вокруг:
smali для работы с APK / DEX / smaliarmv8-encode для AArch64 и ARMv7 (A32 / Thumb) — нативные .so, iOS Mach-Ogpui (Zed) для ускоренного GPU нативного интерфейсаredb для персистентности по содержимомуrquickjs для скриптовых плагинов (планируется)Лицензия: GPL-3.0-only (наследуется от smali).
Все мы пользовались IDA Pro — это отраслевой стандарт для реверсинга, за ним стоят годы плагинов, но он медленный, дорогой и устаревший. Glass на 100% написан на Rust с ускоренным GPU интерфейсом для плавного взаимодействия. Он также на 100% бесплатный и с открытым исходным кодом — пожалуйста, внесите свой вклад.
arm64-v8a и armeabi-v7a ищутся за один запрос). Грамматика байтовых шаблонов с маскированием и пропусками; грамматика типизированного ассемблера для AArch64 и ARMv7 с автодополнением с учётом архитектуры ISA.Обзор основных представлений — нажмите на любую миниатюру, чтобы увидеть её в полном размере.
Каждый анализ, выполняемый Glass в графическом интерфейсе, также доступен как команда CLI, выводящая структурированный JSON. Тот же самый бинарный файл glass является точкой входа для автоматизации — выберите подкоманду, и вы получите одноразовый, скриптуемый результат, идеально подходящий для конвейеров jq и 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
Передайте `--text` для человекочитаемого отображения, опустите для JSON.
Полная ссылка: **[docs/cli-api.md](https://github.com/azw413/glass/blob/HEAD/docs/cli-api.md)**.
Это означает, что вы можете скриптовать и автоматизировать типовые операции.
## Навыки и MCP
Каждая команда CLI также доступна в качестве инструмента через встроенный сервер MCP (Model Context Protocol), поэтому любой хост, поддерживающий MCP — Claude Desktop, Cursor, Zed, ваш собственный клиент — может напрямую управлять Glass для помощи в задачах реверс-инжиниринга.```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
Чтобы зарегистрироваться в Claude Desktop, добавьте Glass в ~/Library/Application Support/Claude/claude_desktop_config.json:```json
{
"mcpServers": {
"glass": { "command": "/usr/local/bin/glass", "args": ["mcp"] }
}
}
Затем модель может вызывать `inspect`, `symbols`, `disasm`, `cfg-of`, `dex-callers`, `search` и любую другую команду для любого бандла, на который вы её укажете. Результаты инструмента возвращаются в том же JSON-конверте, который вы получили бы из CLI.
## Поиск
Три взаимодополняющих движка, все доступные из одной палитры ⌘F в GUI и как команды CLI / MCP.
### Полнотекстовый поиск
Нечеткое сопоставление по всему бандлу между native символами, классами / методами / полями DEX и строковыми литералами в секциях кода и данных. Фильтрация в реальном времени по мере ввода; результаты направляются в соответствующее представление (листинг для нативных адресов, smali-просмотрщик для целей DEX, hex-представление для попаданий в данные). Индексы строятся в фоновом потоке после загрузки — индикатор прогресса показывает состояние.```sh
glass search ./app.apk onCreate # all things named like "onCreate"
glass search ./libfoo.so init --limit 20
Справочник CLI: search команда в docs/cli-api.md.
Движок поиска шаблонов на уровне байтов. Каждый атом — это 2-символьная шестнадцатеричная маска (c0, e?, ?f, ??) или пропуск (* = 0..32 байта, *(min..max) для явных границ). Совпадения не пересекают секции. В палитре GUI ⌘2 переключает в режим Binary; флажок Code only (по умолчанию включён) ограничивает сканирование текстовыми секциями, чтобы вы не тонули в потоке совпадений с данными при поиске определённой формы инструкции.```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'
Полная грамматика + рабочие примеры: [`docs/BinSearch.md`](https://github.com/azw413/glass/blob/HEAD/docs/BinSearch.md).
### Поиск инструкций
Напишите ассемблер, Glass компилирует его в байты. Последовательность, разделённая `;`, кодируется через [armv8-encode](https://github.com/azw413/armv8-encode) — **AArch64** (`mov w0, #1`, `adrp x1, *`) и **ARMv7** в обоих режимах (Thumb `mov r1, r7` / `bxeq lr` / `push {r4-r7, lr}` и A32). Любые подстановочные знаки преобразуются в маски битов операндов до того, как байтовый движок вступает в дело. Сканирование глобальное — каждый нативный артефакт в наборе получает правильные атомы ISA (Android-приложения с библиотеками как `arm64-v8a`, так и `armeabi-v7a` ищутся одним запросом).
Внутри режима Binary в графическом интерфейсе ⌘B переключает между грамматиками **Bytes** и **Asm**; выпадающий список автодополнения с поддержкой ISA показывает варианты, которые всё ещё соответствуют тому, что вы ввели — `r1` отфильтровывает кандидатов AArch64, `w0` отфильтровывает кандидаты ARMv7.
Подстановочные знаки:
| Токен | Значение |
|---|---|
| `*` | любой операнд (вид определяется по выбранному opcode) |
| `#*` | любое непосредственное значение (подсказка для выбора opcode) |
| `x`, `w` | любой регистр класса X или W в AArch64 |
| `r` | любой GPR ARMv7 (`r0..r15`, `sp`, `lr`, `pc`) |
| `<*>`, `<X>`, `<W>`, `<R>`, `<imm>` | эквиваленты в скобках, удобны для вложенности в другой синтаксис (`[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'
Ответ содержит bytes_hex с скомпилированной маской (например, 01/1f ?? ?? 90/9f для adrp x1, *), так что вы можете точно видеть, какие биты фиксированы, а какие — маскированы. Захваты (<name:kind>, ссылающиеся на тот же операнд позже в шаблоне) спроектированы, но ещё не реализованы.
Полный дизайн + этапы: docs/InsnPattern.md. Справочник CLI/MCP: insn-search в docs/cli-api.md.
Glass уже сегодня можно использовать для реверс-инжиниринга Android (APK / DEX / нативные .so) и iOS (IPA / Mach-O) приложений, нацеленных на AArch64 и 32-битный ARMv7 (armeabi-v7a библиотеки, A32 + Thumb).
Загрузка файлов
.apk, .aab), iOS-пакеты (.ipa) или любой отдельный ELF / Mach-O бинарник (.so, .dylib, сырые исполняемые файлы) напрямую — Glass автоматически определяет формат.arm64e, обычный arm64 — запасной вариант. Работает как с пакетами, так и с отдельными файлами (например, glass gui /usr/lib/dyld).libfoo.so, поставляемый в двух APK (или тот же libswiftCore.dylib в двух IPA), разделяет состояние анализа.smali).iOS — IPA / Mach-O
Payload/*.app/, парсит Info.plist и выбирает срез arm64 / arm64e из любого жирного бинарника внутри.Frameworks/*.framework + *.dylib загружаются как собственный нативный артефакт с теми же представлениями Обзора и посекционной дизассемблировки, что и для Android .so файлов.__objc_classlist — классы, категории, методы, ivars, свойства — с демангированными именами (включая устаревшее Swift-манглирование _TtC...) и кликабельными переходами от адресов методов к листингу.__swift5_types — классы, структуры, перечисления с их полями и (для классов) vtable, также кликабельные в листинг.Android — APK / DEX / нативный код
.so файлы из lib/<abi>/ загружаются для каждой ABI; AArch64 (arm64-v8a) и ARMv7 (armeabi-v7a) получают полные представления дизассемблировки. Другие ABI (x86 / x86_64) направляются в hex-представление, пока не появится декодер.Редактирование
r1 показывает только варианты ARMv7; w0 — только AArch64.Нативный AArch64 (ELF + тонкий Mach-O)
.eh_frame FDE и синтезированных записей <name>@plt. Деманплинг C++/Rust/Swift через symbolic-demangle.adrp + add/ldr разрешаются в целевые данные, включая строковые литералы, показанные инлайн в комментариях.Нативный ARMv7 (ELF)
00 00), Thumb-2 32 бит и A32 — 4 байта..eh_frame и синтезированные записи <name>@plt (12-байтовые заглушки).movw + movt: movw R, #lo16 ; movt R, #hi16 обнаруживается через пары инструкций, и разрешённая 32-битная константа получает комментарий ; "..." со строкой из rodata на строке movt.ldr Rt, [pc, #imm] разыменовывают один уровень в rodata для того же типа инлайн-строкового комментария, который даёт путь ADRP+ADD в AArch64.Интерфейс
change me находит changeMessage и change_me_count, но не dispatchMenuVisibilityChanged).arm64-v8a + armeabi-v7a получают единые результаты с меткой артефакта + секции на каждое совпадение.embedded.mobileprovision.resources.arsc).r0, lsl #2) и pre/post-index память ([rN, #imm]!, [rN], #imm) парсятся, но только конкретно — нет масок внутри скобок.Glass работает на macOS 13+ (основная цель, ускорение GPU через Metal — не требуется дополнительных SDK, Metal-фреймворк поставляется с ОС), Linux (X11 или Wayland через gpui_linux, Vulkan-бэкенд) и Windows 10/11 (Direct3D-бэкенд через gpui, сборка с помощью инструментария MSVC).
В разделе Releases есть предварительно собранный бинарник для macOS, но если вам нужно собрать из исходников: хорошая новость — всего две команды.
Это подтягивает libxkbcommon-dev, заголовки Wayland и XCB, Vulkan, ALSA и остальную часть тулчейна, необходимого для линковки gpui_linux. Без них сборка завершается ошибкой на этапе линковки с отсутствующими символами xkbcommon / wayland-client.
Если вы предпочитаете не запускать скрипт, эквивалентные пакеты на 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
Сборка завершается ошибкой на раннем этапе в скрипте сборки зависимости (`fontconfig was not found in the pkg-config search path`), если отсутствует `libfontconfig-dev`, а также на этапе компоновки для библиотек X11/Wayland/Vulkan. `libglib2.0-dev` необходим, потому что драйвер Frida динамически компонуется с GLib в Linux (на macOS devkit Frida включает его статически) — без него компоновка завершается ошибкой `undefined symbol: g_object_unref`.
**Только для Windows — установите нативный набор инструментов сборки.** `gpui` требует инструментарий MSVC (цель GNU/MinGW не поддерживается). Использование [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
Установщик LLVM не добавляет себя в PATH, поэтому укажите bindgen на libclang.dll перед сборкой (постоянно через Система → Переменные среды или для текущей оболочки): ```powershell
$env:LIBCLANG_PATH = "C:\Program Files\LLVM\bin"
Без них сборка завершается ошибкой в сценариях зависимостей: `linker 'link.exe' not found` (нет MSVC), `failed to spawn 'cmake'` (нет CMake), или `Unable to find libclang` (нет `LIBCLANG_PATH`). Резерв стека бинарника `glass` автоматически увеличивается в MSVC (см. `crates/glass-cli/build.rs`), чтобы CLI не переполнял маленький стек основного потока Windows по умолчанию — никаких действий не требуется.
3. **Клонирование и сборка**: ```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>
Первая сборка скомпилирует gpui и зависимые компоненты и займет несколько минут. Последующие сборки быстрые.
Запустите его: ```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
Всегда используйте релизную сборку — отладочные сборки дизассемблируются на порядки медленнее.
.appЧтобы поместить релизный бинарник в bundle Glass.app для запуска двойным щелчком из Finder:```sh cargo build --release -p glass-cli ./packaging/make-app.sh open dist/Glass.app
Пакет подписан ad-hoc (не подписан Developer-ID / не нотаризован), поэтому при первом запуске macOS откажется его открывать; щелкните правой кнопкой мыши → **Открыть**, чтобы однократно обойти Gatekeeper.
Два способа получить предварительно собранный zip-архив без локальной сборки:
- **Последний `main`** — каждый push загружает `Glass-app-<sha>.zip` как артефакт рабочего процесса, хранящийся 14 дней. Скачайте его со вкладки [Actions](https://github.com/azw413/Glass/actions).
- **Теговая версия** — отправка тега `v*` (например, `v0.1.0`) запускает тот же рабочий процесс и дополнительно публикует `Glass-<tag>-macOS.zip` на странице [Releases](https://github.com/azw413/Glass/releases) с автоматически сгенерированными заметками о выпуске.
## Рабочее пространство
| Crate | Purpose |
|------------------|------------------------------------------------------------------|
| `glass-core` | Общие типы (`CodeKind`, идентификаторы) |
| `glass-arch-arm` | Дисассемблирование AArch64 + ARMv7, карта символов, синтез PLT, деманплинг |
| `glass-arch-dex` | Фасад DEX / smali поверх `smali` |
| `glass-mobile` | Загрузка пакетов APK + IPA, извлечение нативных библиотек, манифест |
| `glass-db` | Персистентность на основе адресации содержимого (redb): пакеты, вкладки, настройки |
| `glass-device` | Обнаружение устройств Android (adb) + iOS (usbmux) |
| `glass-api` | Глаголы анализа (поиск, перекрестные ссылки, CFG, правки), общие для CLI + MCP + GUI |
| `glass-ui` | Фронтенд `gpui`: дерево, листинг, hex, манифест, палитра |
| `glass-cli` | Безголовый инспектор + лаунчер GUI |
| `glass-mcp` | MCP-сервер, предоставляющий каждую команду CLI как инструмент |
| `glass-script` | Среда выполнения плагинов QuickJS (заглушка) |
## План развития
- **iOS глубже** — Разбор прав (Entitlements) и `embedded.mobileprovision`. (Проходы метаданных ObjC `__objc_classlist` и Swift `__swift5_types` реализованы — см. `glass types` / `glass type`.)
- **x86 / x86_64** — Дизассемблирование для эмуляторных сборок файлов `.so` Android.
- **Внутреннее скриптинг** — Хост плагинов QuickJS со стабильным API для проходов анализа.
- **Расширенное** — Пересборка подписанных APK, смещение вниз по потоку при правках на месте на ARMv7 (чтобы увеличение 2→4 байт могло встраиваться за соседним кодом, а не отказываться).
redb