AFLplusplus / AFLplusplus

The fuzzer afl++ is afl with community patches, qemu 5.1 upgrade, collision-free coverage, enhanced laf-intel & redqueen, AFLfast++ power schedules, MOpt mutators, unicorn_mode, and a lot more!

Home Page:https://aflplus.plus

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

https://github.com/AFLplusplus/qemuafl/blob/40033af00c4c5de172ed4fe60c21b9edbd2c189d/linux-user/i386/cpu_loop.c#L216

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.

https://github.com/AFLplusplus/qemuafl/blob/40033af00c4c5de172ed4fe60c21b9edbd2c189d/linux-user/i386/cpu_loop.c#L216

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.