mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-05 23:01:33 +00:00
Add a test case to `test/test-qemu-mode.sh` and make sure that AFL_QEMU_PERSISTENT_EXITS loops correctly. This works only on platforms for which `afl-qemu-trace` detects exit signals and resets the program counter. This commit updates `test-instr.c` to optionally call `exit(n)` instead of returning n to the operating system. This option can be activated using the `EXIT_AT_END` flag. This way, we can test the QEMU persistent exit mode without having to add a new test file. You can compile and run `test-instr.c` with the exit mode like so: ```bash gcc -o exit -DEXIT_AT_END test-instr.c AFL_QEMU_DEBUG_MAPS= \ AFL_DEBUG= \ AFL_QEMU_PERSISTENT_ADDR=$(readelf -a exit | grep 'main$' | awk '{ printf "0x%s", $2 }') \ AFL_QEMU_PERSISTENT_GPR=1 \ AFL_QEMU_PERSISTENT_EXITS=1 \ ./afl-qemu-trace exit ``` Press enter repeatedly and you will see an output like this: ``` ... Debug: Sending status 0xc201ffff test-instr: Neither one or zero? How quaint! test-instr: Neither one or zero? How quaint! test-instr: Neither one or zero? How quaint! test-instr: Neither one or zero? How quaint! test-instr: Neither one or zero? How quaint! ``` To make sure that persistent exits are detected correctly on x86_64, I've made the following changes to qemuafl: ``` linux-user/i386/cpu_loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c index 4509f46b95..46bdbaf94a 100644 --- a/linux-user/i386/cpu_loop.c +++ b/linux-user/i386/cpu_loop.c @@ -235,7 +235,7 @@ void cpu_loop(CPUX86State *env) #ifndef TARGET_ABI32 case EXCP_SYSCALL: /* linux syscall from syscall instruction */ - if (afl_fork_child && persistent_exits && + if (persistent_exits && env->regs[R_EAX] == TARGET_NR_exit_group) { env->eip = afl_persistent_addr; continue; ```