在ScaPy中使用LenFields

时间:2012-02-23 16:09:35

标签: python hex packet scapy

我在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的内容?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

这个答案与Scapy 2.2.0有关。

LenField通常成对使用,如下所示:

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

注意length_oflength_from如何将两个字段链接在一起。 length_of值告诉Scapy在发送数据包时如何计算"len"字段(请注意默认值为None,表示应自动计算) 。 length_from值告诉Scapy在解析数据包时输入"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

答案 1 :(得分:0)

您可以重写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)