对Tinylnst And Jackalope 初探
字数 2332 2025-08-23 18:31:24
TinyInst与Jackalope模糊测试工具使用指南
1. TinyInst简介
TinyInst是一个轻量级动态检测库(插桩工具),用于执行时代码覆盖率分析。与传统的DynamoRIO相比,TinyInst主打轻量级特性,支持多种架构:
- Windows (x86和x64)
- macOS (x64和arm64)
- Linux (x64和arm64)
- Android (ARM64)
1.1 编译TinyInst
在Windows上编译TinyInst的步骤:
mkdir build
cd build
cmake -G "Visual Studio 16 2019" -A x64 ..
cmake --build . --config Release
注意:64位编译的版本可以在32位目标上工作,因此可能不需要单独编译32位版本。
1.2 TinyInst基本使用
测试用例运行命令示例:
litecov.exe -instrument_module notepad.exe -coverage_file coverage.txt -- notepad.exe
2. TinyInst架构设计
TinyInst框架主要分为三个核心类:
- Debugger类:最底层的调试处理
- TinyInst类:继承自Debugger类,实现插桩功能
- LiteCov类:继承自TinyInst类,处理代码覆盖率
2.1 Debugger类关键功能
- Run():运行和控制程序
- Kill()/Continue():终止或继续调试处理
- OnModuleLoaded():模块加载时调用
- OnProcessCreated():目标进程创建或附加时调用
- HandleExceptionInternal():处理目标程序异常
- HandleTargetEnded():处理目标方法结束
- HandleDllLoadInternal():处理DLL加载
- DebugLoop():主调试循环
2.2 TinyInst类关键功能
- FixCrossModuleLinks():修复跨模块链接
- InitGlobalJumptable():初始化全局跳转表
- CommitCode():提交插桩代码到远程进程
- WritePointer():写入指针值到插桩代码
- WriteCode():写入插桩代码
- HandleBreakpoint():处理各种类型断点
- TranslateBasicBlockRecursive():递归翻译基本块
- TryExecuteInstrumented():尝试执行插桩代码
- InstrumentModule():核心插桩函数
2.3 LiteCov类关键功能
- OnModuleInstrumented():模块插桩后初始化覆盖率数据
- InstrumentBasicBlock()/InstrumentEdge():在基本块或边上插入覆盖率插桩
- EmitCoverageInstrumentation():插入覆盖率插桩指令
- CollectCoverage()/GetCoverage():收集和获取覆盖率
- CompareCoverage():比较覆盖率数据集
3. Jackalope简介
Jackalope是一个可定制的、分布式的、覆盖引导的模糊测试工具,专用于Windows/macOS的黑盒模糊测试。它默认包含TinyInst插桩工具和语法变异引擎。
3.1 编译Jackalope
Windows平台编译步骤:
cd Jackalope
git clone --recurse-submodules https://github.com/googleprojectzero/TinyInst.git
mkdir build
cd build
cmake -G "Visual Studio 16 2019" -A x64 ..
cmake --build . --config Release
编译后会生成fuzzer.exe和test.exe(测试程序)。
3.2 Jackalope基本使用
测试用例运行命令示例:
fuzzer.exe -in in -out out -t 1000 -delivery shmem -instrument_module test.exe -target_module test.exe -target_method fuzz -nargs 1 -iterations 10000 -persist -loop -cmp_coverage -- test.exe -m @@
常用参数说明:
-in:输入目录(样本集)-out:输出目录-t:超时时间(毫秒)-delivery:样本传送机制(file或shmem)-instrument_module:收集覆盖率的目标模块-target_module:目标模块-target_method:目标方法-nargs:参数数量-iterations:迭代次数-persist:持久化模式-loop:循环模式-cmp_coverage:使用比较覆盖
3.3 Jackalope核心组件
-
Fuzzer类:
- 跟踪语料库和覆盖范围
RunSampleAndGetCoverage():运行样本并获取覆盖率- 处理崩溃样本保存
-
Mutator类:
- 处理样本变异
SpliceMutator::Mutate():样本拼接变异
-
Instrumentation类:
- 处理目标运行和覆盖率收集
-
SampleDelivery类:
- 处理样本传递
FileSampleDelivery:文件方式传递SHMSampleDelivery:共享内存方式传递
3.4 自定义Fuzzer开发
可以通过继承Fuzzer类创建自定义模糊测试器:
class BinaryFuzzer : public Fuzzer {
public:
// 重写CreateMutator函数
std::unique_ptr<Mutator> CreateMutator() override;
// 重写TrackHotOffsets函数
bool TrackHotOffsets() override;
// 可选重写
std::unique_ptr<Instrumentation> CreateInstrumentation();
std::unique_ptr<PRNG> CreatePRNG();
};
4. 实战案例:GDI+库模糊测试
示例命令:
fuzzer.exe -in inGDI -out outGDI -t 1000 -delivery shmem -instrument_module gdiplus.dll -target_module ConsoleApplication9.exe -target_offset 0x1170 -target_method fuzz -nargs 1 -iterations 10000 -persist -loop -cmp_coverage -- ConsoleApplication9.exe -m @@
关键点:
- 需要准备高质量的初始语料库
- 针对目标模块(gdiplus.dll)进行插桩
- 指定目标偏移量(0x1170)
- 使用共享内存传递样本(-delivery shmem)
5. 高级技巧
-
MPEngine.dll模糊测试:
- 编写特定harness调用目标函数
- 优化语料库提高效率
- 持续监控和分析崩溃结果
-
性能优化:
- 调整迭代次数
- 优化样本传递机制
- 合理设置超时时间
-
覆盖率分析:
- 使用-cmp_coverage比较覆盖
- 分析热点代码路径
- 针对性优化变异策略
6. 总结
TinyInst和Jackalope组合提供了一个高效的模糊测试解决方案:
- TinyInst提供轻量级插桩能力,支持多平台
- Jackalope提供完整的模糊测试框架,易于扩展
- 组合使用可以快速构建针对特定目标的模糊测试环境
- 通过自定义开发可以适应各种复杂场景
相比传统的WinAFL,Jackalope在某些场景下更加便捷高效,但需要更多的实践来验证其在不同模块上的效果。