Surendrajat/smali-lsp
GitHub: Surendrajat/smali-lsp
面向 Smali(Android Dalvik 字节码语言)的 LSP 和 MCP 服务器,为逆向工程和 AI 辅助分析提供高性能的代码导航与语义理解能力。
Stars: 3 | Forks: 0
# smali-lsp
一个针对 [Smali](https://github.com/google/smali)(Android 应用的字节码语言)的 Language Server Protocol (LSP) 服务器以及内置的 MCP 服务器。
## 功能
- **跳转到定义** — 从任意指令跳转到其目标(类、方法、字段、标签)
- **查找引用** — 支持继承感知的多态匹配的跨文件交叉引用
- **悬停提示** — 方法签名、字段类型、类信息、SDK 类检测
- **文档符号** — 包含方法和字段的类大纲
- **工作区符号** — 跨整个代码库的模糊搜索
- **诊断** — 语法错误和未解析的类引用
- **标签导航** — 方法内部的 goto/if-*/switch 目标
- **支持所有 41 种 Dalvik 指令类型**(invoke-*、iget/iput/sget/sput、new-instance、check-cast 等)
- **MCP 服务器** - 内置 MCP 服务器,为 AI 代理提供对反编译 APK 的全面语义理解。
## 性能
在真实 APK(119K 个 smali 文件,118K 个类,560K 个方法)上进行的测试:
| 操作 | 平均延迟 | 吞吐量 |
|-----------|-------------|------------|
| 跳转到定义 | 0.26ms | 4,011 ops/sec |
| 解析 / 索引 | ~0.3ms/文件 | ~3,300 文件/秒 |
| 查找引用 | <1s | — |
| 符号搜索 | <1s | — |
- 索引完成后,所有查询(定义、引用、符号、悬停)均在 <1s 内返回
- 99.7% 的跳转到定义覆盖率(在 30 万+个方法上测试)
- 在 10 万+个真实 smali 文件上达到 100% 的解析成功率
- 每个索引文件占用 18 KB 内存(字符串留驻)
- 索引 119K 个 smali 文件耗时约 30–36 秒(热启动),约 40 秒(冷启动)
- 索引 27K 个 smali 文件耗时约 6 秒
## 构建
需要 Java 17+ 和 Gradle 8.8+。
```
./gradlew shadowJar
```
输出:`build/libs/smali-lsp-all.jar`
## 使用
### LSP 服务器(用于 IDE)
该服务器在标准 LSP 协议中通过 **stdio** 通信 — 无守护进程,无端口,仅使用 stdio:
```
java -jar smali-lsp-all.jar
```
配置你的编辑器 LSP 客户端,使其针对 `.smali` 文件启动此命令。服务器将在启动时自动为工作区建立索引。
### MCP 服务器(用于 AI 代理)
```
java -jar smali-lsp-all.jar --mcp
```
作为 [MCP](https://modelcontextprotocol.io/) 服务器通过 stdio 运行,向 AI 代理(Claude、Cursor 等)暴露 smali 分析工具。
添加到你的 MCP 配置中(`.vscode/mcp.json`、`claude_desktop_config.json`、Cursor 设置等):
```
{
"mcpServers": {
"smali-mcp": {
"command": "java",
"args": ["-jar", "/path/to/smali-lsp-all.jar", "--mcp"]
}
}
}
```
## 架构
```
ANTLR4 Grammar → SmaliParser → ASTBuilder → WorkspaceIndex → LSP Providers
↑
WorkspaceScanner (parallel)
```
- **Parser**:带有 SLL 预测模式的 ANTLR4(smali 语法中没有歧义)
- **Index**:线程安全的 `ConcurrentHashMap`,具有 O(1) 查找复杂度和双向 class-URI 映射
- **Providers**:位置感知的符号提取 — 能够正确解析光标指向的同一行多个符号中的哪一个
- **Scanner**:并行文件处理,具有智能 APKTool 项目检测功能
## 运行测试
```
# 所有测试
./gradlew test
# 按类别
./gradlew test --tests "*.unit.*"
./gradlew test --tests "*.integration.*"
./gradlew test --tests "*.regression.*"
./gradlew test --tests "*.performance.*"
```
## 许可证
版权所有 (C) 2026 Surendrajat
本项目采用 [GNU General Public License v3.0](LICENSE) 进行许可,`src/main/antlr/` 目录下的文件除外,这些文件采用 MIT 许可证(详见各文件头)。
## 致谢
- 感谢 @psygate 提供 https://github.com/psygate/smali-antlr4-grammar
Neovim(通过 nvim-lspconfig)
``` local lspconfig = require('lspconfig') local configs = require('lspconfig.configs') if not configs.smali_lsp then configs.smali_lsp = { default_config = { cmd = { 'java', '-jar', '/path/to/smali-lsp-all.jar' }, filetypes = { 'smali' }, root_dir = function(fname) return lspconfig.util.root_pattern('AndroidManifest.xml', 'apktool.yml', '.git')(fname) end, }, } end lspconfig.smali_lsp.setup {} ```Helix
``` # ~/.config/helix/languages.toml [[language]] name = "smali" scope = "source.smali" file-types = ["smali"] language-servers = ["smali-lsp"] [language-server.smali-lsp] command = "java" args = ["-jar", "/path/to/smali-lsp-all.jar"] ```Emacs (eglot)
``` (with-eval-after-load 'eglot (add-to-list 'eglot-server-programs '(smali-mode . ("java" "-jar" "/path/to/smali-lsp-all.jar")))) ```VS Code(开发中)
扩展尚未发布。请将 MCP 服务器(见下文)用于 VS Code + AI 代理工作流。可用工具
`smali_index`、`smali_find_definition`、`smali_search_symbols`、`smali_get_stats`、`smali_find_references`、`smali_hover`、`smali_diagnostics`、`smali_document_symbols`标签:AI代理, APK分析, AST解析, Dalvik字节码, JS文件枚举, Language Server Protocol, LSP, MCP, Smali, URL提取, 云安全监控, 云资产清单, 代码导航, 反编译, 后台面板检测, 安卓, 目录枚举, 移动安全, 自动化分析, 跨站脚本, 逆向工程, 静态分析