Zmap源码解析
2023-07-27 00:13:35 # Zmap源码解析

概况

阅读前的注意事项

本文中,对于颜色使用说明:
当遇到行内代码块时:

  • **结构体或者变量以及函数**

  • **结构体成员或者网络协议内容**

  • **文件**

    该系列文章说明

    面向人群所需基础:

  • 拥有C语言基本的知识,如语法基础;

  • 使用过Zmap或者同类型工具的人,对zmap的功能大致了解;

  • 拥有基本的计算机网络知识;

文章目标:

  • 清晰明白的了解Zmap的架构,主要功能实现细节;
  • 能独立的给Zmap添加探针模块(Probe)与输出模块(Output);
  • 如有必要,可自己尝试改写Zmap的基础设施,如如何发包,如何生成IP等;

文章讲述对象:

  • zmap主要代码文件逐行解析;
  • zmap整体结构说明;
  • zmap的探针模块、输出模块的增删改;

Zmap资料与源码

如果要解析Zmap,那肯定是要知道Zmap的介绍以及Zmap的源码在哪。Zmap的介绍必然是看Zmap的论文,从论文中知道Zmap的基本架构以及应用,从Zmap的源码去了解最详实的实现细节,从更深处把握Zmap。
Zmap最初论文如下:
ZMap_Fast Internet-Wide Scanning and its Security Applications.pdf

Zmap项目仓库如下:
https://github.com/zmap/zmap
源码部分,Zmap的源码在该项目的/src目录下。
1690002868684.png

该目录下的主要文件及功能大体如下:

  • zmap.c Zmap的执行入口,main函数在其中,用来解析用户参数,设置zmap全局zconf变量,以及运行发包(sender)线程、收包线程(recv)和监控线程(monitor);

  • probe_modules 探针模块存放目标,该目录下的probe_module.c/h内的代码是用来管理所有探针的;

  • output_modules输出模块存放目录,该目录下的output_module.c/h内的代码时用来管理所有输出模块的;

  • aesrand.c/h``cyclic.c/h``shard.c/h``iterator.c/h这几个文件共同构成了zmap的IP生成机制;

  • send.c/h``recv.c/h``monitor.c/h这几个文件分别是zmap的发包(send)、收包(recv)和监控(monitor)三个线程主要执行内容的实现;

  • socket.c/h是zmap的sender、recv所用socket的来源;

  • state.c/h是zmap下的全局变量zconf、发包sender、收包recv的结构体定义以及实例化代码;

  • fieldset.c/h是zmap下存储数据包的相关结构体,可自定义存储包的字段等;

  • expression.c/h``filter.c/h是zmap下的包的过滤器机制的实现;

  • get_gateway.c/h是zmap下获取本地信息的实现,如本地网卡的物理地址、IP,本地网关的物理地址、IP等;

  • validate.c/h是zmap下检验数据包是否是由zmap发出而返回的校验的具体实现;

Zmap 入口执行流程(zmap.c文件)

零、定义线程参数结构体

1690005516012.png

一、解析用户参数

  1. 解析用户输入参数;
  2. 根据参数进行全局初始化以及填充全局配置变量zconf
    1. 日志模块;
      1. 用户日志
      2. 系统日志
    2. 输出模块配置;
    3. 探针模块配置;
    4. field字段填充;
    5. 目标IP分片配置;
    6. 带宽与速率配置;
    7. 配置zconf

二、按顺序依次开启三个线程,并等待三个线程执行完毕

该部分功能具体实现在同文件下的start_zmap()函数内。

  1. 配置网卡;
  2. 配置源IP;
  3. 配置网关IP;
  4. 配置硬件地址;
  5. output_modules 初始化;
  6. send_init()初始化,返回目标IP生成器;

// 以下是send_init()大致功能
// 1. 生成一个新的原始根和起始位置;
// 2. 确认发送数据包的源地址的偏移量;
// 3. 确认zmap可以扫描的端口范围;
// 4. Probe_module的全局初始化;
// 5. 确认是否指定带宽或速率;
// 6. 将带宽转换为速率;
// 7. 将默认的rate=-1转换为rate=10000,即10k pps;
// 8. 日志速率;
// 9. 获取硬件地址,交给probe;
// 10. 初始化检验凭证;
// 11. 设置信号处理,来通过sig_handler_increase_speed函数和sig_handler_decrease_speed控制发包速度;

  1. 初始化线程三个线程id;
  2. 完善recv线程参数,创建recv线程;
  3. 完善send线程参数,创建sender线程;
  4. monitor_init()初始化;
  5. 完善monitor线程参数,创建monitor线程;
  6. 等待所有的sender线程join;
  7. 等待recv线程join;
  8. 等待monitor线程join;
  9. 输出模块导出结果;
  10. 关闭以及释放之前申请的资源;

三、收尾工作

释放之前申请到的内存资源
1690005633921.png

核心模块

全局配置结构体zconf

Probe_modules 探针模块

output_modules 输出模块

IP 生成模块

fieldset 模块

发包/收包 模块

监控 模块

获取本地网络信息 模块

相关文章

PackageGenerators · Wiki · CMake / Community · GitLab
Cmake教程
【linux C】绑定任务到特定CPU(CPU亲和性)_cpu_set_t_tyrocjl的博客-CSDN博客
PF_RING简单介绍
DPDK解析—–DPDK,PF_RING对比
图解Linux网络包接收过程