libfuzzer: Functionality of coverage/feature feedback

Hello fellow developers,

I’m currently working on my master thesis with stateful fuzzing of server and embedded software as topic (Aflnet for example fuzzes server software. I’m looking for ways to extend and improve their approach).

I have some questions regarding the fuzzer runtime:

  1. If i understood the code correctly, there are multiple parts to the instrumentation: The PC tables, the 8 bit counters, and all the comparison hooks. I’m not quite sure what the difference between the pc tables and the 8 bit counters is. Shouldn’t the information of the pc table be contained in the 8 bit counters?
  2. For my planned addition i need to run the callback multiple times, and reset the coverage information (i.e. the pc tables and 8 bit counters?) before each execution, such that i get the coverage that the input produces on its own. Do you have any pointers, on where to change the fuzzer rt, or would i need to do some additional instrumentation (I’d like to avoid this, since each additional instrumentation pass would mean more code and thus more execution time) in order to not mess with the way the fuzzer works right now? The optimal case would be that there is one overarching pc table that has the information across runs, and one table that is reset before each run. After the run, the table is then merged into the main table. (I think afl does something like this?)
  3. Is there any functionality to set up the target and then fork from that initial state in order to avoid setting up the target each fuzz iteration, or is that not possible, since we are doing in-process fuzzing?

I’m looking forward to any input on this.

Best Regards,
Mark

Hi Mark Leon!

Hello fellow developers,

I’m currently working on my master thesis with stateful fuzzing of server and embedded software as topic (Aflnet for example fuzzes server software. I’m looking for ways to extend and improve their approach).

I have some questions regarding the fuzzer runtime:

  1. If i understood the code correctly, there are multiple parts to the instrumentation: The PC tables, the 8 bit counters, and all the comparison hooks. I’m not quite sure what the difference between the pc tables and the 8 bit counters is. Shouldn’t the information of the pc table be contained in the 8 bit counters?

pc table is a static (immutable) table that maps the 8 bit counters to the PCs.
8 bit counters are what is actually used to collect the coverage feedback.

  1. For my planned addition i need to run the callback multiple times, and reset the coverage information (i.e. the pc tables and 8 bit counters?) before each execution,

8 bit counters.
libFuzzer resets them after each iteration anyway.

  1. such that i get the coverage that the input produces on its own. Do you have any pointers, on where to change the fuzzer rt, or would i need to do some additional instrumentation (I’d like to avoid this, since each additional instrumentation pass would mean more code and thus more execution time) in order to not mess with the way the fuzzer works right now? The optimal case would be that there is one overarching pc table that has the information across runs, and one table that is reset before each run. After the run, the table is then merged into the main table. (I think afl does something like this?)

libFuzzer also works in a very similar way.
Check TracePC::CollectFeatures

  1. Is there any functionality to set up the target and then fork from that initial state in order to avoid setting up the target each fuzz iteration, or is that not possible, since we are doing in-process fuzzing?

Currently there is no such functionality in libFuzzer.
Someone recently posted a request to add such, but that’s all I know.
https://groups.google.com/g/libfuzzer/c/7co7dYuiFYk