AFLNET源码理解(二)

接下来看看源码,今天先看一部分不一定能看完(大概率看不完吧)由于相当大一部分是AFLfuzz的代码,就不重点看这些,主要看看AFLNET做了些什么。
前面都是一些参数配置的检查部分,新增了AFLNET的参数,主要是配置网络信息和选择使用的协议,具体参数可以参考AFLNET的官方文档。

//9132行
//AFLNet - Check for required arguments
  if (!use_net) FATAL("Please specify network information of the server under test (e.g., tcp://127.0.0.1/8554)");

  if (!protocol_selected) FATAL("Please specify the protocol to be tested using the -P option");

  if (netns_name) {
    if (check_ep_capability(CAP_SYS_ADMIN, argv[0]) != 0)
      FATAL("Could not run the server under test in a \"%s\" network namespace "
            "without CAP_SYS_ADMIN capability.\n You can set it by invoking "
            "afl-fuzz with sudo or by \"$ setcap cap_sys_admin+ep /path/to/afl-fuzz\".", netns_name);
  }
//9142行

进行初始化

//9194行
  check_crash_handling();
  check_cpu_governor();

  setup_post();
  setup_shm();
  init_count_class16();

  setup_ipsm();

  setup_dirs_fds();
  read_testcases();
  load_auto();

  pivot_inputs();

  if (extras_dir) load_extras(extras_dir);

  if (!timeout_given) find_timeout();

  detect_file_args(argv + optind + 1);

  if (!out_file) setup_stdio_file();

  check_binary(argv[optind]);

  start_time = get_cur_time();
//9219行

这里初始化时调用了setup_ipsm()函数用于初始化状态机。函数细节等分析完main函数后进行分析。read_testcasese()读取所有测试用例,load_auto()是加载自动生成的额外内容。之后pivot_inputs()在输出目录中为输入的测试用例创建硬链接(/* Create hard links for input test cases in the output directory, choosing good names and pivoting accordingly. */)

  perform_dry_run(use_argv);
  cull_queue();
  show_init_stats();
  seek_to = find_start_position();

  
  write_stats_file(0, 0, 0);
  save_auto();

perform_dry_run()在AFLfuzz中是先把所有测试用例跑一次确保程序正确运行,只在初始化输入时执行且只执行一次。但是由于AFLNET会在此更新状态机,所以这个函数也需要分析。
cull_queue()没有变化,就是简化队列。
show_init_stats();输入目录处理结束后的一些工作。
seek_to = find_start_position();找到队列起始位置。

if (state_aware_mode) {

    if (state_ids_count == 0) {
      PFATAL("No server states have been detected. Server responses are likely empty!");
    }
    while (1) {
      u8 skipped_fuzz;

      struct queue_entry *selected_seed = NULL;
      while(!selected_seed || selected_seed->region_count == 0) {
        target_state_id = choose_target_state(state_selection_algo);

        /* Update favorites based on the selected state */
        cull_queue();

        /* Update number of times a state has been selected for targeted fuzzing */
        khint_t k = kh_get(hms, khms_states, target_state_id);
        if (k != kh_end(khms_states)) {
          kh_val(khms_states, k)->selected_times++;
        }

        selected_seed = choose_seed(target_state_id, seed_selection_algo);
      }

      /* Seek to the selected seed */
      if (selected_seed) {
        if (!queue_cur) {
            current_entry     = 0;
            cur_skipped_paths = 0;
            queue_cur         = queue;
            queue_cycle++;
        }
        while (queue_cur != selected_seed) {
          queue_cur = queue_cur->next;
          current_entry++;
          if (!queue_cur) {
            current_entry     = 0;
            cur_skipped_paths = 0;
            queue_cur         = queue;
            queue_cycle++;
          }
        }
      }

      skipped_fuzz = fuzz_one(use_argv);

      if (!stop_soon && sync_id && !skipped_fuzz) {

        if (!(sync_interval_cnt++ % SYNC_INTERVAL))
          sync_fuzzers(use_argv);

      }

      if (!stop_soon && exit_1) stop_soon = 2;

      if (stop_soon) break;
    }

  } else {
    while (1) {

      u8 skipped_fuzz;

      cull_queue();

      if (!queue_cur) {

        queue_cycle++;
        current_entry     = 0;
        cur_skipped_paths = 0;
        queue_cur         = queue;

        while (seek_to) {
          current_entry++;
          seek_to--;
          queue_cur = queue_cur->next;
        }

        show_stats();

        if (not_on_tty) {
          ACTF("Entering queue cycle %llu.", queue_cycle);
          fflush(stdout);
        }

        /* If we had a full queue cycle with no new finds, try
           recombination strategies next. */

        if (queued_paths == prev_queued) {

          if (use_splicing) cycles_wo_finds++; else use_splicing = 1;

        } else cycles_wo_finds = 0;

        prev_queued = queued_paths;

        if (sync_id && queue_cycle == 1 && getenv("AFL_IMPORT_FIRST"))
          sync_fuzzers(use_argv);

      }

      skipped_fuzz = fuzz_one(use_argv);

      if (!stop_soon && sync_id && !skipped_fuzz) {

        if (!(sync_interval_cnt++ % SYNC_INTERVAL))
          sync_fuzzers(use_argv);

      }

      if (!stop_soon && exit_1) stop_soon = 2;

      if (stop_soon) break;

      queue_cur = queue_cur->next;
      current_entry++;

    }
  }

