
Glass - a fast and free IDA Pro alternative
如其名,透明而顺滑
一款快速、原生、移动应用优先的交互式反汇编器。它是针对 Android / iOS 逆向工程工作流程的 IDA Pro 的精神继承者,围绕以下组件构建:
smali 用于处理 APK / DEX / smaliarmv8-encode 用于 AArch64 和 ARMv7(A32 / Thumb)——原生 .so、iOS Mach-Ogpui(Zed)用于 GPU 加速的原生 UIredb 用于内容寻址持久化rquickjs 用于脚本化插件(计划中)许可证:GPL-3.0-only(继承自 smali)。
我们都用过 IDA Pro —— 它是逆向工程行业的标杆,拥有多年的插件积累,但它速度慢、价格昂贵且过时。Glass 完全使用 Rust 原生编写,并采用 GPU 加速的 UI 实现流畅交互。它也是 100% 免费且开源的 —— 欢迎贡献。
arm64-v8a 和 armeabi-v7a 两个版本的库会在一次查询中被搜索到)。支持带掩码和间隔的字节模式语法;支持 AArch64 和 ARMv7 的类型化汇编语法,并带有 ISA 感知的自动补全下拉菜单主要视图一览 —— 点击缩略图查看完整尺寸。
Glass 在 GUI 中执行的每一次分析也会作为 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(模型上下文协议)服务器作为工具公开,因此任何支持 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"] }
}
}
然后模型可以对任何你指定的包(bundle)调用`inspect`、`symbols`、`disasm`、`cfg-of`、`dex-callers`、`search`以及所有其他动词。工具结果以与CLI返回的相同JSON信封(envelope)格式返回。
## 搜索
三种互补的搜索引擎,均可在GUI的同一个⌘F面板中使用,也可作为CLI/MCP动词使用。
### 全文搜索
对整个包(bundle)进行模糊匹配,涵盖原生符号、DEX类/方法/字段以及代码和数据段中的字符串字面量。输入时实时过滤;结果将被分派到正确的视图(原生地址显示为列表,DEX目标显示为smali查看器,数据命中显示为十六进制视图)。索引在加载后在后台线程中构建——处理过程中会显示进度芯片。```sh
glass search ./app.apk onCreate # all things named like "onCreate"
glass search ./libfoo.so init --limit 20
CLI 参考:search verb in docs/cli-api.md
字节级模式引擎。每个原子是一个2字符十六进制掩码(c0,e?,?f,??)或一个间隔(* = 0..=32 字节,*(min..max) 用于显式范围)。匹配不会跨节。在 GUI 调色板中,⌘2 切换到二进制模式;仅代码 复选框(默认开启)将扫描限制在文本节,这样你在查找指令形状时不会被数据命中淹没。```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 的原子(同时包含 `arm64-v8a` 和 `armeabi-v7a` 库的 Android 应用可以在一次查询中搜索)。
在 GUI 的二进制模式下,⌘B 会在 **Bytes** 和 **Asm** 语法之间切换;一个感知 ISA 的自动补全下拉菜单会显示仍然匹配你输入内容的变体——`r1` 过滤掉 AArch64 候选,`w0` 过滤掉 ARMv7 候选。
通配符:
| 标记 | 含义 |
|---|---|
| `*` | 任意操作数(类型由所选操作码推断) |
| `#*` | 任意立即数(提示操作码选择器) |
| `x`, `w` | 任意 AArch64 X 类或 W 类寄存器 |
| `r` | 任意 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 来显示编译后的掩码(例如 adrp x1, * 对应的 01/1f ?? ?? 90/9f),这样你可以精确地看到哪些位是固定的,哪些是通配的。捕获(<name:kind> 用于后续在模式中交叉引用同一操作数)已设计但尚未实现。
完整设计 + 阶段划分:docs/InsnPattern.md。CLI/MCP 参考:docs/cli-api.md 中的 insn-search。
Glass 现在可用于逆向分析针对 AArch64 以及 32 位 ARMv7(armeabi-v7a 库,A32 + Thumb)的 Android(APK / DEX / 原生 .so)和 iOS(IPA / Mach-O)应用。
文件加载
.apk, .aab)、iOS 包(.ipa)或任何独立的 ELF / Mach-O 二进制文件(.so, .dylib, 原始可执行文件)—— Glass 自动检测格式。arm64e,普通 arm64 作为备选。适用于包和独立文件(例如 glass gui /usr/lib/dyld)。libfoo.so(或两个 IPA 中的同一 libswiftCore.dylib)共享分析状态。smali 解码的二进制 XML)。iOS — IPA / Mach-O
Payload/*.app/,解析 Info.plist,并从其中的任何胖二进制选择 arm64 / arm64e 切片。Frameworks/*.framework + *.dylib 都被加载为其自己的原生工件,并使用与 Android .so 文件相同的概览 + 每节反汇编视图。__objc_classlist——类、分类、方法、实例变量、属性——具有去混杂的名称(包括遗留的 _TtC... Swift 混杂),并且可以从方法地址点击跳转到列表。__swift5_types——类、结构体、枚举及其字段和(对于类)虚函数表,也可以点击跳转到列表。Android — APK / DEX / 原生
.so 文件位于 lib/<abi>/ 下,按 ABI 加载;AArch64(arm64-v8a)和 ARMv7(armeabi-v7a)都获得完整的反汇编视图。其他 ABI(x86 / x86_64)路由到十六进制视图,直到解码器实现。编辑
r1 仅显示 ARMv7 变体;w0 仅显示 AArch64。AArch64 原生(ELF + thin Mach-O)
.eh_frame FDE 以及合成的 <name>@plt 条目。通过 symbolic-demangle 进行 C++/Rust/Swift 去名称修饰。adrp + add/ldr 指令对解析到数据目标,包括内联显示为注释的字符串字面量。ARMv7 原生(ELF)
00 00 填充),32 位 Thumb-2 和 A32 显示 4 个字节。.eh_frame 以及合成的 <name>@plt 条目(12 字节存根)。movw + movt 融合:跨指令对检测到 movw R, #lo16 ; movt R, #hi16,解析后的 32 位常数在 movt 行上获得一个 ; "..." rodata 字符串注释。ldr Rt, [pc, #imm] 字面量池加载解引用一层进入 rodata,以产生与 AArch64 的 ADRP+ADD 路径相同类型的内联字符串注释。用户界面
change me 找到 changeMessage 和 change_me_count,但不会找到 dispatchMenuVisibilityChanged)。arm64-v8a + armeabi-v7a 的 Android 应用获得统一结果,每个匹配标记有工件 + 节。redb 中;重新启动时重新打开你上次离开的位置。embedded.mobileprovision 解析。resources.arsc 解析)。r0, lsl #2)和前后索引内存([rN, #imm]!、[rN], #imm)可以解析,但仅限具体形式——括号内不支持通配符。Glass 运行在 macOS 13+(主要目标,通过 Metal 进行 GPU 加速——无需额外 SDK,Metal 框架随操作系统一起提供)、Linux(通过 gpui_linux 的 X11 或 Wayland,Vulkan 后端)和 Windows 10/11(通过 gpui 的 Direct3D 后端,使用 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
The build fails early in a dependency build script (`fontconfig was not found in the pkg-config search path`) if `libfontconfig-dev` is missing, and later at link time for the X11/Wayland/Vulkan libraries. `libglib2.0-dev` is needed because the Frida driver links GLib dynamically on Linux (on macOS the Frida devkit bundles it statically) — without it the link fails with `undefined symbol: g_object_unref`.
**Windows only — install the native build toolchain.** `gpui` requires the MSVC toolchain (the GNU/MinGW target is not supported). Using [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
The LLVM installer does not add itself to PATH, so point bindgen at libclang.dll before building (set it permanently via System → Environment Variables, or per-shell): ```powershell
$env:LIBCLANG_PATH = "C:\Program Files\LLVM\bin"
Without these the build fails in dependency build scripts: `linker 'link.exe' not found` (没有 MSVC), `failed to spawn 'cmake'` (没有 CMake), or `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 包要将发布二进制文件包装到 Glass.app 包中,以便从 Finder 中双击启动:```sh cargo build --release -p glass-cli ./packaging/make-app.sh open dist/Glass.app
该捆绑包是即席签名的(未进行开发者 ID 签名/公证),因此首次启动时 macOS 会拒绝打开它;右键单击 → **打开** 可绕过 Gatekeeper 一次。
两种获取预构建 zip 的方式,无需本地构建:
- **最新的 `main` 分支**——每次推送都会上传一个 `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 | 目的 |
|------------------|------------------------------------------------------------------|
| `glass-core` | 共享类型(`CodeKind`、ID) |
| `glass-arch-arm` | AArch64 + ARMv7 反汇编、符号映射、PLT 合成、名称还原 |
| `glass-arch-dex` | 基于 `smali` 的 DEX / smali 外观层 |
| `glass-mobile` | APK + IPA 捆绑包加载、原生库提取、清单文件 |
| `glass-db` | 内容寻址持久化(redb):捆绑包、标签、设置 |
| `glass-device` | Android(adb)+ iOS(usbmux)设备发现 |
| `glass-api` | 分析动词(搜索、交叉引用、CFG、编辑),由 CLI + MCP + GUI 共享 |
| `glass-ui` | `gpui` 前端:树、列表、十六进制、清单、调色板 |
| `glass-cli` | 无头检查器 + GUI 启动器 |
| `glass-mcp` | MCP 服务器,将每个 CLI 动词暴露为一个工具 |
| `glass-script` | QuickJS 插件运行时(占位符) |
## 路线图
- **iOS 更深层次**——权限和 `embedded.mobileprovision` 解析。(ObjC `__objc_classlist` 和 Swift `__swift5_types` 元数据传递已完成——参见 `glass types` / `glass type`。)
- **x86 / x86_64**——针对 Android `.so` 文件的模拟器版本进行反汇编。
- **内部脚本**——QuickJS 插件主机,为分析传递提供稳定 API。
- **高级功能**——签名 APK 重建,ARMv7 原地编辑中的下游移位(使 2→4 字节增长可以绕过相邻代码拼接,而不是拒绝)。
反汇编列表 彩色操作数、控制流箭头、行内已解析的字符串字面量 |
控制流图 每个函数的 CFG,带有虚线条件边和路由的多层级通道 |
DEX 调用图 悬停展开被调用者,点击跳转到该方法的 smali |
节映射概览 按节大小比例显示条,点击跳转到列表/十六进制视图 |