Makeph/gravedigger
GitHub: Makeph/gravedigger
一个零依赖的 Rust 实现的 x86-64 离线反汇编器、模拟器和调试器,从原始字节层面手动解码指令并在自建软件 CPU 中执行。
Stars: 0 | Forks: 0
# 掘墓人
**从零开始的 x86-64 反汇编器和基于模拟器的调试器。没有 capstone,没有 objdump,也没有 ptrace —— 它手动解码机器码,并在自己的软件 CPU 中*运行*它。**
大多数调试器借来一具尸体:它们通过 OS 连接到一个实时进程
(`ptrace`,Windows 调试 API)并依赖像 capstone 这样的库来读取
字节。gravedigger 挖掘自己的坟墓。它从原始 opcodes 解码 x86-64,
自行解析 ELF 和 PE 容器,并在从零开始的模拟器中执行指令 ——
因此你可以单步执行、打断点并检查**任何** x86-64 二进制文件,
离线,在任何 OS 上,且具有**零依赖**。
```
$ gravedigger info ./a.out
format : Pe
arch : X86_64
entry : 0x140073550
sections:
name addr size flags
.text 0000000140001000 476160 x
.rdata 0000000140076000 130048
.data 0000000140096000 512 w
```
## 它的功能
- **以硬核方式反汇编** x86-64 —— legacy prefixes、REX、ModRM/SIB、
RIP 相对寻址、单字节和双字节(`0f`)opcode 映射 —— 并输出
整洁的 Intel 语法。
- **遵循控制流。** 递归下降从入口点和
每个函数符号遍历 calls 和 jumps,因此你得到的是真实的代码列表,
而不是那种会被数据和 padding 绊倒的线性扫描。
- **原生加载 ELF64 和 PE32+**(以及位于选定 base 地址的原始 shellcode blob)。
- **运行代码。** 手写的 CPU —— 16 个寄存器、具有正确算术/溢出/进位语义的 RFLAGS、
带有映射 stack 的分段地址空间 —— 逐一执行指令。
Calls 进行 push,rets 进行 pop,syscalls 作为停止事件出现。
绝对不会触及任何宿主进程。
- **交互式调试。** 断点、单步、继续、寄存器/内存/stack
检查、实时代码反汇编 —— 全部由模拟器驱动。
## 反汇编
```
$ gravedigger disasm ./a.out --entry main
main:
0000000140012110: 48 83 ec 28 sub rsp, 0x28
0000000140012114: 49 89 d0 mov r8, rdx
0000000140012117: 48 63 d1 movsxd rdx, ecx
000000014001211a: 48 8d 0d 8f ed ff ff lea rcx, [rip - 0x1271]
0000000140012121: 45 31 c9 xor r9d, r9d
0000000140012124: e8 97 17 00 00 call 0x1400138c0
```
原始机器码也可以:
```
$ gravedigger disasm shellcode.bin --raw --base 0x400000
```
## 调试
```
$ gravedigger debug ./a.out --entry main
gravedigger debugger -- 'help' for commands, 'q' to quit
=> 0000000140073550: 48 83 ec 28 sub rsp, 0x28
(grave) s
=> 0000000140073554: e8 77 02 00 00 call 0x1400737d0
(grave) s
=> 00000001400737d6: 48 8b ec mov rbp, rsp ; stepped INTO the call
(grave) stack 3
stack (rsp = 00007fffffffeec0):
00007fffffffeec0: 0000000000000000
00007fffffffeec8: 0000000140073559 <- return address, one past the call
00007fffffffeed0: 0000000000000000
```
stack 上的那个返回地址不是由 OS 打印的 —— 而是 gravedigger 的 CPU
在执行 `call` 时将其 push 进去的。
| 命令 | 作用 |
|--------------|-------------------------------------------------|
| `s [n]` | 单步执行 n 条指令(按 Enter 重复) |
| `c` | 继续执行直到断点 / halt / 顶层 `ret` |
| `b ` | 在 `0xADDR`、十进制地址或某个 symbol 处打断点 |
| `d ` | 删除断点 |
| `r` | 导出寄存器和 flags |
| `x [n]` | 检查内存 |
| `stack [n]` | 导出 stack |
| `dis [n]` | 从 `rip` 开始反汇编 |
## 构建
```
$ cargo build --release
$ cargo test # 12 tests: golden decode vectors + end-to-end emulation
```
零依赖。整个项目仅使用 `std` 和手动编写的表格。
## 它是如何组合起来的
```
bytes ──▶ x86::decode ──▶ Insn ──┬──▶ x86::fmt ──▶ Intel text
└──▶ emu::exec ──▶ CPU state / stops
file ──▶ loader (elf/pe/raw) ──▶ Program ──▶ analysis (recursive descent)
──▶ emu (mapped memory + stack)
──▶ dbg (interactive REPL)
```
请参阅 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) 了解完整的详细介绍。
## 限制
v0.1 涵盖了现代编译器实际生成的整数/标量子集:mov、
lea、完整的算术/逻辑指令集、mul/div、移位、cmov/setcc、push/pop、call、
ret、leave、条件跳转和间接跳转、movzx/movsx/movsxd、syscall。
尚不支持:SSE/AVX/x87,且 `cdqe`/`cqo` 假定为 64 位宽度。解码器遇到任何
未知的指令都会输出 `(bad)`,而不是盲目猜测。
## 许可证
MIT。请负责任地挖掘。
标签:ELF/PE解析, Rust, x86-64, 云资产清单, 反汇编器, 可视化界面, 安全头部检测, 网络流量审计, 逆向工程, 通知系统