| /* |
| american fuzzy lop++ - high-performance binary-only instrumentation |
| ------------------------------------------------------------------- |
| |
| Originally written by Andrew Griffiths <agriffiths@google.com> and |
| Michal Zalewski |
| |
| TCG instrumentation and block chaining support by Andrea Biondo |
| <andrea.biondo965@gmail.com> |
| |
| QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero |
| counters by Andrea Fioraldi <andreafioraldi@gmail.com> |
| |
| Copyright 2015, 2016, 2017 Google Inc. All rights reserved. |
| Copyright 2019-2020 AFLplusplus Project. All rights reserved. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at: |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| This code is a shim patched into the separately-distributed source |
| code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality |
| to implement AFL-style instrumentation and to take care of the remaining |
| parts of the AFL fork server logic. |
| |
| The resulting QEMU binary is essentially a standalone instrumentation |
| tool; for an example of how to leverage it for other purposes, you can |
| have a look at afl-showmap.c. |
| |
| */ |
| |
| #include "afl-qemu-common.h" |
| #include "tcg-op.h" |
| |
| void HELPER(afl_maybe_log)(target_ulong cur_loc) { |
| |
| register uintptr_t afl_idx = cur_loc ^ afl_prev_loc; |
| |
| INC_AFL_AREA(afl_idx); |
| |
| afl_prev_loc = cur_loc >> 1; |
| |
| } |
| |
| /* Generates TCG code for AFL's tracing instrumentation. */ |
| static void afl_gen_trace(target_ulong cur_loc) { |
| |
| /* Optimize for cur_loc > afl_end_code, which is the most likely case on |
| Linux systems. */ |
| |
| if (cur_loc > afl_end_code || |
| cur_loc < afl_start_code /*|| !afl_area_ptr*/) // not needed because of |
| // static dummy buffer |
| return; |
| |
| /* Looks like QEMU always maps to fixed locations, so ASLR is not a |
| concern. Phew. But instruction addresses may be aligned. Let's mangle |
| the value to get something quasi-uniform. */ |
| |
| cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); |
| cur_loc &= MAP_SIZE - 1; |
| |
| /* Implement probabilistic instrumentation by looking at scrambled block |
| address. This keeps the instrumented locations stable across runs. */ |
| |
| if (cur_loc >= afl_inst_rms) return; |
| |
| TCGv cur_loc_v = tcg_const_tl(cur_loc); |
| gen_helper_afl_maybe_log(cur_loc_v); |
| tcg_temp_free(cur_loc_v); |
| |
| } |
| |