1

我正在 ScaPy 中编写一些协议,但很难理解 len 字段的工作原理。阅读http://trac.secdev.org/scapy/wiki/LengthFields后,我的开明程度也不逊色。

显然,我们有他们所谓的“lenfield”(保存字段的长度)和“varfield”(包含实际的可变长度字段)。但是,似乎唯一可以是 varfield 的字段是 PacketLenField、StrFixedLenField 和 StrLenField。其余的田地在哪里?为什么不能有可变长度的 BitField 或 XBitField?

例如我有:

BitFieldLenField('lenfield', None, 8, length_of='varfield')

这正确返回了 8 的长度(在这种情况下我想要的字段是 8 个八位字节/ 4 个十六进制对长)。到目前为止一切都很好。但是,当我尝试获取该字段时,似乎我唯一的选择是 StrLenField,它返回类似 'A\x81\x11\x11P 3'

所以,我的问题是:如何将该字段作为数据包中的实际十六进制取回?我是否缺少内置字段中的某些内容,或者我是否必须创建类似 XBitLenField 的内容?

谢谢你的帮助。

4

2 回答 2

3

这个答案是关于 Scapy 2.2.0 的。

LenFields 通常成对工作,如下所示:

FieldLenField("len", None, length_of="data")
StrLenField("data", "", length_from=lambda pkt:pkt.len)

注意length_of和如何length_from将两个字段链接在一起。该值告诉 Scapy 在发送length_of数据包时如何计算该"len"字段(注意默认值为,表示应该自动计算)。该值告诉 Scapy 在解析数据包时要输入多少字节。Nonelength_from"data"

有一个LenField可以单独使用的特殊字段。再次注意默认值None意味着它应该自动计算。发送时, Scapy 将简单地计算"len"为当前层之后的字节数。

LenField("len", None)

现在已经引入了长度字段,您可以使用 Python 将输出编码StrLenField为十六进制。

# In layer definition
BitFieldLenField("lenfield", None, 8, length_of="varfield")
StrLenField("varfield", "", length_from=lambda pkt:pkt.lenfield)

# In main script
print(pck[mylayer].varfield.encode("hex"))    # Replace "mylayer" with the name of your new layer
于 2012-05-16T15:01:56.200 回答
2

您可以重写 Fields 对象,例如 StrLenField:

# String to hex split by space
def str2hex(string):
    return ' '.join('%02x' % ord(b) for b in string)


class XStrLenField(scapy.fields.StrLenField):

    def i2repr(self, pkt, x):
        return str2hex(scapy.fields.StrLenField.i2m(self, pkt, x))

在你可以使用 field_desc[] 中的 XStrLenField 之后:

XStrLenField("rand", "", length_from=lambda x: x.len)
于 2012-07-31T13:07:56.373 回答