afl-tmin.c源码 完整版

本文详细探讨了AFL-tmin.c的源代码,揭示了模糊测试工具AFL内部工作原理的关键细节,包括如何优化输入样本以增强测试覆盖率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define AFL_MAIN

#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 <fcntl.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>

static s32 child_pid;                 /* PID of the tested program         */

static u8 *trace_bits,                /* SHM with instrumentation bitmap   */
          *mask_bitmap;               /* Mask for trace bits (-B)          */

static u8 *in_file,                   /* Minimizer input test case         */
          *out_file,                  /* Minimizer output file             */
          *prog_in,                   /* Targeted program input file       */
          *target_path,               /* Path to target binary             */
          *doc_path;                  /* Path to docs                      */

static u8* in_data;                   /* Input data for trimming           */

static u32 in_len,                    /* Input data length                 */
           orig_cksum,                /* Original checksum                 */
           total_execs,               /* Total number of execs             */
           missed_hangs,              /* Misses due to hangs               */
           missed_crashes,            /* Misses due to crashes             */
           missed_paths,              /* Misses due to exec path diffs     */
           exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms)                 */

static u64 mem_limit = MEM_LIMIT;     /* Memory limit (MB)                 */

static s32 shm_id,                    /* ID of the SHM region              */
           dev_null_fd = -1;          /* FD to /dev/null                   */

static u8  crash_mode,                /* Crash-centric mode?               */
           exit_crash,                /* Treat non-zero exit as crash?     */
           edges_only,                /* Ignore hit counts?                */
           exact_mode,                /* Require path match for crashes?   */
           use_stdin = 1;             /* Use stdin for program input?      */

static volatile u8
           stop_soon,                 /* Ctrl-C pressed?                   */
           child_timed_out;           /* Child timed out?                  */


/* Classify tuple counts. This is a slow & naive version, but good enough here. */

static const u8 count_class_lookup[256] = {
   
   

  [0]           = 0,
  [1]           = 1,
  [2]           = 2,
  [3]           = 4,
  [4 ... 7]     = 8,
  [8 ... 15]    = 16,
  [16 ... 31]   = 32,
  [32 ... 127]  = 64,
  [128 ... 255] = 128

};

static void classify_counts(u8* mem) {
   
   

  u32 i = MAP_SIZE;

  if (edges_only) {
   
   

    while (i--) {
   
   
      if (*mem) *mem = 1;
      mem++;
    }

  } else {
   
   

    while (i--) {
   
   
      *mem = count_class_lookup[*mem];
      mem++;
    }

  }

}


/* Apply mask to classified bitmap (if set). */

static void apply_mask(u32* mem, u32* mask) {
   
   

  u32 i = (MAP_SIZE >> 2);

  if (!mask) return;

  while (i--) {
   
   

    *mem &= ~*mask;
    mem++;
    mask++;

  }

}


/* See if any bytes are set in the bitmap. */

static inline u8 anything_set(void) {
   
   

  u32* ptr = (u32*)trace_bits;
  u32  i   = (MAP_SIZE >> 2);

  while (i--) if (*(ptr++)) return 1;

  return 0;

}



/* Get rid of shared memory and temp files (atexit handler). */

static void remove_shm(void) {
   
   

  if (prog_in) unlink(prog_in); /* Ignore errors */
  shmctl(shm_id, IPC_RMID, NULL);

}


/* Configure shared memory. */

static void setup_shm(void) {
   
   

  u8* shm_str;

  shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);

  if (shm_id < 0) PFATAL("shmget() failed");

  atexit(remove_shm);

  shm_str = alloc_printf("%d", shm_id);

  setenv(SHM_ENV_VAR, shm_str, 1);

  ck_free(shm_str);

  trace_bits = shmat(shm_id, NULL, 0);

  if (!trace_bits) PFATAL("shmat() failed");

}


/* Read initial file. */

static void read_initial_file(void) {
   
   

  struct stat st;
  s32 fd = open(in_file, O_RDONLY);

  if (fd < 0) PFATAL("Unable to open '%s'", in_file);

  if (fstat(fd, &st) || !st.st_size)
    FATAL("Zero-sized input file.");

  if (st.st_size >= TMIN_MAX_FILE)
    FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);

  in_len  = st.st_size;
  in_data = ck_alloc_nozero(in_len);

  ck_read(fd, in_data, in_len, in_file);

  close(fd);

  OKF("Read %u byte%s from '%s'.", in_len, in_len == 1 ? "" : "s", in_file);

}


