在阅读了Neuzz的源码之后,决定记录下阅读源码整理出的Neuzz具体工作机制,以供日后回顾。如有出现理解错误,烦请路过的大佬们多指点,不胜感激。
综述
NEUZZ最主要的思想是:利用神经网络来模拟程序的分支行为。
neuzz是想通过有策略地修改现有seeds的一些bytes以期来产生interesting seeds从而能触发未执行过的edge。而这个策略要借助神经网络才能得以具体实施。因此neuzz中的神经网络输入层是代表seed文件内容的向量,输出层表示该seed经过程序中各edge的概率。通过随机的挑选一些output neuron代表未执行过的edge,然后计算各neuron关于一些seed的bytes的梯度。根据梯度提供的信息对这些bytes有策略的改动,从而得到新的seeds去测试程序。
程序结构
NEUZZ的主要工作机制是一个C文件和一个py文件交互的工作过程。两个文件的通信是利用socket通信进行的。
neuzz.c的工作
在main()函数中,对执行该文件时的各项命令参数进行解析之后,就是众多封装好的函数了。
- setup_signal_handers(); 设置信号处理程序
- check_cpu_governor(); 检查cpu的调速器
- get_core_count();
- bind_to_free_cpu();
- setup_shm(); 注册共享内存和virgin_bits数组
- init_count_class16();
- setup_dirs_fds();
… - copy_seeds(in_dir, out_dir); 将作者在neuzz_in文件夹中准备的seeds复制到seeds/文件夹下。(当然这里仅指按作者github上所指示的操作时,最本意就是从你存放seeds的文件夹复制到最终存储程序执行过程中的所有输出的文件夹)。
- init_forkserver(argv+optind); emmmm, forkserver机制暂时还不懂,好像是能让程序并行测试seeds的。
- start_fuzz(len); 前面的那些程序都是完成准备工作,这个函数开始正式执行。所以下面对该函数的具体工作流进行详细分析。