学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1171

主题

[原创图文] UDP首部校验的计算

发表于 2019-5-3 18:44:22 | 查看: 6017| 回复: 0

例一

得出数值:

例二

UDP首部校验和的计算IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,算法如下:
在发送数据时,为了计算IP数据包的校验和。应该按如下步骤:
1.把IP数据包的校验和字段置为0;
2.把首部看成以16位为单位的数字组成,依次进行二进制反码求和;
3.把得到的结果存入校验和字段中。
在接收数据时,计算数据包的校验和相对简单,按如下步骤:
1.把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;

  1. 检查计算出的校验和的结果是否等于零(反码应为16个1);
    3.如果等于零,说明被整除,校验是和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。
    所谓的二进制反码求和,即为先进行二进制求和,然后对和取反。计算对IP首部检验和的算法如下:
    1.把IP数据包的校验和字段置为0;
    2.把首部看成以16位为单位的数字组成,依次进行二进制求和(注意:求和时应将最高位的进位保存,所以加法应采用32位加法);
    3.将上述加法过程中产生的进位(最高位的进位)加到低16位(采用32位加法时,即为将高16位与低16位相加,之后还要把该次加法最高位产生的进位加到低16位)
    4.将上述的和取反,即得到校验和。
    5.其中,二进制反码求和的计算方法:
    首先,我们计算如图所示的部分和。我们把每一列相加,如果有进位,就加到下一列。注意以下几点:

    ( 二进制记法的部分和)
    6.补充:此次操作是二进制求和,最后一列(左第一位得到数值是5=101)
    ①当我们加第1列(最右边一列)的时候,我们得到7。在二进制中,数7是111。我们保留最右边的1,把其余的位进到第2列和第3列。
    ②当我们加第2列时,我们计入从第1列来的进位。结果是8,它是二进制的1000。我们保留第一个位(最右边的),把其余100进位给第3列、第4列和第5列。
    ③对每一列重复以上过程。
    ④当我们加完最后一列时,我们有两个1没有列可以进行相加。这两个1在下一个步骤中应与部分和(Partial sum)相加。

    实战

    UDP报文图解


    为了弄清楚这些字段究竟是什么东西,下面我们使用 wireshark 来抓取一个 UDP 包来详细分析。为了制造这个 UDP 包,使用如下代码来向某 ip 地址发送一段数据(这个 ip 不一定非得实际存在,我们只需要观察基于 UDP 协议封装的数据,所以只要能被 wireshark 获取就行)

    import java.io.IOException;
    import java.net.*;
    public class Client {
    
    private DatagramSocket socket;
    
    public Client() throws SocketException {
        socket = new DatagramSocket();
    }
    public void run() throws IOException {
        InetAddress ip = InetAddress.getByName("11.111.111.111");
        String message = "hello UDP";
        byte[] buffer = message.getBytes();
        DatagramPacket sendPacket = new DatagramPacket(buffer, buffer.length, ip, 12345);
        socket.send(sendPacket);
    }
    public static void main(String[] args) throws IOException {
        new Client().run();
    }
    }

在运行之前,启动 wireshark 捕获,之后找到 Destination 栏为 11.111.111.111 的 UDP 行,类似于下图所示

然后找到这个 UDP 包的详细信息

以及这段信息的十六进制表示

key human hex
Source 192.168.1.106 c0a8 016a
Destination 11.111.111.111 0b6f 6f6f
Protocol UDP(17) 11
Length 17 11
Source Port 63549 f83d
Destination Port 12345 3039
Length 17 11
Checksum 0xb12d b12d
Data hello UDP 6865 6c6c 6f20 5544 5000

然后就可以开始着手校验和的计算了,但在这之前还应注意,上表中有一项 Checksum ,这是发送方根据发送内容计算出来校验和,接受方需要根据收到的内容重新计算一遍校验和,然后再对比两者。所以在接收方计算时应该忽略这里 Checksum 项。

校验和的计算规则

校验和的计算规则很简单,就是将上表中所有的 16 进制数加起来,之后取反码。有一点需要注意的是,如果遇到最高位进位,那么需要对结果进行回卷,意思是

简单来说,就是将要进的那一位加到尾部,上面是以二进制演示的,对于16进制同样适用。

温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-12-27 07:30 , Processed in 0.159780 second(s), 37 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表