bauratynov/shrike

GitHub: bauratynov/shrike

一个用纯 C99 实现的极简 x86-64 ROP 工具链查找器,解决静态环境下轻量高效地枚举 ROP gadget 的问题。

Stars: 0 | Forks: 0

# shrike

shrike gadget list and density heatmap

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Language: C99](https://img.shields.io/badge/Language-C99-blue.svg)](https://en.wikipedia.org/wiki/C99) [![Platform: x86-64](https://img.shields.io/badge/Platform-x86__64-green.svg)](https://refspecs.linuxfoundation.org/elf/) 针对 x86-64 ELF64 二进制文件的极简 ROP 工具链查找器,使用纯 C99 从头实现。解析 ELF,遍历可执行的 PT_LOAD 段,使用小型表驱动解码器解码指令长度, 并枚举以返回指令结尾的工具链序列。 以伯劳鸟(一种鸣禽)命名——它们会将猎物刺在荆棘上以便稍后取用。很贴切。 ## 为什么 [ROPgadget](https://github.com/JonathanSalwan/ROPgadget) 已经存在且 非常优秀。它也是基于 Python 的,并且依赖项较多。 `shrike` 是你可以在静态二进制文件中部署到加固审计主机的工具——输出格式相同, 零运行时依赖,可在一个下午内审计。 它也与 [lbr-hunt](https://github.com/bauratynov/lbr-hunt) 天然配对:静态工具链枚举(shrike)+ 通过 Intel LBR 的 运行时链检测。 ## 设计 - **C99,无外部依赖**,仅依赖 `` / `` / ``。单一源码树,可从头到尾阅读。 - **边界检查的 ELF 加载器**。每个偏移量在解引用前都会针对文件大小进行验证。 拒绝格式错误的二进制文件,而不是解析后导致未定义行为。 - **表驱动长度解码器**。256 项主操作码映射、0x0F 两字节映射的分类器, 以及 3 字节 0x38 / 0x3A 映射的合理默认值。足以支持工具链枚举; 并非完整的反汇编器。 - **从终止指令向后遍历**。对于每个 `ret` / `retf` / `int` / `syscall` / `sysret` / 间接 `call` / 间接 `jmp` 字节, 尝试向后解码指令链;输出精确落在终止指令上的工具链序列。 ## 构建 ``` make ./shrike /bin/ls ``` ## 用法 ``` # 转储 /bin/ls 中的所有工具 ./shrike /bin/ls # 更长的工具,更宽的扫描,仅输出摘要 ./shrike --max-insn 8 --back 64 --quiet /bin/bash # 仅纯 RET 结尾的工具(跳过 syscall / int / indirect) ./shrike --no-syscall --no-int --no-ind /bin/ls # 搜索特定工具 ./shrike /bin/ls | grep 'pop rdi ; ret' ``` 示例输出: ``` # 文件: /bin/ls # 类型: ET_DYN 入口: 0x6ab0 片段: 2 # 片段[0]: vaddr=0x0000000000001000 字节=24288 0x000000000000108c: pop rbp ; ret 0x0000000000001290: pop rdi ; ret 0x0000000000001292: ret 0x000000000000218c: xor eax, eax ; ret ... shrike: 1284 gadgets emitted ``` ## 退出码 | 代码 | 含义 | |------|----------------------------------------| | 0 | 正常执行 | | 1 | 运行时错误(无法读取文件、mmap 失败) | | 2 | 调用错误 | ## 布局 ``` shrike/ ├── LICENSE / SECURITY.md / CHANGELOG.md ├── Makefile ├── include/{elf64,xdec,scan,format}.h ├── src/elf64.c # bounds-checked loader ├── src/xdec.c # x86-64 length decoder ├── src/scan.c # backward gadget scanner ├── src/format.c # mnemonic printer + hex fallback ├── src/main.c # CLI ├── tests/ │ ├── test_xdec.c # 40+ length-decoder unit cases │ ├── test_scan.c # scanner unit cases │ └── integration.sh # /bin/ls, /bin/bash, /bin/cat smoke ├── docs/hero.svg └── .github/workflows/ci.yml ``` ## 路线图 - [x] 第一阶段:ELF64 加载器 + CLI 骨架 - [x] 第二阶段:x86-64 长度解码器 + 单元测试 - [x] 第三阶段:工具链扫描器 + 助记符打印器 - [x] 第四阶段:CI + 集成测试 + v0.1.0 - [ ] 第五阶段:通过助记符哈希去重 + 过滤表达式 - [ ] 第六阶段:ARM64 支持(同级长度解码器) ## 配套工具 - [lbr-hunt](https://github.com/bauratynov/lbr-hunt) — 通过 Intel LBR 进行运行时 ROP 检测。静态枚举(shrike)+ 运行时检测(lbr-hunt)提供完整覆盖的缓解审计。 - [checkhard](https://github.com/bauratynov/checkhard) — ELF 加固审计器:PIE、NX、RELRO、栈保护、FORTIFY、RPATH、RWX。 ## 参考 - Shacham, H. *The Geometry of Innocent Flesh on the Bone: Return-into-libc without Function Calls (on the x86)*, CCS 2007 — 原始 ROP 论文。 - Intel® 64 and IA-32 Architectures Software Developer's Manual, 卷 2:指令集参考。 - [ROPgadget](https://github.com/JonathanSalwan/ROPgadget) — Python 参考实现,`shrike` 在范围上向其收敛。 ## 许可证 MIT — 参见 [LICENSE](LICENSE)。 ## 作者 **Baurzhan Atynov** — [bauratynov@gmail.com](mailto:bauratynov@gmail.com)
标签:C99, ELF, ROP, Wayback Machine, x86-64, 二进制分析, 云安全监控, 云安全运维, 云资产清单, 反汇编, 客户端加密, 嵌入式审计, 操作系统安全, 无依赖, 漏洞利用开发, 逆向工程, 静态分析