Confused about AFL_QEMU_PERSISTENT_EXITS
ChongChengAC opened this issue · comments
Hi community, I'm confused about qemu persistent mode, especially AFL_QEMU_PERSISTENT_EXITS. In qemu persistent mode doc, it states:
Persistent mode lets you fuzz your target persistently between two addresses - without forking for every fuzzing attempt.
And I think it is:
save_gpr();
save_mem();
while (__AFL_LOOP(AFL_QEMU_PERSISTENT_CNT)) { // START address assigned by AFL_QEMU_PERSISTENT_ADDR
if (AFL_QEMU_PERSISTENT_GPR)
restore_gpr();
if (AFL_QEMU_PERSISTENT_MEM)
restore_mem();
...
if (!AFL_QEMU_PERSISTENT_EXITS)
exit_group(); // confused, how can it continue looping after call exit_group()
} // treat RET as jump to START
The user can force QEMU to set the program counter to START instead of executing the exit_group syscall and exit the program.
In my case, my program runs at 15 exec/s with 97% stability with qemu persistent mode off. With AFL_QEMU_SNAPSHOT=0x...
, it runs with 70% stability. If I don't set AFL_QEMU_PERSISTENT_EXITS=1
, it runs at above 40 exec/s with 93% stability.
As I understand, exit_group
will terminate the thread and recycle resources the thread used, so stability returns to normal. My confusion lies in how it can fuzz "without forking" while using exit_group.
honestly I do not know, @andreafioraldi should but he might be busy currently
simply hooking exit_group and, when hit, restoring PC to START
@andreafioraldi as far as I understood it’s the qemuafl persistent implementation that calls exit, and the question is why is exit called when the feature is called persistent fuzzing.
simply hooking exit_group and, when hit, restoring PC to START
Thanks for your reply. Do you mean customizing (utilizing) exit_group to restore PC between kernel reclaiming resources and actually destroying threads?
No it's you target code that calls exit(). persistent exits just tells qemu to not call the actual syscall but to jump back to the start address.
No it's you target code that calls exit(). persistent exits just tells qemu to not call the actual syscall but to jump back to the start address.
So it's for the case where middle exit()
in a function (fuzzing body) should not exit actually but jump back to start address and continue (persistent) fuzzing.