Blues-star/revdb
GitHub: Blues-star/revdb
将 IDA 导出的分散逆向产物整合为带全文索引的 SQLite 数据库,提供高效的函数、字符串和调用关系查询能力。
Stars: 0 | Forks: 0
# revdb
`revdb` 是一个面向 **IDA 导出逆向产物** 的 **SQLite/FTS5** 数据库与查询工具。
它当前以 **`IDA-NO-MCP/INP.py`** 的导出结果作为主要输入契约,把函数、源码/反汇编、调用关系、字符串、导入导出符号、内存 hexdump 导入到单样本 SQLite 数据库中,并提供 **CLI** 与 **Python API** 查询能力。
## 这个项目解决什么问题
逆向导出目录通常由大量松散文件组成:
- `decompile/*.c`
- `disassembly/*.asm`
- `decompile_failed.txt`
- `decompile_skipped.txt`
- `strings.txt`
- `imports.txt` / `exports.txt`
- `memory/*.txt`
直接在文件系统里 grep、跳转、关联 callers / callees、按地址读取内存都不够顺手。`revdb` 的目标是把这些内容整理为一份**可重建、可检索、可脚本化查询**的 SQLite 数据库。
## 当前能力
- 导入 `decompile/*.c` 与 `disassembly/*.asm`
- 导入 `decompile_failed.txt` / `decompile_skipped.txt`
- 导入 `strings.txt` / `imports.txt` / `exports.txt`
- 导入 `memory/*.txt` 形式的 hexdump,并转成原始 `BLOB`
- 构建函数源码 / 反汇编与字符串的 **FTS5** 全文索引
- 提供 Typer CLI 与 Python 查询 API
- 提供 **IDA-NO-MCP 风格 mock 数据生成器**,方便在真实样本缺失时做开发、回归测试和演示
- 已用仓库本地的真实导出样本 `export-for-ai/` 验证核心导入流程
## 设计原则
- **单样本单库**:当前版本每个导出目录对应一个 SQLite 数据库
- **导入性能优先**:数据库是可重建产物,导入阶段优先吞吐,不强调崩溃恢复
- **查询友好**:优化地址查找、调用关系、源码搜索、字符串搜索、内存读取
- **原始 SQL**:使用 APSW + raw SQL,不引入 ORM
## 环境要求
- Python 3.11+
- SQLite 需支持 FTS5
- 建议使用 `uv`
安装开发环境:
uv sync --dev
## 快速开始
### 1)查看 CLI 帮助
uv run python ./src/revdb --help
或使用脚本入口:
uv run revdb --help
### 2)生成一份 mock 导出目录
uv run revdb mock-export ./.tmp/mock-export
可选参数示例:
uv run revdb mock-export ./.tmp/mock-export \
--decompile-count 6 \
--fallback-count 2 \
--failed-count 2 \
--skipped-count 1
生成结果会尽量贴近 `IDA-NO-MCP/INP.py` 的输出结构,包括:
- `decompile/`
- `disassembly/`
- `disassembly_fallback.txt`
- `decompile_failed.txt`
- `decompile_skipped.txt`
- `strings.txt`
- `imports.txt`
- `exports.txt`
- `memory/`
- `.export_progress`
- `function_index.txt`
- `pointers.txt`
### 3)导入 SQLite 数据库
uv run revdb scan
默认会显示基于 rich 的导入进度条;如果你只想看最终结果,可以关闭:
uv run revdb scan --no-progress
示例:
uv run revdb mock-export ./.tmp/mock-export
uv run revdb scan ./.tmp/mock-export ./.tmp/sample.db
### 4)执行常见查询
uv run revdb func 0x401000 --db ./.tmp/sample.db
uv run revdb name sub_401000 --db ./.tmp/sample.db
uv run revdb callers 0x402000 --db ./.tmp/sample.db
uv run revdb callees 0x403000 --db ./.tmp/sample.db
uv run revdb grep-code MockOpenFileMarker --db ./.tmp/sample.db
uv run revdb grep-string mock --db ./.tmp/sample.db
uv run revdb imports CreateFileW --db ./.tmp/sample.db
uv run revdb exports DllMain --db ./.tmp/sample.db
uv run revdb string 0x600000 --db ./.tmp/sample.db
uv run revdb mem 0x5FFFFC --size 6 --db ./.tmp/sample.db
## CLI 命令速查
| 命令 | 说明 |
| --- | --- |
| `scan` | 扫描导出目录并构建 SQLite 数据库 |
| `mock-export` | 生成一份符合 IDA-NO-MCP 风格的模拟导出目录 |
| `func` | 按地址查看函数详情与源码/反汇编 |
| `name` | 按函数名查找函数 |
| `callers` | 查看调用指定函数的上游函数 |
| `callees` | 查看指定函数调用的下游函数 |
| `grep-code` | 使用 FTS5 搜索源码或反汇编内容 |
| `grep-string` | 使用 FTS5 搜索字符串内容 |
| `imports` | 按名称查找 import 符号 |
| `exports` | 按名称查找 export 符号 |
| `string` | 按地址查看字符串记录 |
| `mem` | 按地址读取内存并输出十六进制字节 |
查看某个子命令的详细帮助:
uv run revdb scan --help
uv run revdb grep-code --help
## Python API
from revdb.query.repository import RevDbRepository
with RevDbRepository("sample.db") as repo:
function = repo.get_function(0x401000)
callers = repo.get_callers(0x402000)
callees = repo.get_callees(0x402000)
code_hits = repo.search_code("CreateFileW")
string_hits = repo.search_strings("http")
data = repo.read_memory(0x5FFFFC, 16)
常用接口包括:
- `get_function(addr, with_source=True)`
- `find_functions_by_name(name, limit=50)`
- `get_callers(addr, limit=1000)`
- `get_callees(addr, limit=1000)`
- `search_code(query, limit=50)`
- `search_strings(query, limit=50)`
- `get_imports_by_name(name)`
- `get_exports_by_name(name)`
- `get_string_by_addr(addr)`
- `read_memory(addr, size)`
## 当前已对齐的 `INP.py` 输出格式
### 1)`decompile/*.c` / `disassembly/*.asm`
支持读取如下元数据头:
/*
* func-name: sub_401000
* func-address: 0x401000
* export-type: decompile
* callers: 0x402000, 0x403000
* callees: 0x404000, 0x405000
* fallback-reason: decompilation failure: ...
*/
说明:
- `callers: none` / `callees: none` 会被识别为空列表
- `disassembly-fallback` 会作为可查询源码一并入库
- 回退原因会写入 `functions.reason`
- `source_file` 保存相对路径,如 `decompile/401000.c`、`disassembly/404000.asm`
### 2)`decompile_failed.txt` / `decompile_skipped.txt`
支持:
0x405000 | sub_405000 | mock failed reason
也兼容较宽松的旧格式解析。若某些问题记录没有合法地址,会进入 issue 记录而不是函数表。
### 3)`strings.txt`
支持:
0x600000 | 21 | ASCII | http://mock.local/api
0x600020 24 UTF-16 MockWideString
0x600030: fallback text
说明:
- 会优先按 `|` 分隔格式解析,再退回 tab / `addr: text` 格式
- 会保留字符串内容中的控制字符(例如 tab、vertical-tab),不会错误把它们当成新的记录行
### 4)`memory/*.txt`
支持 `INP.py` 的列式 hexdump:
00000000005FFFFC | 41 42 43 44 | ABCD
也兼容较简单的:
0x5FFFFC: 41 42 43 44
导入时会把十六进制文本解析为原始 bytes,并存入 `memory_chunks.data` 的 BLOB 字段,而不是把 hexdump 文本原样落库。
说明:
- `memory/` 文件名虽然是区间形式,但真实样本里不一定严格按 1MB 边界切分
- importer 会把同一 1MB 对齐 chunk 内来自多个文件的 memory 段合并后再写库,避免后写文件覆盖先前 chunk 数据
## 开发与验证
常用检查命令:
uv run pytest
uv run pytest --cov=src/revdb --cov-report=term-missing
uv run ruff check .
uv run mypy src
导入 benchmark:
uv run python scripts/bench_import.py ./export-for-ai --runs 1
可选参数:
uv run python scripts/bench_import.py ./export-for-ai \
--runs 3 \
--keep-db \
--progress
benchmark 会输出:
- 输入规模摘要
- 每次导入耗时
- 平均 phase timings
- 输出表行数
- 吞吐指标(functions/s、strings/s、MiB/s)
如果只想快速体验一遍流程:
uv run revdb mock-export ./.tmp/mock-export
uv run revdb scan ./.tmp/mock-export ./.tmp/sample.db
uv run revdb func 0x401000 --db ./.tmp/sample.db
## 当前限制
- 当前主要对齐 `IDA-NO-MCP/INP.py`,真实样本兼容性仍需要继续验证
- `pointers.txt` 尚未进入 schema / importer / query API
- 不提供增量更新与崩溃恢复;数据库默认视为可重建产物, 后续可能会更新api,支持增量更新与崩溃恢复
## 后续方向
- 用真实 `INP.py` 导出样本继续校正规则
- 引入多进程解析 + 单写入器优化导入吞吐
- 评估是否将 `pointers.txt` 纳入数据库 schema
- 支持函数体原地更新
- 支持函数名变更
标签:API查询, APSW, FTS5, Hexdump, IDA Pro, JARM, Python, SQLite, TLS抓取, Typer, URL提取, Wayback Machine, 二进制分析, 云安全监控, 云安全运维, 云资产清单, 代码示例, 全文检索, 内存分析, 反汇编, 反编译, 幻觉缓解, 恶意代码分析, 数据分析, 数据库工具, 数据管理, 无后门, 符号执行, 软件安全, 逆向工具, 逆向工程, 配置文件, 静态分析