本文转自捉迷藏博客
首先我们要知道afl首期出现是在linux的环境下的,依赖的是源码插桩与qemu进行的插桩,winafl的出现弥补了afl在win下的环境空缺,改动重写了一部分api函数以及把插桩库替换为了dynamorio 具体程序分析可以看winafl.c和afl-fuzz.c,我们下一章来对源码进行分析
我们先进行编译之后举个例子对x雷进行fuzz
环境
vs 2017 cmake git dynamorio-release-8 winafl源码
git clone https://github.com/googleprojectzero/winafl
之后我们进入vs 2017 交叉x64_86的兼容命令行下
32位编译
**mkdir build32
cd build32
cmake -G"Visual Studio 15 2017" -A Win32 .. -DDynamoRIO_DIR=..\path\to\DynamoRIO\cmake -DINTELPT=1
cmake --build . --config Release**
64位编译
**mkdir build64
cd build64
cmake -G"Visual Studio 15 2017" -A x64 .. -DDynamoRIO_DIR=..\path\to\DynamoRIO\cmake -DINTELPT=1
cmake --build . --config Release**
测试我们使用test.exe对winafl进行测试我们使用到的命令如下
afl-fuzz.exe -i input -o output -D C:\Users\fuzz\Desktop\dynamorio-cronbuild-8.0.18978\build_x64\bin64 -t 20000 -- -coverage_module test.exe -fuzz_iterations 5000 -target_module test.exe -target_offset 0x1200 -nargs 2 -- test.exe @@
-i 输入文件路径
-o 输出文件路径
-D dynamorio路径
-- 第一条分界线
-coverage_module 代码覆盖包含
-fuzz_iterations 迭代次数
-target_module 测试程序
-target_offset 测试函数偏移
-nargs 命令行打开参数(包括程序本身)
@@使用 input 文件内容进行输入
如下是效果图 测试的时候记得关闭地址随机化哦
举个粒子
#include <stdio.h>
#include <Windows.h>
#define ASSISTANTTOOLS_DLL "AssistantTools.dll"
extern "C" __declspec(dllexport) VOID fuzz_method(CHAR * filePath);
// AssistantTools.dll
static HMODULE hAssistantTools = NULL;
// AssistantTools!XL_ParseTorrentFileW
signed int __cdecl XL_ParseTorrentFileW(CHAR* aFileName, PVOID* a1);
using Fun_XL_ParseTorrentFileW = decltype(&XL_ParseTorrentFileW);
static Fun_XL_ParseTorrentFileW fun_XL_ParseTorrentFileW = NULL;
// AssistantTools!XL_ReleaseTorrentFileInfoW
void __cdecl XL_ReleaseTorrentFileInfoW(PVOID a1);
using Fun_XL_ReleaseTorrentFileInfoW = decltype(&XL_ReleaseTorrentFileInfoW);
static Fun_XL_ReleaseTorrentFileInfoW fun_XL_ReleaseTorrentFileInfoW = NULL;
VOID fuzz_method(CHAR* filePath)
{
PVOID a1 = NULL;
fun_XL_ParseTorrentFileW(filePath, &a1);
if (a1)
{
fun_XL_ReleaseTorrentFileInfoW(a1);
}
return;
}
int main(int argc, char* argv[])
{
CHAR assistantTools_path[MAX_PATH] = {0};
CHAR* pTemp = NULL;
if (2 != argc)
{
printf("Parameter Error\n");
goto End;
}
// 获取AssistantTools.dll的全路径
if(0 == GetModuleFileNameA(NULL, assistantTools_path, sizeof(assistantTools_path)))
{
printf("GetModuleFileNameA Error\n");
goto End;
}
pTemp = strrchr(assistantTools_path, '\\');
if(NULL == pTemp)
{
printf("strrchr Error\n");
goto End;
}
++pTemp;
*pTemp = '\0';
strcat(pTemp, ASSISTANTTOOLS_DLL);
// 加载AssistantTools.dll并获取函数地址
hAssistantTools = LoadLibraryA(assistantTools_path);
if (NULL == hAssistantTools)
{
printf("LoadLibraryA fail: 0x%x\n", GetLastError());
goto End;
}
fun_XL_ParseTorrentFileW = (Fun_XL_ParseTorrentFileW)GetProcAddress(hAssistantTools, "XL_ParseTorrentFileW");
if (NULL == fun_XL_ParseTorrentFileW)
{
printf("GetProcAddress fail\n");
goto End;
}
fun_XL_ReleaseTorrentFileInfoW = (Fun_XL_ReleaseTorrentFileInfoW)GetProcAddress(hAssistantTools, "XL_ReleaseTorrentFileInfoW");
if (NULL == fun_XL_ParseTorrentFileW)
{
printf("GetProcAddress fail\n");
goto End;
}
fuzz_method(argv[1]);
End:
if(hAssistantTools)
{
FreeLibrary(hAssistantTools);
}
return 0;
return 0;
}
针对逆向分析之后我们写出如上代码
使用命令为
afl-fuzz.exe -i input -M master -o "out" -D "D:\fuzz\dynamorio\build_Win32\bin32" -I 100000+ -t 9000 -- -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 5000 -nargs 2 -- "fuzz_program.exe" @@
链接:https://pan.baidu.com/s/1pnoF7dm40Nfl_b01bW9CRA
提取码:t3vj
我们得到的crash 一个是除0异常 一个是栈溢出
各位大佬可以用这个姿势继续fuzz