You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Scapy自定义数据包中的多字段添加固定长度填充?

解决方案

要实现Scapy自定义层固定为指定字节长度,且在两个字符串字段后添加非包尾填充(后续可追加其他字段),可以通过动态计算填充长度并添加Padding字段来实现,具体步骤如下:

1. 修正原代码语法错误

原代码中StrLenField("field2", None, length_from=lambda pkt: pkt.field2_len)缺少闭合括号,先修正该问题。

2. 添加动态填充字段

在fields_desc中加入Padding字段,通过length_from参数计算需要填充的字节数:

  • 先定义层的固定总长度(比如FIXED_LENGTH = 10)
  • 填充长度 = 固定总长度 - (field1_len长度 + field1内容长度 + field2_len长度 + field2内容长度 + 后续其他字段总长度)

如果暂时没有后续其他字段,后续字段总长度按0计算,完整代码如下:

from scapy.all import Packet, FieldLenField, StrLenField, Padding, Ether

class Custom(Packet):
    FIXED_LENGTH = 10  # 硬编码固定层总长度
    fields_desc = [        
        FieldLenField("field1_len", None, fmt="B", length_of="field1"),
        StrLenField("field1", None, length_from=lambda pkt: pkt.field1_len),
        FieldLenField("field2_len", None, fmt="B", length_of="field2"),
        StrLenField("field2", None, length_from=lambda pkt: pkt.field2_len),
        # 动态计算填充长度:固定长度减去前面所有字段的总长度
        Padding(
            load=b"\x00",  # 填充字节,可自定义为其他值
            length_from=lambda pkt: Custom.FIXED_LENGTH - (1 + len(pkt.field1) + 1 + len(pkt.field2))
        )
        # 后续可添加其他字段,比如 ByteField("extra_field", 0)
        # 若添加其他字段,需在length_from计算中减去对应字段长度,例如 -1
    ]

# 测试数据包
packet = Ether() / Custom(field1="abcd", field2="efg")
# 查看Custom层字节内容
print("Custom层字节:", bytes(packet[Custom]))
# 验证Custom层长度
print("Custom层长度:", len(packet[Custom]))

3. 针对示例需求调整(忽略长度字段场景)

如果你的目标是让field1+field2+填充的内容为abcdefg000(共10字节),且不需要长度字段,可修改为直接使用固定长度字符串字段加填充:

from scapy.all import Packet, StrFixedLenField, Padding, Ether

class Custom(Packet):
    DATA_FIXED_LENGTH = 10  # field1+field2+填充的固定长度
    fields_desc = [        
        StrFixedLenField("field1", "", length=4),  # 固定4字节长度
        StrFixedLenField("field2", "", length=3),  # 固定3字节长度
        Padding(
            load=b"\x00",
            length_from=lambda pkt: Custom.DATA_FIXED_LENGTH - (len(pkt.field1) + len(pkt.field2))
        )
        # 后续可添加其他字段
    ]

packet = Ether() / Custom(field1="abcd", field2="efg")
print("目标数据部分字节:", bytes(packet[Custom][:10]))  # 输出 b'abcdefg\x00\x00\x00'

关键说明

  • Padding字段的load参数可自定义填充字节(比如b"\x00"或其他业务需要的值)
  • 若后续添加其他字段,必须在length_from的计算中减去这些字段的总长度,确保整个层的总长度符合要求
  • 固定长度可设为类属性,方便后续调整

内容的提问来源于stack exchange,提问作者Attila M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:05:17