AFL fork server和fuzzer的交互

看了一些博客,都是在说fuzzer和fork server进行交互,由fork server fork出子进程来执行程序,但是不太明白这两者到底是如何在代码层面进行交互的。

run_target中有这么一段代码,大概意思是fuzzer给fork server传递prev_timed_out,然后再从fork server读取子进程的pid,child_pid:

    s32 res;/* In non-dumb mode, we have the fork server up and running, so simplytell it to have at it, and then read back PID. */if ((res = write(fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {if (stop_soon) return 0;RPFATAL(res, "Unable to request new process from fork server (OOM?)");}if ((res = read(fsrv_st_fd, &child_pid, 4)) != 4) {if (stop_soon) return 0;RPFATAL(res, "Unable to request new process from fork server (OOM?)");}if (child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)");

我现在的问题是,为什么fuzzer给fork server传了个参数,fork server就直接返回pid了呢?这中间两者是如何进行交互的?fork server做了什么,就传递了一个child_pid出来?

fork server进程是执行了下面这段代码(删去了一些不重要的代码):

  if (!forksrv_pid) {struct rlimit r;/* Isolate the process and configure standard descriptors. If out_file isspecified, stdin is /dev/null; otherwise, out_fd is cloned instead. */setsid();dup2(dev_null_fd, 1);dup2(dev_null_fd, 2);if (out_file) {dup2(dev_null_fd, 0);} else {dup2(out_fd, 0);close(out_fd);}/* Set up control and status pipes, close the unneeded original fds. */if (dup2(ctl_pipe[0], FORKSRV_FD) < 0) PFATAL("dup2() failed");if (dup2(st_pipe[1], FORKSRV_FD + 1) < 0) PFATAL("dup2() failed");close(ctl_pipe[0]);close(ctl_pipe[1]);close(st_pipe[0]);close(st_pipe[1]);close(out_dir_fd);close(dev_null_fd);close(dev_urandom_fd);close(fileno(plot_file));execv(target_path, argv);/* Use a distinctive bitmap signature to tell the parent about execv()falling through. */*(u32*)trace_bits = EXEC_FAIL_SIG;exit(0);}

可能需要理解setsid();?
简单搜索了下,还得去理解进程相关只是,于是去问了bing,bing的回答告诉我:setsid()函数是一个系统调用,它的作用是创建一个新的会话(session),并使得当前进程成为会话的首进程(session leader),这个函数似乎和我想知道的东西没有联系。

问了下bing,并参考了这个博客:https://blog.csdn.net/Little_Bro/article/details/122694054,fork server的交互还和插桩有关系。

查看了AFL白皮书:https://github.com/mirrorer/afl/blob/master/docs/technical_details.txt,写的很粗略,还是得去看作者的博客:https://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html

Unfortunately, there is also a problem: especially for simple libraries, you may end up spending most of the time waiting for execve(), the linker, and all the library initialization routines to do their job. I’ve been thinking of ways to minimize this overhead in american fuzzy lop, but most of the ideas I had were annoyingly complicated. For example, it is possible to write a custom ELF loader and execute the program in-process while using mprotect() to temporarily lock down the memory used by the fuzzer itself - but things such as signal handling would be a mess. Another option would be to execute in a single child process, make a snapshot of the child’s process memory and then “rewind” to that image later on via /proc/pid/mem - but likewise, dealing with signals or file descriptors would require a ton of fragile hacks.

为什么不直接多次调用execve()?因为每次调用 execve()都会有一些预处理的开销,作者想要加快这个过程。(不太了解预处理的过程,后续有需要再了解)

Luckily, Jann Horn figured a different, much simpler approach, and sent me a patch for afl out of the blue 😃 It boils down to injecting a small piece of code into the fuzzed binary - a feat that can be achieved via LD_PRELOAD, via PTRACE_POKETEXT, via compile-time instrumentation, or simply by rewriting the ELF binary ahead of the time. The purpose of the injected shim is to let execve() happen, get past the linker (ideally with LD_BIND_NOW=1, so that all the hard work is done beforehand), and then stop early on in the actual program, before it gets to processing any inputs generated by the fuzzer or doing anything else of interest. In fact, in the simplest variant, we can simply stop at main().

作者给出了一个很巧妙的解决方法,在被fuzzed的程序中插桩,让这个程序在完成预处理后暂停(比如再main函数的第一句话暂停),然后在这里调用fork(),被fork出来的子进程将会直接跳过预处理过程,开始执行实际处理。

Once the designated point in the program is reached, our shim simply waits for commands from the fuzzer; when it receives a “go” message, it calls fork() to create an identical clone of the already-loaded program; thanks to the powers of copy-on-write, the clone is created very quickly yet enjoys a robust level of isolation from its older twin. Within the child process(fork server创建的子进程), the injected code returns control to the original binary, letting it process the fuzzer-supplied input data (and suffer any consequences of doing so). Within the parent, the shim relays the PID of the newly-crated process to the fuzzer and goes back to the command-wait loop.

作者把插入的代码叫做slim(分隔片,还是很形象的),slim等待来自fuzzer的命令(对应run_target中的write(fsrv_ctl_fd, &prev_timed_out, 4)?),在收到fuzzer的命令后,fork server fork出来一个真正执行二进制程序的fuzzed进程,并给fuzzer返回一个pid。

这里有一个问题,函数参数是在哪里传递的呢?write(fsrv_ctl_fd, &prev_timed_out, 4)似乎没有传递参数。

接下俩作者还讨论了实际实现可能遇到的问题,以及插桩的汇编代码

https://blog.csdn.net/Little_Bro/article/details/12269405,这个博客对插桩代码进行了解释,但是我目前不需要对插桩代码理解的那么清楚,已经明白了fork server和fuzzer之间交互的逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712439.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-如果没有工具就创造工具

内容参考于&#xff1a; 易道云信息技术研究院VIP课 上一个内容 &#xff1a;12.游戏网络通信存在的问题 现在把游戏网络的架构看了一个小小的大概&#xff0c;可以用它的接口发数据接收数据了&#xff0c;如果真正想用它这一套东西&#xff0c;真正核心不在于它的接口而在于…

2024GAS《声学大讲堂》

由中国电子音响行业协会主办&#xff0c;上海市浦东新区先进音视频技术协会承办的GAS《声学大讲堂》2021年开播&#xff0c;三年来GAS《声学大讲堂》开设了“沉浸声音频与艺术”、“智能车载音频”、“智能可穿戴”、“智能耳机”、“智能音箱”、“专业音响”、“助听/辅听设备…

老卫带你学---leetcode刷题(268. 丢失的数字)

268. 丢失的数字 问题 给定一个包含 [0, n] 中 n 个数的数组 nums &#xff0c;找出 [0, n] 这个范围内没有出现在数组中的那个数。 示例 1&#xff1a; 输入&#xff1a;nums [3,0,1] 输出&#xff1a;2 解释&#xff1a;n 3&#xff0c;因为有 3 个数字&#xff0c;所以…

R语言安装和简单入门HelloWorld用法

R语言安装和简单入门HelloWorld用法 #R语言安装地址 https://www.r-project.org/ click->CRAN mirror->选择China下列表&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/CRAN/ 选择Download R for Windows 选择base Download R-4.3.2 for Windows 下载文件R-4.3.2-…

怎么重构数据库表结构

重构数据库表结构是指对已有的数据库表进行调整和优化&#xff0c;以提高数据库的性能、可扩展性和可维护性。以下是一些重构数据库表结构的常见步骤&#xff1a; 分析现有表结构&#xff1a;首先&#xff0c;仔细分析现有的数据库表结构&#xff0c;了解表之间的关系和依赖关…

数据结构从入门到精通——算法的时间复杂度和空间复杂度

算法的时间复杂度和空间复杂度 前言一、算法效率1.1 如何衡量一个算法的好坏1.2 算法的复杂度 二、时间复杂度2.1 时间复杂度的概念2.2 大O的渐进表示法2.3常见时间复杂度计算举例2.4等差数列计算公式2.5等比数列计算方法 三、空间复杂度四、 常见复杂度对比五、 复杂度的oj练习…

ts学习:is关键词

is关键词主要用来框定类型并实现对应的类型断言&#xff0c;下面看一个例子 写一个简单函数来判断某个值是否是字符串类型 function isString(value:unknown):boolean{return typeof value "string" } 这里我们的参数选用了unknown类型&#xff0c;该类型就是一个…

python代码优化学习

代码优化对比&#xff1a; 优化前&#xff1a; # 登录系统 xxljob_login() start_time time.time() # 循环处理需要补数的数据 for item in authId_lists: preSettleInfoHandler(item) count 1 print("运行了第" str(count) "个") …

数据分析---主要工作

目录 几个主要工作常用的数据分析工具具体的使用场景几个主要工作 数据清洗和预处理:对原始数据进行清洗、去重、填充缺失值、处理异常值等操作,以确保数据的准确性和完整性。探索性数据分析(EDA):通过可视化和统计方法,对数据进行探索,发现数据的分布、相关性、异常情况…

【JVM】聊聊常见的JVM排查工具

JDK工具包 jps 虚拟机进程状况工具 jps是虚拟机进程状况工具&#xff0c;列出正在运行的虚拟机进程&#xff0c;使用 Windows 的任务管理器或 UNIX 的 ps 命令也可以查询&#xff0c;但如果同时启动多个进程&#xff0c;必须依赖 jps。jps -l 显示类名 jps :列出Java程序进程…

linux vi 退出编辑状态

在 vi 编辑器中&#xff0c;要退出编辑状态并保存或者放弃更改&#xff0c;需要执行以下步骤&#xff1a; 1. 保存并退出&#xff1a; - 按下 Esc 键确保你处于正常模式&#xff08;Normal Mode&#xff09;。 - 输入 :wq&#xff0c;然后按下 Enter 键。这将保存更改并…

SVPWM

SVPWM SVPWMSVPWM原理产品比较特点来源 SVPWM SVPWM的主要思想是以三相对称正弦波电压供电时三相对称电动机定子理想磁链圆为参考标准&#xff0c;以三相逆变器不同开关模式作适当的切换&#xff0c;从而形成PWM波&#xff0c;以所形成的实际磁链矢量来追踪其准确磁链圆。传统…

3.1作业

改变图片色彩————德国国旗 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> int main(int argc, const char *argv[]) {FILE* fpfopen("./haha.bmp","r");int h0,w0;fseek(fp,18,SEEK_SET)…

yolo训练时遇到GBK编码问题

yolo训练时遇到GBK编码问题 启动训练具体信息如下&#xff1a; comet upload E:\python\yolov9-main.cometml-runs\e0c17dd22058467f98cf447d5cc45bf5.zip COMET INFO: Using ‘D:\pycharmProject\yolov5-master-6.2\.cometml-runs’ path as offline directory. Pass ‘off…

高比例清洁能源接入下计及需求响应的配电网重构(matlab代码)

目录 1 主要内容 目标函数 重要约束条件 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现《高比例清洁能源接入下计及需求响应的配电网重构》&#xff0c;以考虑网损成本、弃风弃光成本和开关操作惩罚成本的综合成本最小为目标&#xff0c;针对配电网重构模型的…

3694-51-7,3,5-Dinitro-1,2-phenylenediamine,合成其他化合物的重要中间体

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;3694-51-7&#xff0c;3,5-Dinitro-1,2-phenylenediamine&#xff0c;3,5-二硝基-1,2-苯二胺;3,5-二硝基苯-1,2-二胺 一、基本信息 【产品简介】&#xff1a;3,5-Dinitro-1,2-phenylenediamine, with the molecular…

提取抖店卖家电话的爬虫软件

介绍&#xff1a; 如今&#xff0c;电商平台上的抖店卖家数量庞大&#xff0c;对于想要联系卖家的买家来说&#xff0c;获取卖家的联系电话是一项相当繁琐的任务。为了简化这个过程&#xff0c;我们可以借助Python编写一个抖店卖家电话提取爬虫软件&#xff0c;快速获取所需的联…

SpringBoot启动扩展应用:干预优化+加快启动时间(干货典藏版)

一、SpringBoot启动过程干预 Spring Boot启动过程中我们可以实现以下干预工作&#xff1a; 修改Spring Boot默认的配置属性。使用ConfigurationProperties和EnableConfigurationProperties注解&#xff0c;可以获取和修改Spring Boot的配置属性。 加载配置文件。Spring Boot会…

面试数据库篇(mysql)- 06覆盖索引

原理 覆盖索引是指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。 id name gender createdate 2 Arm

c++_leetcode_寻找峰值

目录 一、寻找峰值的示例 二、官方实现代码及解释 1、官方测试结果&#xff1a; 2、代码解释&#xff1a; 3、解题思路&#xff1a; 三、我的暴力解决 1、测试一&#xff1a; 2、测试二&#xff1a; 3、最终“暴力求解”代码&#xff1a; 4、官网提交测试通过&#xf…