这部分代码是启用了感知机模式即使用状态机指导fuzzing的代码。
首先如果state_ids_count==0的话表示服务器状态数为0即服务器没有返回响应报文,这时报错退出。这也说明之前的state_ids_count记录的是状态机的状态数。
while(1)部分即进行fuzzing的部分。

while (1) {
      u8 skipped_fuzz;

      struct queue_entry *selected_seed = NULL;
      while(!selected_seed || selected_seed->region_count == 0) {
        target_state_id = choose_target_state(state_selection_algo);

        /* Update favorites based on the selected state */
        cull_queue();

        /* Update number of times a state has been selected for targeted fuzzing */
        khint_t k = kh_get(hms, khms_states, target_state_id);
        if (k != kh_end(khms_states)) {
          kh_val(khms_states, k)->selected_times++;
        }

        selected_seed = choose_seed(target_state_id, seed_selection_algo);
      }

      /* Seek to the selected seed */
      if (selected_seed) {
        if (!queue_cur) {
            current_entry     = 0;
            cur_skipped_paths = 0;
            queue_cur         = queue;
            queue_cycle++;
        }
        while (queue_cur != selected_seed) {
          queue_cur = queue_cur->next;
          current_entry++;
          if (!queue_cur) {
            current_entry     = 0;
            cur_skipped_paths = 0;
            queue_cur         = queue;
            queue_cycle++;
          }
        }
      }

      skipped_fuzz = fuzz_one(use_argv);

      if (!stop_soon && sync_id && !skipped_fuzz) {

        if (!(sync_interval_cnt++ % SYNC_INTERVAL))
          sync_fuzzers(use_argv);

      }

      if (!stop_soon && exit_1) stop_soon = 2;

      if (stop_soon) break;
    }

当queue entry* selected_seed没有选出来或者selected_seed中的regions数为0时,先通过choose_target_state()函数选出目标状态id,之后调用cull_queue()更新队列,之后更新被选中状态的选中次数。之后通过choose_seed()函数选出selected_seed。 之后调整queue_cur到selected_seed。之后调用fuzz_one()函数进行一次fuzz,再根据fuzz的结果判断是否结束fuzz。
之后是一些结束fuzz清理资源关闭文件的一些操作。
以上是对AFLNET的main函数执行步骤的分析,还需要对setup_ipsm()、perform_dry_run()、fuzz_one()进一步分析。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring MVC是Spring框架的一个模块,它提供了一种基于注解和xml配置的web MVC框架,可以帮助我们更加方便地开发Web应用程序。 Spring MVC的码可以分为以下几个部分: 1. 核心类:DispatcherServlet DispatcherServlet是Spring MVC框架的核心类,它继承了HttpServlet,并且重写了doGet, doPost等方法。DispatcherServlet负责协调整个Web应用程序的请求和响应。它会根据配置文件中的映射关系,将请求分发到相应的处理器HandlerMapping、处理器适配器HandlerAdapter和视图解析器ViewResolver等组件中进行处理。 2. 处理器映射器:HandlerMapping HandlerMapping用于将请求映射到相应的处理器Handler上,它负责根据请求的URL、请求的参数等信息,找到合适的Handler,然后将请求转发给Handler进行处理。 3. 处理器适配器:HandlerAdapter HandlerAdapter负责将请求转换成处理器能够处理的参数类型,并将处理器返回的结果转换成响应类型,以便DispatcherServlet能够将其返回给客户端。 4. 视图解析器:ViewResolver ViewResolver用于将处理器返回的模型数据和视图名称组装成一个完整的视图,以便DispatcherServlet将其返回给客户端。ViewResolver会根据视图名称查找相应的视图,并将模型数据填充到视图中。 5. 处理器:Handler Handler是处理请求的核心组件,它实现了Controller接口,并且根据请求的URL和请求的参数等信息,执行相应的业务逻辑,并返回模型数据和视图名称。 6. 拦截器:Interceptor Interceptor用于拦截请求和响应,它可以在请求到达Handler之前或者返回给客户端之前进行一些处理,例如权限校验、日志记录等。 以上是Spring MVC框架的一些核心组件,如果想要深入理解Spring MVC的码,可以从这些组件入手,逐个分析其实现原理和代码逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值