Frida-Fuzzer是一款针对API的内存模糊测试框架,该工具的设计和开发灵感来源于AFL/AFL++,Frida-Fuzzer的当前版本支持在GNU/linux x86_64和Android x86——64平台上运行。
除此之外,你还使用下列命令安装Frida >= v12.8.1和frida-tools来对项目代码进行编译和使用该工具。
pip3 install -U frida
工具下载
广大研究人员可以使用下列命令将项目源码克隆至本地:
git clone https://github.com/andreafioraldi/frida-fuzzer.git
工具使用
在项目代码中,fuzz库必须导入至一个自定义Harness中,然后使用frida-compile进行编译并生成一个代理,随后Frida-Fuzzer会将生成的代理注入到目标应用程序之中。
Frida-Fuzzer的所有功能逻辑都在这个生成的代理之中,功能也全部由这个代理来实现。
前文所述的自定义Harness格式如下:
var fuzz = require("./fuzz");
var TARGET_MODULE = "test_linux64";
var TARGET_FUNCTION = DebugSymbol.fromName("target_func").address;;
var RET_TYPE = "void";
var ARGS_TYPES = ['pointer', 'int'];
var func_handle = new NativeFunction(TARGET_FUNCTION, RET_TYPE, ARGS_TYPES, { traps: 'all' });
fuzz.target_module = TARGET_MODULE; var payload_mem = Memory.alloc(fuzz.config.MAX_FILE);
fuzz.fuzzer_test_one_input = function (/* Uint8Array */ payload) {
Memory.writeByteArray(payload_mem, payload, payload.length);
func_handle(payload_mem, payload.length);
}
fuzz.fuzzer_test_one_input是必须要有的,如果你没有指定fuzz.target_module的话,所有的代码都将会被执行。
你还可以设置fuzz.manual_loop_start = true来告诉模糊测试器你将会在回调中调用fuzz.fuzzing_loop()。
fuzz.init_callback回调在设置之后,可以让模糊测试器在准备开始工作之后便执行代码,具体样例可以参考tests/test_java.js。
fuzz.dictionary是一个典型的模糊测试字典,其中包含了一个数组,你可以向其中添加数据对象,支持的类型有Array、ArrayBuffer、Uint8Array和String,它们都可以作为变异器的额外变异因子。具体样例可以参考tests/test_libxml2.js。
Frida-Fuzzer支持接收下列参数:
| -i FOLDER | 包含初始化种子的目录 |
|---|---|
| -o FOLDER | 包含中间种子和崩溃信息的输出目录 |
| -U | 连接USB |
| -spawn | 生成附加数据 |
| -script SCRIPT | 脚本文件名(默认为fuzzer-agent.js) |
如果你不指定输出目录的话,该工具将会在/tmp目录下创建一个临时文件夹。如果你不指定包含初始化种子的目录,该工具将会使用0000作为初始种子。
如果你是在对一个本地应用程序进行模糊测试的话,你可能需要在执行Frida-Fuzzer之前执行system-config来调整系统执行参数并优化任务执行。
运行下列命令之后,你将会在终端窗口中看到下列工具状态信息:
./frida-fuzzer -spawn ./tests/test_linux64

你还可以在fuzz/fuzzer.js中添加自定义步骤,并将其添加到fuzz/index.js的步骤列表中。
如需对模糊测试器进行自定义设置,可以编辑fuzz/config.js文件,此时你需要修改的变量为MAP_SIZE(可以降低代码大小以实现速度优化)、MAX_FILE(生成输入的最大大小)和QUEUE_CACHE_MAX_SIZE(增加队列缓存大小以实现速度提升)。
工具使用样例
比如说,我们要对一个样例Android应用程序的本地共享库进行测试,首先你需要确保已经在虚拟设备中实现了root:
host$ adb root
从该项目的Release页面下载Android x86_64 frida-server,然后将其拷贝到设备的/data/local/tmp目录下,这里可以使用adb push。
接下来,开启一个shell,并运行frida-server:
device# cd /data/local/tmp
device# ./frida-server
现在,安装测试应用程序tests/app-debug.apk,安装完成后运行App。
使用frida-compile编译代理脚本:
host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js
在模拟器中打开App。
使用下列命令对测试App中libnative-lib.so库的test_func函数进行测试:
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
测试样例和崩溃信息等输出结果都将保存在项目的output_folder中。
测试截图如下:

