This is an extension to issue #2 - I found out where the loss of coverage is.
There seems to be a logic bug that sometimes results in a basic block not being instrumented when it should.
In the following example the if (argc < 2) { BASIC_BLOCK } basic block is not instrumented.
Note that is has to be compiled with AFL_DONT_OPTIMIZE:
AFL_DONT_OPTIMIZE=1 MARKSET=1 afl-clang-fast -o bug bug.c
#include <stdio.h>
#include <stdlib.h>
void foo(int a) {
printf("foo\n");
if (a == 1)
printf("1\n");
else
printf("2\n");
printf("done\n");
}
void bar() {
printf("bar\n");
}
int main(int argc, char *argv[]) {
printf("main\n");
if (argc < 2) {
printf("argc<2\n"); // *This is not instrumented*
return -1;
} else if (argc > 2)
printf("argc>2\n");
else
printf("argc=2\n");
printf("ok\n");
if (argv[1][0] == 'a')
foo(atoi(argv[1]));
else
bar();
printf("end\n");
return 0;
}
The disassembly looks like this:
Dump of assembler code for function main:
0x0000000000401320 <+0>: push rbp
0x0000000000401321 <+1>: mov rbp,rsp
0x0000000000401324 <+4>: sub rsp,0x20
0x0000000000401328 <+8>: mov DWORD PTR [rbp-0x4],0x0
0x000000000040132f <+15>: mov DWORD PTR [rbp-0x8],edi
0x0000000000401332 <+18>: mov QWORD PTR [rbp-0x10],rsi
0x0000000000401336 <+22>: movabs rdi,0x402017
0x0000000000401340 <+32>: mov al,0x0
0x0000000000401342 <+34>: call 0x401080 <printf@plt>
0x0000000000401347 <+39>: cmp DWORD PTR [rbp-0x8],0x2
0x000000000040134b <+43>: jge 0x40136e <main+78>
-> HERE begins the non-instrumented basic block
0x0000000000401351 <+49>: movabs rdi,0x40201d
0x000000000040135b <+59>: mov al,0x0
0x000000000040135d <+61>: call 0x401080 <printf@plt>
0x0000000000401362 <+66>: mov DWORD PTR [rbp-0x4],0xffffffff
0x0000000000401369 <+73>: jmp 0x401482 <main+354>
-> HERE it jumps to the end
Decompiled in Ghidra it looks like this:
int main(uint param_1,char** param_2) {
// remove variable declarations
printf("main\n");
if ((int)param_1 < 2) {
printf("argc<2\n");
local_c = 0xffffffff;
} else {
...
}
return (ulong)local_c;
}
This is an extension to issue #2 - I found out where the loss of coverage is.
There seems to be a logic bug that sometimes results in a basic block not being instrumented when it should.
In the following example the
if (argc < 2) { BASIC_BLOCK }basic block is not instrumented.Note that is has to be compiled with AFL_DONT_OPTIMIZE:
AFL_DONT_OPTIMIZE=1 MARKSET=1 afl-clang-fast -o bug bug.cThe disassembly looks like this:
Decompiled in Ghidra it looks like this: