有条理地解析scapy中的数据包字段

时间:2014-06-16 09:36:43

标签: conditional decode scapy

我有以下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()版本,因此只能在有效负载级别运行。

1 个答案:

答案 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图层实现,因为它们几乎可以运用您需要的所有内容。