我有以下scapy图层:
基础层(实际上是来自scapy.sctp的SCTPChunkData(),但下面是它的简化版本):
class BaseProto(Packet):
fields_desc = [ # other fields omitted...
FieldLenField("len", None, length_of="data", adjust = lambda pkt,x:x+6),
XIntField("protoId", None),
StrLenField("data", "", length_from=lambda pkt: pkt.len-6),
]
我的图层定义如下:
MY_PROTO_ID = 19
class My_Proto(Packet):
fields_desc = [ ShortField ("f1", None),
ByteField ("f2", None),
ByteField ("length", None), ]
如果来自 BaseProto的 protoId 字段,我想将 BaseProto 中的数据字段解析为 MyProto 等于MY_PROTO_ID。
我为此尝试过使用bind_layers(),但后来我意识到这个函数将“告诉”scapy如何剖析基础层的有效负载,而不是特定的字段。在我的示例中, data 字段实际上将我要解码的所有字节存储为 MyProto 。
此外,guess_payload_class()没有帮助,因为它只是一个不同的(更强大的)bind_layers()版本,因此只能在有效负载级别运行。
答案 0 :(得分:0)
您必须将图层链接为BaseProto()/My_Proto()
并使用bind_layers(first_layer, next_layer, condition)
根据条件对其进行scapy剖析。
这是它应该是什么样子。
PROTO_IDS = {
19: 'my_proto',
# define all other proto ids
}
class BaseProto(Packet):
name = "BaseProto"
fields_desc = [ # other fields omitted...
FieldLenField("len", None, length_of="data", adjust = lambda pkt,x:x+6),
IntEnumField("protoId", 19, PROTO_IDS),
#StrLenField("data", "", length_from=lambda pkt: pkt.len-6), #<-- will be the next layer, extra data will show up as Raw or PADD
]
class My_Proto(Packet):
name = "MyProto Sublayer"
fields_desc = [ ShortField ("f1", None),
ByteField ("f2", None),
ByteField ("length", None), ]
# BIND TCP.dport==9999 => BaseProto and BaseProto.protoId==19 to My_Proto
bind_layers(TCP, BaseProto, dport=9999)
# means: if BaseProto.protoId==19: dissect as BaseProto()/My_Proto()
bind_layers(BaseProto, My_Proto, {'protoId':19})
#example / testing
bytestr = str(BaseProto()/My_Proto()) # build
BaseProto(bytestr).show() # dissect
作为参考,请查看scapy-ssl_tls图层实现,因为它们几乎可以运用您需要的所有内容。