AFL源码分析计划1 -- afl-gcc.c

从main函数开始,可以看到主要就这三行

1
2
3
4
5
find_as(argv[0]);

edit_params(argc, argv);

execvp(cc_params[0], (char**)cc_params);

find_as

先讲一下as,编译的主要过程是“源代码”->“汇编代码”->“二进制”,而将汇编代码编译成二进制的工具,就是汇编器assembler。Linux系统常用的汇编器是as。

find_as找的就是这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
u8 *afl_path = getenv("AFL_PATH");
if (afl_path) {

tmp = alloc_printf("%s/as", afl_path);

if (!access(tmp, X_OK)) {
as_path = afl_path;
ck_free(tmp);
return;
}

ck_free(tmp);

}

获取环境变量AFL_PATH,如果存在,就验证指向as的路径是否正确,正确则赋值给变量as_path

1
2
3
4
if (!access(AFL_PATH "/as", X_OK)) {
as_path = AFL_PATH;
return;
}

如果AFL_PATH路径错误或者没有指定,这里会自动找到as并取得afl-as的路径

edit_params

1
cc_params = ck_alloc((argc + 128) * sizeof(u8*));

首先分配一块内存空间

接下来是一堆东西,根据argv配置环境变量等东西

1
2
3
4
if (!strcmp(cur, "-fsanitize=address") ||
!strcmp(cur, "-fsanitize=memory")) asan_set = 1;

if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;

往下看到这里,AFL可以选择使用sanitizer去更有效得查找memory access bugs,但是同时也会带来性能的下降

execvp

这里在源码加个for把参数cc_params打印出来

1
gcc note.c -o www -B /home/test/afl-2.52b -g -O3 -funroll-loops -D__AFL_COMPILER=1 -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1

-B 参数

1
-B <directory>           Add <directory> to the compiler's search paths

大概就是指定编译器,也就是说这里先把汇编码给了afl-as,插完桩后再传递给real as。

所以afl-gcc就是gcc的一个wraper,用来设置一下gcc的编译选项,还有把汇编器换成自己的afl-as

0%