googleprojectzero / winafl

A fork of AFL for fuzzing Windows binaries
Apache License 2.0
2.31k stars 530 forks source link

Inconsistent Execution of instrument_bb_coverage Function A #447

Open bluestar628 opened 3 weeks ago

bluestar628 commented 3 weeks ago

t appears that the instrument_bb_coverage function is not triggered every time a basic block is executed. I added the following code at the beginning of instrument_bb_coverage:

dr_fprintf(log_file, "bb called %d\n", bb_count);
bb_count++;
if (bb_count == 100000) bb_count = 0;

Upon reviewing the log_file, I noticed that the output increases rapidly when fuzzing begins. However, over time, it slows down and eventually stops at different points for different applications. Could you please help me understand why this might be happening?

Thank you for your assistance!

ifratric commented 3 weeks ago

That sounds correct. instrument_bb_coverage is not meant to run each time a basic block is executed, but rather each time a basic block is translated. In DR, my understanding is that this generally occurs the first time a basic block is executed. instrument_bb_coverage then writes assembly instructions to the basic block (using instrlist_meta_preinsert) and those assembly instructions are executed each time a basic block executes.

bluestar628 commented 3 weeks ago

That sounds correct. instrument_bb_coverage is not meant to run each time a basic block is executed, but rather each time a basic block is translated. In DR, my understanding is that this generally occurs the first time a basic block is executed. instrument_bb_coverage then writes assembly instructions to the basic block (using instrlist_meta_preinsert) and those assembly instructions are executed each time a basic block executes.

Thanks for your help! However, I also noticed some repeated addresses in the log file, though they don't appear too often. How should I understand this?

ifratric commented 3 weeks ago

Can you explain what you mean by "repeated addresses"? Addresses of basic blocks or something else and how/where are they logged?

bluestar628 commented 3 weeks ago

I added the following code at the beginning of instrument_bb_coverage, intending for the offset of each executed basic block to be logged in log_file (a file_t object initialized in dr_main).

dr_fprintf(log_file, "bb called %d\n", bb_count); bb_count++; if (bb_count == 100000) bb_count = 0;

However, over time, the log_file stops increasing. You explained that instrument_bb_coverage is only called the first time a block is translated, yet I observe some addresses appearing more than once. Why are these blocks translated multiple times? Thank you!

ifratric commented 3 weeks ago

If the target process restarts for any reason, code is going to need to be reinstrumented (during a fuzzing session this occurs if maximum number of persistent iterations has been reached, on crashes, hangs etc.) so translation will occur again. It's also possible that DynamoRIO sometimes translates basic blocks multiple times for whatever reason (e.g. if it suspects a basic block has changed, as a part of some optimization?), but I'm not that familiar with DR internals. Such questions I can better answer for TinyInst, which I developed myself (TinyInst will not translate a basic block twice unless the target process restarts)

bluestar628 commented 3 weeks ago

Amazing! You're the author of TinyInst! Thank you so much for your help!