我正在尝试在Scapy中构建一个包含“LengthField”的自己的图层。此字段应包含此图层的总大小+后面的所有内容。 我知道“post_build”方法是我需要实现的目标,我试图理解它是如何在Scapy文档中使用的,但我不明白。
假设我有一个图层
class MyLayer(Packet):
name = "MyLayer"
fields_desc = [
ByteField("SomeField", 1),
IntField("LengthField", 0)
]
如何修改此类以便它可以在构建时自动更新LengthField?
答案 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'
您可以打印p
和pay
来理解代码:
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)