Scapy:使用post_build函数构建后更新字段

时间:2015-10-09 11:53:11

标签: python layer packet scapy

我正在尝试在Scapy中构建一个包含“LengthField”的自己的图层。此字段应包含此图层的总大小+后面的所有内容。 我知道“post_build”方法是我需要实现的目标,我试图理解它是如何在Scapy文档中使用的,但我不明白。

假设我有一个图层

class MyLayer(Packet):

    name = "MyLayer"
    fields_desc = [
                   ByteField("SomeField", 1),
                   IntField("LengthField", 0)
                   ]

如何修改此类以便它可以在构建时自动更新LengthField?

2 个答案:

答案 0 :(得分:2)

def post_build(self, p, pay):
    p += pay
    if self.LengthField is None:
        p = p[:1] + struct.pack("I", len(p)) + p[5:]
        hexdump(p)
    return p

您可以参考源代码中的一些示例:

class HCI_Command_Hdr(Packet):
    name = "HCI Command header"
    fields_desc = [XLEShortField("opcode", 0),
                   ByteField("len", None), ]

    def post_build(self, p, pay):
        p += pay
        if self.len is None:
            p = p[:2] + struct.pack("B", len(pay)) + p[3:]
        return p

结果是:

>>> (HCI_Command_Hdr()/"1234567").show2()
###[ HCI Command header ]### 
  opcode= 0x0
  len= 7
###[ Raw ]### 
     load= '1234567'

您可以打印ppay来理解代码:

 p[:2] + struct.pack("B", len(pay)) + p[3:]

然后,修改它以满足您的需求。

答案 1 :(得分:-1)

使用MyLayer中新post_dissect的长度修复字段大小。请注意,您无法使用len(str(self))进行长度计算,因为str()调用do_dissect会导致无休止的递归。

class MyLayer(Packet):
    name = "MyLayer"
    fields_desc = [
                   ByteField("SomeField", 1),
                   LenField("LengthField", None),   # calcs len(pkt.payload)
                   ]
    def post_dissect(self, s):
        self.LengthField += len(str(self.__class__()))     # add this layer size by creating a new temporary layer and calculating its size.
        return Packet.post_dissect(self, s)

该值将在show2()

时计算
(MyLayer()/Raw().show2()

结果

###[ MyLayer ]###
  SomeField = 1
  LengthField= 9
###[ Raw ]###
     load      = 'hihiii'

其中9 = 6字节有效负载(原始)+ 1字节(SomeField)+ 2字节(LenField,fmt =“H”== shortInt == 2bytes)