python – Virtual PacketField:如何处理多态protocole?
我是一个新的scapy用户,今天我要求你的帮助.
我正在尝试在scapy中添加一个新的protocole.这个protocole有点特别,因为他是多态的.通过变形,我的意思是他的结构和他的长度取决于某些领域.通常,有一个’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",ByteField("dataTwo",0x0) ] ### REAL DATA PACKET TWO class myPacketDataTwo(myPacketData): name = "Data Type Two" fields_desc = [ FieldLenField("length",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",length_of="param"),FieldLenField("lengthData",PacketField("param",myPacketParamOne(),myPacketParam),PacketField("data",myPacketDataOne(),myPacketData) ] 好吧,关键是主数据包“myPacket”中的“param”和“data”字段.例如,“param”packetfield正在询问myPacketParam数据包.但我希望这个数据包是虚拟的:后面的真正数据包可以是myPacketParamOne或myPacketParamTwo.数据同样如此. 构建此数据包看起来没问题. p = myPacket() p.show() # great result p.function = 2 p.show() ###[ myPacket ]### version = 21 function = 2 lengthParam= None lengthData= None param |###[ Parameter Type Two ]### | length = None | stringOpt = 'BAGUETTE' data |###[ Data Type Two ]### | length = None | data = 'SAUCISSON' 但我猜解剖是行不通的. p.show2() ###[ myPacket ]### version = 21 function = 2 lengthParam= 10 lengthData= 11 param |###[ Virtual Param Packet ]### |###[ Raw ]### | load = 'BAGUETTEx00tSAUCISSON' data |###[ Data Type One ]### | length = 2 | dataOne = 0 | dataTwo = 0 这是完全错误的. 我找到了一些解决方案通过示例使用conditionalField.但在我真正的protocole中,同一个数据包中有很多形态.并且因为字段不能具有相同的名称,所以主数据包中没有简单的param字段,而是每个案例的新名称.因此,真正利用我的scapy实现是非常无聊而且不简单. 第二种解决方案是取消链接标题,参数和数据.所以你可以像这样使用protocole:p = myPacket()/ myPacketParamOne()/ myPacketDataOne().但对我来说这不是一个好的解决方案,因为我的真正的protocole在每个部分之间都存在依赖关系,而且对于我的scapy实现的用户来说仍然很复杂. 所以,如果可能的话,我正在寻找一个解决方案: 我觉得解决方案可以是在每个“虚拟数据包”中重新定义do_dissect函数,或者为新的字段编码,特别是对于虚拟数据包,但我尝试了许多事情而没有成功. 我希望我能理解. 先感谢您 :) 弥敦道 解决方法
(这有点旧^^)
自从Scapy的最新版本(使用2.4.3rc是安全的)以来,我们有一个新的MultipleTypeField似乎在做你想要的.这是回归测试中的一个例子: class DebugPacket(Packet): fields_desc = [ ByteEnumField("atyp",0x1,{0x1: "IPv4",0x3: "DNS",0x4: "IPv6"}),MultipleTypeField( [ # IPv4 (IPField("addr","0.0.0.0"),lambda pkt: pkt.atyp == 0x1),# DNS (DNSStrField("addr",""),lambda pkt: pkt.atyp == 0x3),# IPv6 (IP6Field("addr","::"),lambda pkt: pkt.atyp == 0x4),],StrField("addr","") # By default ),] 它允许您根据条件使具有多种类型的相同字段 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |