AFL源码分析之afl-fuzz.c(仅注释了初始化的配置函数)

更新时间:2023-06-14 03:09:23 阅读: 评论:0

AFL源码分析之afl-fuzz.c(仅注释了初始化的配置函数)通过hollk师傅和sakura师傅的博客对afl-fuzz.c的初始化配置函数进⾏了注释和解读
说实话函数名字的多样性导致我感觉我对整体的初始配置函数理解的完全不够
为过后⼏天还是需要多多的复习和理解
fuzz的实⾏流程推荐⼀些师傅的博客,因为我也是在跟着他们的博客去学习,
可能还有很多优质的师傅的afl分析我没找到,希望在看afl源码的师傅可以推荐⼀下,感谢
/*
Copyright 2013 Google LLC All rights rerved.
Licend under the Apache Licen, Version 2.0 (the "Licen");
you may not u this file except in compliance with the Licen.
You may obtain a copy of the Licen at:
www.apache/licens/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the Licen is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the Licen for the specific language governing permissions and
limitations under the Licen.
*/
/*
american fuzzy lop - fuzzer code
--------------------------------
Written and maintained by Michal Zalewski <>
Forkrver design by Jann Horn <>
This is the real deal: the program takes an instrumented binary and
attempts a variety of basic fuzzing tricks, paying clo attention to
how they affect the execution path.
*/
#define AFL_MAIN
#include "android-ashmem.h"
#define MESSAGES_TO_STDOUT
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#define _FILE_OFFSET_BITS 64
#include "config.h"
#include "types.h"
#include "debug.h"
#include "alloc-inl.h"
#include "hash.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <dirent.h>
#include <ctype.h>
#include <fcntl.h>
#include <termios.h>
#include <dlfcn.h>
#include <sched.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/shm.h>
四叶草寓意
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#if defined(__APPLE__) || defined(__FreeBSD__) || defined (__OpenBSD__)
#  include <sys/sysctl.h>
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
/* For systems that have sched_taffinity; right now just Linux, but one
*/
#ifdef __linux__
#  define HAVE_AFFINITY 1
#endif /* __linux__ */
/* A toggle to export some variables when building as a library. Not very
uful for the general public. */
#ifdef AFL_LIB
#  define EXP_ST
#el
#  define EXP_ST static
#endif /* ^AFL_LIB */
/* Lots of globals, but mostly for the status UI and other things where it
really makes no n to haul them around as function parameters. */
EXP_ST u8 *in_dir,                    /* Input directory with test cas  */
*out_file,                  /* File to fuzz, if any            */
*out_dir,                  /* Working & output directory      */
*sync_dir,                  /* Synchronization directory        */
*sync_id,                  /* Fuzzer ID                        */
*u_banner,                /* Display banner                  */
守株待兔什么意思
*in_bitmap,                /* Input bitmap                    */
*doc_path,                  /* Path to documentation dir        */
*target_path,              /* Path to target binary            */
*orig_cmdline;              /* Original command line            */
EXP_ST u32 exec_tmout = EXEC_TIMEOUT; /* Configurable exec timeout (ms)  */ static u32 hang_tmout = EXEC_TIMEOUT; /* Timeout ud for hang det (ms)  */ EXP_ST u64 mem_limit  = MEM_LIMIT;    /* Memory cap for child (MB)        */ static u32 stats_update_freq = 1;    /* Stats update frequency (execs)  */
EXP_ST u8  skip_deterministic,        /* Skip deterministic stages?      */
force_deterministic,      /* Force deterministic stages?  ⼒确定的阶段?    */
u_splicing,              /* Recombine input files?  再结合输⼊⽂件吗?        */
dumb_mode,                /* Run in non-instrumented mode?    */
score_changed,            /* Scoring for favorites changed?  */
kill_signal,              /* Signal that killed the child    */
resuming_fuzz,            /* Resuming an older fuzzing job?  */
timeout_given,            /* Specific timeout given?          */
earn
not_on_tty,                /* stdout is not a tty              */
69parkterm_too_small,            /* terminal dimensions too small    */
us_asan,                /* Target us ASAN?                */
no_forkrver,            /* Disable forkrver?              */
crash_mode,                /* Crash mode! Yeah!                */
in_place_resume,          /* Attempt in-place resume?        */
auto_changed,              /* Auto-generated tokens changed?  */
我的梦no_cpu_meter_red,          /* Feng shui on the status screen  */
no_arith,                  /* Skip most arithmetic ops        */
shuffle_queue,            /* Shuffle input queue?            */
bitmap_changed = 1,        /* Time to update bitmap?          */
qemu_mode,                /* Running in QEMU mode?            */
skip_requested,            /* Skip request, via SIGUSR1        */
run_over10m,              /* Run time over 10 minutes?        */
persistent_mode,          /* Running in persistent mode?      */
deferred_mode,            /* Deferred forkrver mode?        */
fast_cal;                  /* Try to calibrate faster?        */
static s32 out_fd,                    /* Persistent fd for out_file      */
dev_urandom_fd = -1,      /* Persistent fd for /dev/urandom  */
dev_null_fd = -1,          /* Persistent fd for /dev/null      */
fsrv_ctl_fd,              /* Fork rver control pipe (write) */
fsrv_st_fd;                /* Fork rver status pipe (read)  */
static s32 forksrv_pid,              /* PID of the fork rver          */
child_pid = -1,            /* PID of the fuzzed program        */
out_dir_fd = -1;          /* FD of the lock file              */
EXP_ST u8* trace_bits;                /* SHM with instrumentation bitmap  */
EXP_ST u8  virgin_bits[MAP_SIZE],    /* Regions yet untouched by fuzzing */
virgin_tmout[MAP_SIZE],    /* Bits we haven't en in tmouts  */
virgin_crash[MAP_SIZE];    /* Bits we haven't en in crashes  */
static u8  var_bytes[MAP_SIZE];      /* Bytes that appear to be variable */
static s32 shm_id;                    /* ID of the SHM region            */
static volatile u8 stop_soon,        /* Ctrl-C presd?                  */
clear_screen = 1,  /* Window resized?                  */
child_timed_out;  /* Traced process timed out?        */
EXP_ST u32 queued_paths,              /* Total number of queued testcas */
queued_variable,          /* Testcas with variable behavior */
queued_at_start,          /* Total number of initial inputs  */
queued_discovered,        /* Items discovered during this run */
queued_imported,          /* Items imported via -S            */
queued_favored,            /* Paths deemed favorable          */
queued_with_cov,          /* Paths with new coverage bytes    */
pending_not_fuzzed,        /* Queued but not done yet          */
pending_favored,          /* Pending favored paths            */
cur_skipped_paths,        /* Abandoned inputs in cur cycle    */
cur_depth,                /* Current path depth              */
max_depth,                /* Max path depth                  */
uless_at_start,          /* Number of uless starting paths */
var_byte_count,            /* Bitmap bytes with var behavior  */
current_entry,            /* Current queue entry ID          */
havoc_div = 1;            /* Cycle count divisor for havoc    */
EXP_ST u64 total_crashes,            /* Total number of crashes          */
unique_crashes,            /* Crashes with unique signatures  */
total_tmouts,              /* Total number of timeouts        */
unique_tmouts,            /* Timeouts with unique signatures  */
unique_hangs,              /* Hangs with unique signatures    */
total_execs,              /* Total execve() calls            */
slowest_exec_ms,          /* Slowest testca non hang in ms  */
start_time,                /* Unix start time (ms)            */
last_path_time,            /* Time for most recent path (ms)  */
last_crash_time,          /* Time for most recent crash (ms)  */
last_hang_time,            /* Time for most recent hang (ms)  */
last_crash_execs,          /* Exec counter at last crash      */
queue_cycle,              /* Queue round counter              */
cycles_wo_finds,          /* Cycles without any new paths    */
trim_execs,                /* Execs done to trim input files  */
bytes_trim_in,            /* Bytes coming into the trimmer    */
bytes_trim_out,            /* Bytes coming outa the trimmer    */
blocks_eff_total,          /* Blocks subject to effector maps  */
blocks_eff_lect;        /* Blocks lected as fuzzable      */
static u32 subq_tmouts;            /* Number of timeouts in a row      */
static u8 *stage_name = "init",      /* Name of the current fuzz stage  */
*stage_short,              /* Short stage name                */
*syncing_party;            /* Currently         */
static s32 stage_cur, stage_max;      /* Stage progression                */
static s32 splicing_with = -1;        /* Splicing with which test ca?  */
static u32 master_id, master_max;    /* Master instance job splitting    */
static u32 syncing_ca;              /* Syncing with ca #...          */
static s32 stage_cur_byte,            /* Byte offt of current stage op  */
stage_cur_val;            /* Value ud for stage op          */
static u8  stage_val_type;            /* Value type (STAGE_VAL_*)        */
static u64 stage_finds[32],          /* Patterns found per fuzz stage    */
stage_cycles[32];          /* Execs per fuzz stage            */
static u32 rand_cnt;                  /* Random number counter            */
static u64 total_cal_us,              /* Total calibration time (us)      */
total_cal_cycles;          /* Total calibration cycles        */
static u64 total_bitmap_size,        /* Total bit count for all bitmaps  */
total_bitmap_entries;      /* Number of bitmaps counted        */
static s32 cpu_core_count;            /* CPU core count                  */
#ifdef HAVE_AFFINITY
static s32 cpu_aff = -1;              /* Selected CPU core                */
#endif /* HAVE_AFFINITY */
static FILE* plot_file;              /* Gnuplot output file              */
struct queue_entry {
u8* fname;                          /* File name for the test ca      */
u32 len;                            /* Input length                    */
u8  cal_failed,                    /* Calibration failed?              */
trim_done,                      /* Trimmed?                        */
was_fuzzed,                    /* Had any fuzzing done yet?        */
pasd_det,                    /* Deterministic stages pasd?    */
has_new_cov,                    /* Triggers new coverage?          */
var_behavior,                  /* Variable behavior?              */
favored,                        /* Currently favored?              */
fs_redundant;                  /* Marked as redundant in the fs?  */
u32 bitmap_size,                    /* Number of bits t in bitmap    */
exec_cksum;                    /* Checksum of the execution trace  */
u64 exec_us,                        /* Execution time (us)              */
handicap,                      /* Number of queue cycles behind    */
depth;                          /* Path depth                      */
u8* trace_mini;                    /* Trace bytes, if kept            */
u32 tc_ref;                        /* Trace bytes ref count            */
struct queue_entry *next,          /* Next element, if any            */
*next_100;      /* 100 elements ahead              */
};
static struct queue_entry *queue,    /* Fuzzing queue (linked list)      */
*queue_cur, /* Current offt within the queue  */
*queue_top, /* Top of the list                  */
*q_prev100; /* Previous 100 marker              */
static struct queue_entry*
top_rated[MAP_SIZE];                /* Top entries for bitmap bytes    */
struct extra_data {
u8* data;                          /* Dictionary token data            */
u32 len;                            /* Dictionary token length          */
u32 hit_cnt;                        /* U count in the corpus          */
};
static struct extra_data* extras;    /* Extra tokens to fuzz with        */
static u32 extras_cnt;                /* Total number of tokens read      */
static struct extra_data* a_extras;  /* Automatically lected extras    */
static u32 a_extras_cnt;              /* Total number of tokens available */
static u8* (*post_handler)(u8* buf, u32* len);
/* Interesting values, as per config.h */
static s8  interesting_8[]  = { INTERESTING_8 };
static s16 interesting_16[] = { INTERESTING_8, INTERESTING_16 };
static s32 interesting_32[] = { INTERESTING_8, INTERESTING_16, INTERESTING_32 }; /* Fuzzing stages */
enum {
/* 00 */ STAGE_FLIP1,
/* 01 */ STAGE_FLIP2,
/* 02 */ STAGE_FLIP4,
/* 03 */ STAGE_FLIP8,
/* 04 */ STAGE_FLIP16,
/* 05 */ STAGE_FLIP32,
/* 06 */ STAGE_ARITH8,
/* 07 */ STAGE_ARITH16,
/* 08 */ STAGE_ARITH32,
/* 09 */ STAGE_INTEREST8,
/* 10 */ STAGE_INTEREST16,
/* 11 */ STAGE_INTEREST32,
/* 12 */ STAGE_EXTRAS_UO,
/* 13 */ STAGE_EXTRAS_UI,
/* 14 */ STAGE_EXTRAS_AO,
/* 15 */ STAGE_HAVOC,
/* 16 */ STAGE_SPLICE
};
/* Stage value types */
enum {
/
* 00 */ STAGE_VAL_NONE,
/* 01 */ STAGE_VAL_LE,
/* 02 */ STAGE_VAL_BE
};
/* Execution status fault codes */
enum {
/* 00 */ FAULT_NONE,
/* 01 */ FAULT_TMOUT,
/* 02 */ FAULT_CRASH,
/* 03 */ FAULT_ERROR,
/* 04 */ FAULT_NOINST,
/
* 05 */ FAULT_NOBITS
};
/* Get unix time in milliconds */
static u64 get_cur_time(void) { //以
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return (tv.tv_c * 1000ULL) + (tv.tv_uc / 1000);
}
/* Get unix time in microconds */
static u64 get_cur_time_us(void) {
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return (tv.tv_c * 1000000ULL) + tv.tv_uc;
}
/* Generate a random number (from 0 to limit - 1). This may
have slight bias. */
static inline u32 UR(u32 limit) {
if (unlikely(!rand_cnt--)) {
u32 ed[2];
ck_read(dev_urandom_fd, &ed, sizeof(ed), "/dev/urandom");
srandom(ed[0]);
rand_cnt = (RESEED_RNG / 2) + (ed[1] % RESEED_RNG);
}
return random() % limit;
}
/* Shuffle an array of pointers. Might be slightly biad. */
static void shuffle_ptrs(void** ptrs, u32 cnt) {
u32 i;
for (i = 0; i < cnt - 2; i++) {
u32 j = i + UR(cnt - i);
void *s = ptrs[i];
ptrs[i] = ptrs[j];
ptrs[j] = s;
}
}
#ifdef HAVE_AFFINITY
/* Build a list of process bound to specific cores. Returns -1 if nothing    can be found. Assumes an upper bound of 4k CPUs. */
static void bind_to_free_cpu(void) {
DIR* d;
struct dirent* de;
cpu_t_t c;
u8 cpu_ud[4096] = { 0 };
u32 i;
if (cpu_core_count < 2) return;
if (getenv("AFL_NO_AFFINITY")) {
WARNF("Not binding to a CPU core (AFL_NO_AFFINITY t).");
return;
}
d = opendir("/proc");
if (!d) {
窿组词组
WARNF("Unable to access /proc - can't scan for free CPU cores.");
return;
}
ACTF("Checking CPU ");
/* Introduce some jitter, in ca multiple AFL tasks are doing the same
thing at the */
usleep(R(1000) * 250);
/* Scan all /proc/<pid>/status entries, checking for Cpus_allowed_list.
Flag all process bound to a specific CPU using cpu_ud[]. This will
fail for some exotic binding tups, but is likely good enough in almost
all real-world u cas. */
while ((de = readdir(d))) {
u8* fn;
FILE* f;
u8 tmp[MAX_LINE];
u8 has_vmsize = 0;
if (!isdigit(de->d_name[0])) continue;
fn = alloc_printf("/proc/%s/status", de->d_name);
if (!(f = fopen(fn, "r"))) {
ck_free(fn);
continue;
}
while (fgets(tmp, MAX_LINE, f)) {
u32 hval;
/* Process without VmSize are probably kernel tasks. */
if (!strncmp(tmp, "VmSize:\t", 8)) has_vmsize = 1;
if (!strncmp(tmp, "Cpus_allowed_list:\t", 19) &&
!strchr(tmp, '-') && !strchr(tmp, ',') &&
sscanf(tmp + 19, "%u", &hval) == 1 && hval < sizeof(cpu_ud) &&
has_vmsize) {
cpu_ud[hval] = 1;
break;
}
}
ck_free(fn);
fclo(f);
}
clodir(d);
for (i = 0; i < cpu_core_count; i++) if (!cpu_ud[i]) break;
if (i == cpu_core_count) {
SAYF("\n" cLRD "[-] " cRST
"Uh-oh, looks like all %u CPU cores on your system are allocated to\n"
"    other instances of afl-fuzz (or similar CPU-locked tasks). Starting\n"
"    another fuzzer on this machine is probably a bad plan, but if you are\n"        "    absolutely sure, you can t AFL_NO_AFFINITY and try again.\n",
盘扣式脚手架cpu_core_count);
FATAL("No more free CPU cores");
}
涑的拼音OKF("Found a free CPU core, binding to #%u.", i);
cpu_aff = i;
CPU_ZERO(&c);
CPU_SET(i, &c);
if (sched_taffinity(0, sizeof(c), &c))
PFATAL("sched_taffinity failed");
}
#endif /* HAVE_AFFINITY */
#ifndef IGNORE_FINDS
/* Helper function to compare buffers; returns first and last differing offt. We    u this to find reasonable locations for splicing two files. */
static void locate_diffs(u8* ptr1, u8* ptr2, u32 len, s32* first, s32* last) {
s32 f_loc = -1;
s32 l_loc = -1;
u32 pos;
for (pos = 0; pos < len; pos++) {

本文发布于:2023-06-14 03:09:23,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1037474.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   配置   推荐   源码   理解
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图