项目地址
Frida-Fuzzer:【GitHub传送门】

韩国 1F
要是能在Windows上跑就好了,现在只能干看着
新西兰 2F
frida-compile编译老失败,有人遇到过吗?
广东省东莞市 3F
感觉作者对AFL++理解挺深,这移植做得不简单
安徽省淮北市 B1
@ 咣当当 移植AFL++的思路确实巧,但hook开销没提,有点悬
台湾省桃园市 4F
之前搞逆向时用过Frida,这框架看着顺眼多了
上海市 5F
这个fuzz.manual_loop_start咋用?文档好像没说清楚
台湾省新北市 B1
@ 医者彭 手动循环要在回调里自己调fuzzing_loop,没啥魔法,直接在fuzz.init_callback里写就行。
福建省福州市 6F
又是x86_64限定,arm64啥时候能支持啊
日本 B1
@ 赛博机械师 arm64的支持还在roadmap里,估计下个大版本会加,等官方release再说。
福建省泉州市 7F
payload_mem那段代码我试了下,确实得小心内存越界
广东省汕头市 8F
frida-server在真机上老崩,是不是版本问题?
重庆市 B1
@ 幻光者 frida-server崩多半是版本不匹配,我换15.1.17稳了
韩国 9F
话说这个MAX_FILE改大会不会拖慢整体速度?
重庆市 B1
@ 星空观察员 MAX_FILE太大确实会让队列膨胀,我调到2M后跑速明显慢下来,建议酌情降。
四川省 B1
@ 星空观察员 改大了肯定慢啊,我试过MAX_FILE=1024直接卡成PPT
北京市 10F
这个框架看着挺爽的。
韩国 11F
我之前玩Frida,写脚本时总怕内存泄漏。
浙江省宁波市 12F
为什么不直接支持Windows?跨平台太鸡肋。
韩国 13F
装了frida-server老是崩,版本到底选哪个?
北京市 14F
文档里没提手动loop的坑,真是坑爹。
辽宁省抚顺市 15F
看到大家都在讨论x86_64,我反手给arm64写了个PR,顺便吐槽下维护太慢 😂
台湾省嘉义市 16F
我把fuzz.dictionary里加了几个常用URL,结果发现崩溃点竟然是字符拼接,感觉还挺意外的。
菲律宾 17F
这工具门槛有点高啊,Frida都还没整明白😂
越南 B1
@ 幽冥眼 有谁在真机上跑过吗,会不会直接卡死?
安徽省芜湖市鸠江区 18F
arm64支持啥时候来?x86_64都快淘汰了好吗
浙江省金华市 19F
payload_mem分配太小容易越界,我踩过这坑
上海市 20F
fuzz.dictionary加二进制数据会炸,有人试过吗?
韩国 21F
手动loop那块文档跟没写一样,纯靠猜🤔
上海市 22F
这玩意比直接用AFL++还难上手,新手劝退
印度尼西亚 23F
Windows用户只能围观,泪目😭
山东省德州市 24F
frida-compile老报错“Cannot find module”,路径到底咋配?
广东省 25F
安卓要root才能跑?门槛不低啊。
广东省广州市 26F
啥时候能支持Mac啊,M1芯片完全没法用
北京市 27F
这个脚本示例里的TARGET_FUNCTION是怎么确定的?
日本 28F
测试截图加载不出来,是我的问题吗🤔
上海市金山区 29F
看了半天还是没懂怎么配置初始化种子
上海市浦东新区 30F
依赖frida版本还挺新的,得先升级一下才能试。
浙江省金华市 31F
之前用AFL++搞过类似的东西,这个上手确实快一些
湖南省常德市石门县 32F
那如果是arm架构的Android设备呢?
日本 33F
配置部分看着有点绕,得多试几次。
韩国 B1
@ RippleFur 多跑几次就顺了