/* Write output file. */

static s32 write_to_file(u8* path, u8* mem, u32 len) {
   
   

  s32 ret;

  unlink(path); /* Ignore errors */

  ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);

  if (ret < 0) PFATAL("Unable to create '%s'", path);

  ck_write(ret, mem, len, path);

  lseek(ret, 0, SEEK_SET);

  return ret;

}


/* Handle timeout signal. */

static void handle_timeout(int sig) {
   
   

  child_timed_out = 1;
  if (child_pid > 0) kill(child_pid, SIGKILL);

}


/* Execute target application. Returns 0 if the changes are a dud, or
   1 if they should be kept. */

static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
   
   

  static struct itimerval it;
  int status = 0;

  s32 prog_in_fd;
  u32 cksum;

  memset(trace_bits, 0
<think>好的,我现在需要帮用户找到关于afl-full的详细教程或使用指南。首先,用户提到的afl-full可能是指AFL(American Fuzzy Lop)的完整版本或某个特定配置。我需要先确认afl-full的具体含义。根据用户提供的引用,AFL涉及变异策略、编译安装步骤等,比如引用[1]提到整数变异和大小端序处理,引用[2]和[3]涉及安装和编译。这可能说明afl-full是AFL的标准安装或某个扩展版本。 接下来,我应该检查用户提供的引用内容是否有直接相关的信息。引用[2]提到了使用afl-clang-fast进行编译,引用[3]是关于安装步骤。用户可能需要完整的配置和使用流程,但现有的引用可能不够详细。因此,可能需要补充外部资源或官方文档的信息。 用户的需求是寻找教程或指南,所以需要整理安装步骤、配置方法、基本用法和高级技巧。需要确保步骤清晰,结合现有的引用内容,比如编译时的CC和CXX设置,以及变异策略的说明。此外,用户可能需要了解如何有效使用AFL进行模糊测试,包括目标程序的插桩、测试用例管理、结果分析等。 另外,用户可能遇到的问题包括安装过程中的依赖项缺失、环境配置错误,或者如何优化AFL的性能。需要建议参考官方文档、社区资源或详细教程,比如GitHub仓库的README或官方仓库的wiki页面。同时,引用中提到的变异策略(如算术变异)可以作为高级用法的例子。 最后,生成相关问题需要考虑用户可能的后续疑问,比如安装问题、优化方法、结果分析等,确保覆盖用户可能遇到的各个阶段的问题。</think>关于AFL(American Fuzzy Lop)的完整使用教程,目前公开资料中并未明确提及"afl-full"的专有名词,推测可能指AFL的完整安装配置或扩展功能。以下整理AFL的核心使用指南与进阶操作: --- ### **一、AFL基础安装与配置** 1. **编译安装** 通过源码编译时需指定编译器路径,支持对C/C++项目的插桩: ```bash # 设置环境变量后配置项目 CC=/path/to/afl/afl-clang-fast ./configure CXX=/path/to/afl/afl-clang-fast++ ./configure make clean && make ``` 安装完成后执行`make install`,若修改过工具链需重新安装[^2][^3]。 2. **变异策略** AFL采用非冗余变异策略,如对整数进行±1至±35的算术变异,同时考虑大小端序(Big/Little Endian)差异[^1]。通过跳过低效变异操作保持执行效率。 --- ### **二、关键操作流程** 1. **目标程序插桩** 使用`afl-gcc`或`afl-clang-fast`编译目标程序,生成插桩后的二进制文件: ```bash afl-clang-fast -o target target.c ``` 2. **模糊测试启动** 指定输入种子目录和输出结果路径: ```bash afl-fuzz -i input_dir -o output_dir ./target @@ ``` 3. **测试结果分析** 通过`afl-cmin`精简测试用例,利用`afl-tmin`最小化触发崩溃的输入文件。 --- ### **三、高级功能扩展** - **并行化测试** 使用`-M`(主节点)和`-S`(从节点)参数实现多核分布式模糊测试 - **持久模式(Persistent Mode)** 对特定函数进行高频次调用,加速局部代码覆盖 - **自定义字典** 添加语法规则或关键字提升变异有效性 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值