1. 模糊测试简介
模糊测试 (fuzz testing, fuzzing)是一种软件测试技术。其核心思想是将自动或半自动生成的随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。模糊测试常常用于检测软件或计算机系统的安全漏洞。
模糊测试通常被用于黑盒测试。其回报率通常比较高。当然,模糊测试只是相当于对系统的行为做了一个随机采样,所以在许多情况下通过了模糊测试只是说明软件可以处理异常以避免崩溃,而不能说明该软件的行为完全正确。这表明模糊测试更多是一种对整体质量的保证,并不能替代全面的测试或者形式化方法。作为一种粗略的可靠性度量方法,模糊测试可以提示程序哪些部件需要特殊的注意。对于这些部件可以进一步使用代码审计,静态分析以及代码重写。
模糊测试工具通常可以被分为两类。
- 变异测试通过改变已有的数据样本去生成测试数据。
- 生成测试则通过对程序输入的建模来生成新的测试数据。
最简单的模糊测试是通过命令行,网络包或者事件向一个程序输入一段随机比特流。这种技术目前依然是有效的发现程序错误的方法。另一个常见且易于实现的技术是通过随机反转一些比特或者整体移动一些数据块来变异已有的输入数据。但是,最有效的模糊测试需要能够理解被测试对象的格式或者协议。这可以通过阅读设计规格来实现。基于设计规格的模糊工具包含完整的规格,并通过基于模型的测试生成方法去遍历规格,并在数据内容,结构,消息,序列中引入一些异常。这种“聪明的”模糊测试也被称作健壮性测试,句法测试,语法测试以及错误注入。这种协议感知的特性也可以启发式的从例子中生成。相关的工具有Sequitur。
模糊测试也可以与其他技术结合。白盒模糊测试结合了符号执行技术与约束求解技术。演化模糊测试则利用了一个启发的反馈来有效的实现自动的探索性测试。
Android 构建系统通过从 LLVM 编译器基础架构项目纳入 libFuzzer 来支持模糊测试。LibFuzzer 与被测库相关联,并处理在模糊测试会话期间出现的所有输入选择、变更和崩溃报告。LLVM 的排错程序用于协助内存损坏检测以及提供代码覆盖率指标。
2. 编写模糊测试工具
为了说明如何在 Android 中使用 libFuzzer 编写端到端的模糊测试工具,请将以下易受攻击的代码作为测试用例。 这样做有助于对模糊测试工具进行测试,确保一切运行正常,并说明崩溃数据是什么样的。
下面是测试函数
#include <stdint.h>
#include <stddef.h>
bool FuzzMe(const char *Data, size_t DataSize) {
return DataSize >= 3 &&
Data[0] == 'F' &&
Data[1] == 'U' &&
Data[2] == 'Z' &&
Data[3] == 'Z'; // ← Out of bounds access
}
要编译并运行此模糊测试工具,请执行以下操作:
1.模糊测试目标包含两个文件:一个构建文件和模糊测试目标源代码,即源码和Android.bp文件。
2.使用 libFuzzer 编写模糊测试目标。模糊测试目标是一个函数,该函数可接收指定大小的 blob 数据,并将其传递给要接受模糊测试的函数。以下是针对易受攻击的测试函数的基本模糊测试工具:
#include <stddef.h>
#include <stdint.h>
extern "C" int LLVMFuzzerTestOneInput(const char *data, size_t size) {
// ...
// Use the data to call the library you are fuzzing.
// ...
return FuzzMe(data, size);
}
3.编译fuzzer二进制文件。在Android.bp中定义如下
cc_fuzz {
name: "fuzz_me_fuzzer",
srcs: [
"fuzz_me_fuzzer.cpp",
],
// If the fuzzer has a dependent library, uncomment the following section and
// include it.
// static_libs: [
// "libfoo", // Dependent library
// ],
//
// The advanced features below allow you to package your corpus and
// dictionary files during building. You can find more information about
// these features at:
// - Corpus: https://llvm.org/docs/LibFuzzer.html#corpus
// - Dictionaries: https://llvm.org/docs/LibFuzzer.html#dictionaries
// These features are not required for fuzzing, but are highly recommended
// to gain extra coverage.
// To include a corpus folder, uncomment the following line.
// corpus: ["corpus/*"],
// To include a dictionary, uncomment the following line.
// dictionary: "fuzz_me_fuzzer.dict",
}
4.如果在目标板上运行,使用下面的命令编译
SANITIZE_TARGET=hwaddress m fuzz_me_fuzzer
5.如果是在host机器上运行,使用下面的命令编译
SANITIZE_HOST=address m fuzz_me_fuzzer
方便起见,你可以在shelll变量中先定义好指向测试目标路径的变量(名字来自Android.bp,ps:只是为了下面运行的时候使用下)
export FUZZER_NAME=your_fuzz_target
编译之后,生成的编译好的fuzzer路径为
$ANDROID_PRODUCT_OUT/data/fuzz/$TARGET_ARCH/$FUZZER_NAME/$FUZZER_NAME for device
$ANDROID_HOST_OUT/fuzz/$TARGET_ARCH/$FUZZER_NAME/$FUZZER_NAME for host
4. 在主机上运行模糊测试工具
在host机器上运行还需要在Android.bp文件中包含如下属性
host_supported: true,
然后在用命令编译SANITIZE_HOST=address m fuzz_me_fuzzer
,生成的可执行文件路径为
$ANDROID_HOST_OUT/fuzz/x86_64/$FUZZER_NAME/$FUZZER_NAME
然后运行该文件,可看到下面的内容
user@user-600-G5:~/project$ ./out/host/linux-x86/fuzz/x86_64/fuzz_me_fuzzer/fuzz_me_fuzzer
INFO: Seed: 1250055691
INFO: Loaded 2 modules (17714 inline 8-bit counters): 17702 [0x7f6ac18913f0, 0x7f6ac1895916), 12 [0x5598c24b5ad8, 0x5598c24b5ae4),
INFO: Loaded 2 PC tables (17714 PCs): 17702 [0x7f6ac1895918,0x7f6ac18dab78), 12 [0x5598c24b5ae8,0x5598c24b5ba8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED cov: 2 ft: 2 corp: 1/1b exec/s: 0 rss: 28Mb
#16 NEW cov: 3 ft: 3 corp: 2/4b lim: 4 exec/s: 0 rss: 28Mb L: 3/3 MS: 4 ChangeBit-ChangeBit-InsertByte-InsertByte-
#4304 NEW cov: 4 ft: 4 corp: 3/7b lim: 43 exec/s: 0 rss: 28Mb L: 3/3 MS: 3 ChangeByte-EraseBytes-InsertByte-
#19688 NEW cov: 5 ft: 5 corp: 4/113b lim: 191 exec/s: 0 rss: 30Mb L: 106/106 MS: 4 EraseBytes-InsertByte-ChangeBinInt-InsertRepeatedBytes-
#19742 REDUCE cov: 5 ft: 5 corp: 4/62b lim: 191 exec/s: 0 rss: 30Mb L: 55/55 MS: 4 ShuffleBytes-InsertByte-ChangeBit-EraseBytes-
#19784 REDUCE cov: 5 ft: 5 corp: 4/41b lim: 191 exec/s: 0 rss: 30Mb L: 34/34 MS: 2 ShuffleBytes-EraseBytes-
#19830 REDUCE cov: 5 ft: 5 corp: 4/37b lim: 191 exec/s: 0 rss: 30Mb L: 30/30 MS: 1 EraseBytes-
#19857 REDUCE cov: 5 ft: 5 corp: 4/27b lim: 191 exec/s: 0 rss: 30Mb L: 20/20 MS: 2 ChangeBinInt-EraseBytes-
#19868 REDUCE cov: 5 ft: 5 corp: 4/24b lim: 191 exec/s: 0 rss: 30Mb L: 17/17 MS: 1 EraseBytes-
#19876 REDUCE cov: 5 ft: 5 corp: 4/21b lim: 191 exec/s: 0 rss: 30Mb L: 14/14 MS: 3 ChangeByte-ChangeBinInt-EraseBytes-
#19968 REDUCE cov: 5 ft: 5 corp: 4/19b lim: 191 exec/s: 0 rss: 30Mb L: 12/12 MS: 2 ChangeBinInt-EraseBytes-
#20129 REDUCE cov: 5 ft: 5 corp: 4/15b lim: 191 exec/s: 0 rss: 30Mb L: 8/8 MS: 1 EraseBytes-
#20146 REDUCE cov: 5 ft: 5 corp: 4/12b lim: 191 exec/s: 0 rss: 30Mb L: 5/5 MS: 2 ChangeByte-EraseBytes-
#20527 REDUCE cov: 5 ft: 5 corp: 4/11b lim: 191 exec/s: 0 rss: 30Mb L: 4/4 MS: 1 CrossOver-
#20748 REDUCE cov: 5 ft: 5 corp: 4/10b lim: 191 exec/s: 0 rss: 30Mb L: 3/3 MS: 1 EraseBytes-
#78010 REDUCE cov: 6 ft: 6 corp: 5/14b lim: 760 exec/s: 0 rss: 41Mb L: 4/4 MS: 2 InsertByte-ChangeBinInt-
=================================================================
==32332==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020001650d3 at pc 0x5598c241efff bp 0x7ffffec9ad10 sp 0x7ffffec9ad08
READ of size 1 at 0x6020001650d3 thread T0
#0 0x5598c241effe in FuzzMe(char const*, unsigned long) vendor/eswin/proprietary/tanxiaolong/libfuzzer_test/fuzz_me_fuzzer.cpp:9:3
#1 0x5598c241effe in LLVMFuzzerTestOneInput vendor/eswin/proprietary/tanxiaolong/libfuzzer_test/fuzz_me_fuzzer.cpp:17:9
#2 0x5598c2459573 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
#3 0x5598c2458cd5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:470:3
#4 0x5598c245b057 in fuzzer::Fuzzer::MutateAndTestOne() /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:698:19
#5 0x5598c245bd65 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:830:5
#6 0x5598c24498d0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:832:6
#7 0x5598c2474212 in main /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
#8 0x7f6ac0633bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310
#9 0x5598c2376728 in _start (/home/user/txl/project/LD60_pre/out/host/linux-x86/fuzz/x86_64/fuzz_me_fuzzer/fuzz_me_fuzzer+0x86728)
0x6020001650d3 is located 0 bytes to the right of 3-byte region [0x6020001650d0,0x6020001650d3)
allocated by thread T0 here:
#0 0x5598c23ee52d in malloc /out/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x5598c24332a7 in operator new(unsigned long) (/home/user/txl/project/LD60_pre/out/host/linux-x86/fuzz/x86_64/fuzz_me_fuzzer/fuzz_me_fuzzer+0x1432a7)
#2 0x5598c2458cd5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:470:3
#3 0x5598c245b057 in fuzzer::Fuzzer::MutateAndTestOne() /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:698:19
#4 0x5598c245bd65 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:830:5
#5 0x5598c24498d0 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:832:6
#6 0x5598c2474212 in main /out/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
#7 0x7f6ac0633bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310
SUMMARY: AddressSanitizer: heap-buffer-overflow
// 注意:这里第九行也就是代码出错的地方
vendor/eswin/proprietary/tanxiaolong/libfuzzer_test/fuzz_me_fuzzer.cpp:9:3 in FuzzMe(char const*, unsigned long)
Shadow bytes around the buggy address:
0x0c04800249c0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c04800249d0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c04800249e0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c04800249f0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c0480024a00: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x0c0480024a10: fa fa fd fa fa fa fd fa fa fa[03]fa fa fa fa fa
0x0c0480024a20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480024a30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480024a40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480024a50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480024a60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==32332==ABORTING
MS: 1 EraseBytes-; base unit: 8f2e64dfbc76edd9e0a40f4415ef8095d3dcfbe7
0x46,0x55,0x5a,
FUZ
artifact_prefix='./'; Test unit written to ./crash-0eb8e4ed029b774d80f2b66408203801cb982a60
Base64: RlVa
在示例输出中,崩溃是由第 9 行 fuzz_me_fuzzer.cpp 导致的:
Data[3] == 'Z'; // :(
如果数据长度为 3,会导致出界读取错误。
5. 在设备上运行模糊测试工具
使用命令'SANITIZE_TARGET=address m fuzz_me_fuzzer'编译
使用adb将编译出的文件复制到开发板上,使用下面的命令
adb root
adb sync data
然后在设备上直接运行即可
txl60_evb:/ # ./data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer
INFO: Seed: 1585887023
INFO: Loaded 2 modules (17746 inline 8-bit counters): 17740 [0xe9d42088, 0xe9d465d4), 6 [0x7ab9494, 0x7ab949a),
INFO: Loaded 2 PC tables (17746 PCs): 17740 [0xe9d465d4,0xe9d69034), 6 [0x7ab949c,0x7ab94cc),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED cov: 4 ft: 4 corp: 1/1b exec/s: 0 rss: 27Mb
#6 NEW cov: 5 ft: 5 corp: 2/5b lim: 4 exec/s: 0 rss: 27Mb L: 4/4 MS: 4 InsertByte-EraseBytes-ChangeASCIIInt-CrossOver-
#18 REDUCE cov: 5 ft: 5 corp: 2/4b lim: 4 exec/s: 0 rss: 27Mb L: 3/3 MS: 2 ChangeByte-EraseBytes-
#2471 REDUCE cov: 6 ft: 6 corp: 3/7b lim: 25 exec/s: 0 rss: 27Mb L: 3/3 MS: 3 ChangeByte-ChangeBit-ChangeByte-
#16217 NEW cov: 7 ft: 7 corp: 4/117b lim: 156 exec/s: 0 rss: 28Mb L: 110/110 MS: 1 InsertRepeatedBytes-
#16278 REDUCE cov: 7 ft: 7 corp: 4/104b lim: 156 exec/s: 0 rss: 28Mb L: 97/97 MS: 1 EraseBytes-
#16280 REDUCE cov: 7 ft: 7 corp: 4/57b lim: 156 exec/s: 0 rss: 28Mb L: 50/50 MS: 2 InsertByte-CrossOver-
#16299 REDUCE cov: 7 ft: 7 corp: 4/41b lim: 156 exec/s: 0 rss: 28Mb L: 34/34 MS: 4 ShuffleBytes-CMP-ShuffleBytes-EraseBytes- DE: "\x01\x00\x00\x00\x00\x00\x00\x00"-
#16335 REDUCE cov: 7 ft: 7 corp: 4/34b lim: 156 exec/s: 0 rss: 28Mb L: 27/27 MS: 1 EraseBytes-
#16401 REDUCE cov: 7 ft: 7 corp: 4/21b lim: 156 exec/s: 0 rss: 28Mb L: 14/14 MS: 1 EraseBytes-
#16488 REDUCE cov: 7 ft: 7 corp: 4/18b lim: 156 exec/s: 0 rss: 28Mb L: 11/11 MS: 2 CMP-EraseBytes- DE: "\xff\xff\xff\xff\xff\xff\xff\xff"-
#16519 REDUCE cov: 7 ft: 7 corp: 4/15b lim: 156 exec/s: 0 rss: 28Mb L: 8/8 MS: 1 EraseBytes-
#16710 REDUCE cov: 7 ft: 7 corp: 4/12b lim: 156 exec/s: 0 rss: 28Mb L: 5/5 MS: 1 EraseBytes-
#16771 REDUCE cov: 7 ft: 7 corp: 4/10b lim: 156 exec/s: 0 rss: 28Mb L: 3/3 MS: 1 EraseBytes-
=================================================================
==4807==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xc4f170f3 at pc 0x07a85671 bp 0xff9b6d68 sp 0xff9b6d64
READ of size 1 at 0xc4f170f3 thread T0
#0 0x7a8566e (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x966e)
#1 0x7a8afe0 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0xefe0)
#2 0x7a8a8cc (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0xe8cc)
#3 0x7a8c2b0 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x102b0)
#4 0x7a8cd7c (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x10d7c)
#5 0x7a9a9f4 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x1e9f4)
#6 0x7ab5318 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x39318)
#7 0xe9dce1dc (/data/fuzz/arm/lib/libc.so+0x331dc)
#8 0x7a85548 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x9548)
0xc4f170f3 is located 0 bytes to the right of 3-byte region [0xc4f170f0,0xc4f170f3)
allocated by thread T0 here:
#0 0xe9adb01c (/data/fuzz/arm/lib/libclang_rt.asan-arm-android.so+0xad01c)
#1 0x7a8aebc (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0xeebc)
#2 0x7a8a8cc (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0xe8cc)
#3 0x7a8c2b0 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x102b0)
#4 0x7a8cd7c (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x10d7c)
#5 0x7a9a9f4 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x1e9f4)
#6 0x7ab5318 (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x39318)
#7 0xe9dce1de (/data/fuzz/arm/lib/libc.so+0x331de)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/data/fuzz/arm/fuzz_me_fuzzer/fuzz_me_fuzzer+0x966e)
Shadow bytes around the buggy address:
0xe23aadc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0xe23aadd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0xe23aade0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0xe23aadf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0xe23aae00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0xe23aae10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[03]fa
0xe23aae20: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
0xe23aae30: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
0xe23aae40: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0xe23aae50: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0xe23aae60: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==4807==ABORTING
MS: 1 ChangeByte-; base unit: 9d447627131a2fa79c753457599a7adc3ef03146
0x46,0x55,0x5a,
FUZ
artifact_prefix='./'; Test unit written to ./crash-0eb8e4ed029b774d80f2b66408203801cb982a60
Base64: RlVa
Aborted (core dumped)
运行模糊测试工具结束后,输出常常会导致crash,而导致问题的输入会保存在语料库中,并提供一个ID。
如我在host机器上运行时,输出就保存在运行的当前目录中,名称为crash-0eb8e4ed029b774d80f2b66408203801cb982a60
,里边内容为
FUZ
要在在设备上进行模糊测试时检索崩溃信息,发出以下命令,指定您的崩溃 ID:
adb pull /data/fuzz/arm64/fuzz_me_fuzzer/corpus/CRASH_ID
请注意,如需将测试用例保存到正确目录,您可以使用正文文件夹(如上例所示)或使用 artifact_prefix 参数(例如 -artifact_prefix=/data/fuzz/where/my/crashes/go
)。
评论 (0)