
Glass - a fast and free IDA Pro alternative
투명하고 매끄러운 유리처럼
빠르고, 네이티브하며, 모바일 앱 우선인 대화형 디스어셈블러입니다. Android/iOS 리버스 엔지니어링 워크플로를 위한 IDA Pro의 정신적 후속작으로, 다음을 기반으로 구축되었습니다:
smali - APK / DEX / smali 처리armv8-encode - AArch64 및 ARMv7 (A32 / Thumb) — 네이티브 .so, iOS Mach-Ogpui (Zed) - GPU 가속 네이티브 UIredb - 콘텐츠 주소 지정 영속성rquickjs - 스크립트 가능 플러그인 (계획 중)라이선스: GPL-3.0-only (smali에서 상속).
우리 모두 IDA Pro를 사용해봤습니다 — 리버싱의 업계 표준이며 수년간의 플러그인이 있지만, 느리고 비싸며 구식입니다. Glass는 100% Rust 네이티브이며 GPU 가속 UI로 부드러운 상호작용을 제공합니다. 또한 100% 무료 오픈 소스입니다 — 기여해주세요.
arm64-v8a 및 armeabi-v7a 복사본이 하나의 쿼리로 검색됨). 마스킹 + 갭이 있는 바이트 패턴 문법; AArch64 및 ARMv7용 타입 어셈블리 문법, ISA 인식 자동완성 드롭다운 제공주요 뷰 둘러보기 — 축소판을 클릭하면 전체 크기로 볼 수 있습니다.
Glass가 GUI에서 수행하는 모든 분석은 구조화된 JSON을 출력하는 CLI 동사로도 노출됩니다. 동일한 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
Pass `--text` for a human-readable rendering, omit it for JSON.
Full reference: **[docs/cli-api.md](https://github.com/azw413/glass/blob/HEAD/docs/cli-api.md)**.
즉, 일반적인 작업을 스크립팅하고 자동화할 수 있습니다.
## Skills 및 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"] }
}
}
The model can then call `inspect`, `symbols`, `disasm`, `cfg-of`, `dex-callers`, `search` and every other verb on any bundle you point it at. Tool results come back as the same JSON envelope you'd get from the CLI.
## Searching
Three complementary engines, all available from the same ⌘F palette in the GUI and as CLI / MCP verbs.
### Full text search
Bundle-wide fuzzy match across native symbols, DEX classes / methods / fields, and string literals in code and data sections. Live-filtered as you type; results dispatch to the right view (listing for native addresses, smali viewer for DEX targets, hex view for data hits). Indices build on a background thread after load — a progress chip shows while in flight.```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문자 16진수 마스크(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의 Binary 모드에서 ⌘B는 **Bytes**와 **Asm** 문법 사이를 전환합니다. ISA를 인식하는 자동 완성 드롭다운은 입력한 내용과 여전히 일치하는 변형을 표시합니다 — `r1`은 AArch64 후보를 필터링하고, `w0`는 ARMv7 후보를 필터링합니다.
와일드카드:
| 토큰 | 의미 |
|---|---|
| `*` | 모든 피연산자 (선택된 opcode에서 종류 추론) |
| `#*` | 모든 즉시값 (opcode 선택기에 힌트) |
| `x`, `w` | 모든 AArch64 X 또는 W 클래스 레지스터 |
| `r` | 모든 ARMv7 GPR (`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'
응답에는 컴파일된 마스크(예: adrp x1, *의 경우 01/1f ?? ?? 90/9f)를 보여주는 bytes_hex가 포함되어 있어 고정된 비트와 와일드카드 처리된 비트를 정확히 볼 수 있습니다. 캡처(<name:kind>가 패턴에서 나중에 동일한 피연산자를 상호 참조)는 설계되었지만 아직 구현되지 않았습니다.
전체 설계 + 단계: docs/InsnPattern.md. CLI/MCP 참조: insn-search in docs/cli-api.md.
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를 파싱하고 내부의 모든 fat 바이너리에서 arm64 / arm64e 슬라이스를 선택합니다.Frameworks/*.framework + *.dylib는 자체 네이티브 아티팩트로 로드되며, Android .so 파일에 사용된 것과 동일한 개요 + 섹션별 디스어셈블리 뷰를 사용합니다.__objc_classlist에서 가져온 Objective-C 클래스 브라우저 — 클래스, 카테고리, 메서드, ivar, 프로퍼티 — 디맹글된 이름(레거시 _TtC... Swift 맹글링 포함)과 메서드 주소에서 목록으로의 클릭 가능한 점프를 제공합니다.__swift5_types에서 가져온 Swift 타입 브라우저 — 클래스, 구조체, 열거형과 해당 필드 및 (클래스의 경우) vtable, 또한 목록으로 클릭 가능합니다.Android — APK / DEX / 네이티브
lib/<abi>/ 아래의 네이티브 .so 파일은 ABI별로 로드됩니다. AArch64(arm64-v8a) 및 ARMv7(armeabi-v7a) 모두 전체 디스어셈블리 뷰를 얻습니다. 다른 ABI(x86 / x86_64)는 디코더가 제공될 때까지 16진수 뷰로 전달됩니다.편집
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] 리터럴 풀 로드는 AArch64의 ADRP+ADD 경로가 생성하는 것과 동일한 종류의 인라인 문자열 주석을 위해 rodata로 한 수준 역참조합니다.UI
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 프레임워크는 OS와 함께 제공됨), 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
빌드는 의존성 빌드 스크립트에서 일찍 실패합니다 (`fontconfig was not found in the pkg-config search path`) — 만약 `libfontconfig-dev`가 누락된 경우, 그리고 나중에 X11/Wayland/Vulkan 라이브러리에 대한 링크 시간에 실패합니다. `libglib2.0-dev`가 필요한 이유는 Frida 드라이버가 Linux에서 GLib을 동적으로 링크하기 때문입니다 (macOS에서는 Frida devkit이 정적으로 번들링합니다) — 이것 없이 링크하면 `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
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):
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 번들 패키징릴리스 바이너리를 Glass.app 번들로 감싸 Finder에서 더블 클릭으로 실행할 수 있게 하려면:```sh cargo build --release -p glass-cli ./packaging/make-app.sh open dist/Glass.app
번들은 임시 서명(Developer-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`이 자동 생성된 릴리스 노트와 함께 [릴리스 페이지](https://github.com/azw413/Glass/releases)에 게시됩니다.
## Workspace
| Crate | 용도 |
|------------------|------------------------------------------------------------------|
| `glass-core` | 공유 타입 (`CodeKind`, ID) |
| `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` | CLI + MCP + GUI에서 공유하는 분석 동사 (검색, 교차 참조, CFG, 편집) |
| `glass-ui` | `gpui` 프론트엔드: 트리, 목록, 헥스, 매니페스트, 팔레트 |
| `glass-cli` | 헤드리스 인스펙터 + GUI 런처 |
| `glass-mcp` | 모든 CLI 동사를 도구로 노출하는 MCP 서버 |
| `glass-script` | QuickJS 플러그인 런타임 (플레이스홀더) |
## Roadmap
- **iOS 심층 분석** — Entitlements 및 `embedded.mobileprovision` 파싱. (ObjC `__objc_classlist`와 Swift `__swift5_types` 메타데이터 패스가 추가되었습니다 — `glass types` / `glass type` 참조.)
- **x86 / x86_64** — Android `.so` 파일의 에뮬레이터 빌드를 위한 디스어셈블리.
- **내부 스크립팅** — 분석 패스를 위한 안정적인 API를 갖춘 QuickJS 플러그인 호스트.
- **고급** — 서명된 APK 재빌드, ARMv7 인플레이스 편집에서 다운스트림 시프트(2→4바이트 증가 시 인접 코드를 지나 스플라이스 가능, 거부하지 않음).
디스어셈블리 목록 색상 코딩된 피연산자, 제어 흐름 화살표, 인라인 확인된 문자열 리터럴 |
제어 흐름 그래프 함수별 CFG - 점선 조건부 에지 및 라우팅된 다중 순위 레인 |
DEX 호출 그래프 호버로 호출 수신 확장, 클릭하여 메서드의 smali로 이동 |
섹션 맵 개요 섹션 크기별 비례 막대, 클릭하여 목록/16진수 뷰로 이동 |