afl源码阅读之afl-showmap

看过afl-fuzz的源码,之后再看afl-showmap,很多代码都是copy过去的

main函数

首先还是参数解析

-o:指定afl-showmap输出的文件名
-m:内存限制
-t:设置超时值
-e:就是只获取边,不用获取边的频率
-q:安静模式
-Z:安静模式,和cmin_mode置1,会影响输出文件的格式
-A:指定输入的文件,替代命令行的@@
-Q:qemu模式
-b:输出的是二进制格式,类似于afl-fuzz输出的out_dir/queue/fuzz_bitmap
-c:根据注释是Allow coredumps
-V:输出版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 配置共享内存
setup_shm();
// 设置一些信号的回调函数
setup_signal_handlers();
// 设置环境变量,ASAN_OPTIONS和MSAN_OPTIONS,还有根据AFL_PRELOAD设置LD_PRELOAD和DYLD_INSERT_LIBRARIES
set_up_environment();
// 查找binary,假如是绝对路径,就检测一下文件是否存在,是否可执行,否则就在PATH环境变量下查找binary
find_binary(argv[optind]);
// 非安静模式,输出banner和执行的binary路径
if (!quiet_mode) {
show_banner();
ACTF("Executing '%s'...\n", target_path);
}
// 假如参数中有@@,会将-A参数的testcase替换@@的位置
detect_file_args(argv + optind);

if (qemu_mode)
// 假如是qemu模式,构建qemu的参数,运行的命令替换成`afl-qemu-trace -- target_path`
use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind);
else
use_argv = argv + optind;
// fork一个子进程去运行target,之后对trace_bits进行归一化处理(通过setitimer设置超时发出SIGALRM信号,会回调handle_timeout函数,将子进杀掉)
run_target(use_argv);
// 将结果写到-o指定的文件中,假如binary_mode,将trace_bits直接写到文件中,否则就是`fprintf(f, "%06u:%u\n", i, trace_bits[i]);`写到文件中
tcnt = write_results();

if (!quiet_mode) {

if (!tcnt) FATAL("No instrumentation detected" cRST);
OKF("Captured %u tuples in '%s'." cRST, tcnt, out_file);

}
// 退出
exit(child_crashed * 2 + child_timed_out);

实际结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/afl/afl-showmap -o mapfile ./testimage ./test/tests_61412.jpg
$ cat mapfile | more
000000:1
000230:2
000360:4
000473:1
000522:1
000686:1
000755:1
000774:1
001084:8
001188:4
001220:1
001370:1
001571:7
001880:1
001963:1
002199:1
002268:1
002419:2
002449:2
002781:1
003124:2
......
......
......
打赏专区