【问题标题】:Scapy: Update field after building with post_build functionScapy:使用 post_build 函数构建后更新字段
【发布时间】:2015-10-09 11:53:11
【问题描述】:

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

假设我有一个图层

class MyLayer(Packet):

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

我需要如何修改这个类,以便它可以在构建时自动更新 LengthField?

【问题讨论】:

    标签: python layer packet scapy


    【解决方案1】:
    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:]
    

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

    【讨论】:

      【解决方案2】:

      使用post_dissect 中的新MyLayer 的长度修复字段大小。请注意,您不能使用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 字节有效负载(Raw)+ 1 字节(SomeField)+ 2 字节(LenField with fmt="H" == shortInt == 2bytes)

      【讨论】:

      • 谢谢,我也找到了使用post_build() 的解决方案,其中长度在二进制级别上添加,但这个解决方案似乎更好。
      • 不,post_dissect 是用于解剖(在获取数据包时),而不是在构建时
      猜你喜欢
      • 2014-05-28
      • 1970-01-01
      • 2015-12-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多