今天请新用户帮忙。在
我正试着在斯卡比增加一个新的协议。这个原型有点特别,因为他是一个非常多形的人。我的意思是,他的结构和长度与某些场有关。通常,有一个'function'ByteField,更改此值将更改所有下一个字段。在
所以,让我们看看这段代码,它说明了我想做什么。有一个简单的多态数据包,其主常量结构为//header//parameter//data//。变量在参数和数据结构内部。在
### VIRTUAL PARAMETER PACKET
class myPacketParam(Packet):
name = "Virtual Param Packet"
### REAL PARAMETER PACKET ONE
class myPacketParamOne(myPacketParam):
name = "Parameter Type One"
fields_desc = [
ByteField("paramOne", 0x0),
ByteField("paramTwo", 0x0)
]
### REAL PARAMETER PACKET TWO
class myPacketParamTwo(myPacketParam):
name = "Parameter Type Two"
fields_desc = [
FieldLenField("length", None, length_of="stringOpt"),
StrLenField("stringOpt", "BAGUETTE", # Random default value
length_from=lambda pkt: pkt.length)
]
### VIRTUAL DATA PACKET
class myPacketData(Packet):
name = "Virtual Data Packet"
### REAL DATA PACKET ONE
class myPacketDataOne(myPacketData):
name = "Data Type One"
fields_desc = [
ByteField("length", 2),
ByteField("dataOne", 0x0),
ByteField("dataTwo", 0x0)
]
### REAL DATA PACKET TWO
class myPacketDataTwo(myPacketData):
name = "Data Type Two"
fields_desc = [
FieldLenField("length", None, length_of="data"),
StrLenField("data", "SAUCISSON", length_from=lambda pkt: pkt.length) # Random default value
]
### MAIN PACKET
class myPacket(Packet):
name = "myPacket"
def changeFunction(self, value, data):
if value == 0x1:
self.param = myPacketParamOne()
self.data = myPacketDataOne()
else:
self.param = myPacketParamTwo()
self.data = myPacketDataTwo()
fields_desc = [
ByteField("version", 0x15),
ActionField(ByteField("function", 0x1), "changeFunction"),
FieldLenField("lengthParam", None, length_of="param"),
FieldLenField("lengthData", None, length_of="data"),
PacketField("param", myPacketParamOne(), myPacketParam),
PacketField("data", myPacketDataOne(), myPacketData)
]
重点是主包myPacket中的“param”和“data”字段。例如,“param”packetfield正在询问myPacketParam包。但我希望这个包是虚拟的:后面真正的包可以是myPacketParamOne或myPacketParamTwo。数据也是一样。在
构建这个包看起来不错。在
^{pr2}$但我想解剖是不能正常工作的。在
p.show2()
###[ myPacket ]###
version = 21
function = 2
lengthParam= 10
lengthData= 11
\param \
|###[ Virtual Param Packet ]###
|###[ Raw ]###
| load = 'BAGUETTE\x00\tSAUCISSON'
\data \
|###[ Data Type One ]###
| length = 2
| dataOne = 0
| dataTwo = 0
这是完全错误的。在
我找到了一些解决办法。通过示例使用conditionalField。但在我真正的原型里,在同一个包里有很多形态。因为字段不能有相同的名称,所以在主数据包中没有一个简单的param字段,而是每个案例的新名称。所以,我的scapy实现的真正使用是非常无聊和不简单的。在
第二种解决方案是取消header、param和data的链接。所以可以使用这样的协议:p=myPacket()/myPacketParamOne()/myPacketDataOne()。但这对我来说并不是一个好的解决方案,因为我真正的协议在每个部分之间都有依赖关系,对于我的scapy实现的用户来说,它仍然很复杂。在
所以,如果可能的话,我正在寻找解决方案: -关于主要结构(标题/参数/数据) -这个协议的简单使用(myPacket.param.想要什么获取param而不考虑它是什么类型的param包(当然,在这种param packe中存在什么样的字段))
我觉得解决的办法可以是重新定义每个“虚拟包”中的do_dissect函数,或者专门为虚拟包编写一个新的域,但是我尝试了很多东西,都没有成功。在
我希望我是可以理解的。在
提前感谢:)
内森
(这有点老了^^)
自从Scapy的最新版本(为了安全起见,使用2.4.3rc+),我们有了一个新的
MultipleTypeField
,它似乎在做你想要的。下面是回归测试中的一个示例:它允许您根据条件将同一字段具有多种类型
相关问题 更多 >
编程相关推荐