解包会改变程序并扭曲输出吗?

2024-10-01 22:31:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经为scapy编写了一个函数,它可以帮助解析数据包。函数接收一个原始数据包并返回解析包含的数据所需的类。函数应该可以工作,但是它返回了错误的类。现在我测试了一些东西。我刚加了一行

struct.unpack("!B", packet)

在函数的开始,它实际上什么都不做,但是-这对我来说很奇怪-不知怎么的,这使得函数做了它应该做的。怎么会这样?我已经测试过很多次了。如果函数开头没有这一行,它就不能正常工作,但是,如果有这一行,它的行为应该是这样的,尽管输出似乎有点失真,我也不知道为什么

与行一起输出。它被扭曲了,有些线条在错误的地方,有些甚至被复制

###[ Ethernet ]###
  src       = 00:30:de:09:c7:76
  dst       = ff:ff:ff:ff:ff:ff
  type      = 0x800
  src       = 00:30:de:09:c7:83
###[ IP ]###
  type      = 0x800     version   = 4L

     ihl       = 5L
###[ IP ]###
     tos       = 0x0
     version   = 4L
     len       = 52
     ihl       = 5L
     id        = 312
     tos       = 0x0     flags     = DF

     frag      = 0L
     len       = 52
     ttl       = 64
     id        = 91
     proto     = udp
     flags     = DF
     frag      = 0L
     ttl       = 64
     proto     = udp
     chksum    = 0xb52d
     chksum    = 0xb60b
     src       = 192.168.1.4
     src       = 192.168.1.3
     dst       = 192.168.1.255     dst       = 192.168.1.255

     \options   \
     \options   \
###[ UDP ]###
###[ UDP ]###        sport     = 47808

        dport     = 47808
        sport     = 47808
        len       = 32
        dport     = 47808
        chksum    = 0x6cec
        len       = 32
###[ BVLC ]###
        chksum    = 0x79eb
           type      = 0x81
###[ BVLC ]###
           function  = ORIGINAL_BROADCAST_NPDU
           type      = 0x81
           length    = 24
           function  = ORIGINAL_BROADCAST_NPDU###[ NPDU ]###

              version   = 1
           length    = 24
              control   = 32L
###[ NPDU ]###
              dnet      = 65535
              version   = 1
              dlen      = 0              control   = 32L

              hopCount  = 255
              dnet      = 65535
###[ APDU ]###
              dlen      = 0
                 pduType   = UNCONFIRMED_SERVICE_REQUEST
              hopCount  = 255
                 reserved  = None
###[ APDU ]###
                 serviceChoice= I_AM
                 pduType   = UNCONFIRMED_SERVICE_REQUEST
                 \tagsField \
                 reserved  = None
                  |###[ Raw ]###
                 serviceChoice= I_AM
                  |  load      = '\xc4\x02\t\xc7\x83"\x01\xe0\x91\x00!\xde'
                 \tagsField \
                  |###[ Raw ]###
                  |  load      = '\xc4\x02\t\xc7v"\x01\xe0\x91\x00!\xde'

如果没有行,输出看起来是这样的,但是数据实际上是错误的。原始层实际上应该是APDU层

###[ Ethernet ]###
  dst       = ff:ff:ff:ff:ff:ff
  src       = 00:30:de:09:c7:83
  type      = 0x800
###[ IP ]###
     version   = 4L
     ihl       = 5L
     tos       = 0x0
     len       = 52
     id        = 105
     flags     = DF
     frag      = 0L
     ttl       = 64
     proto     = udp
     chksum    = 0xb5fd
     src       = 192.168.1.3
     dst       = 192.168.1.255
     \options   \
###[ UDP ]###
        sport     = 47808
        dport     = 47808
        len       = 32
        chksum    = 0x6cec
###[ BVLC ]###
           type      = 0x81
           function  = ORIGINAL_BROADCAST_NPDU
           length    = 24
###[ NPDU ]###
              version   = 1
              control   = 32L
              dnet      = 65535
              dlen      = 0
              hopCount  = 255
###[ Raw ]###
                 load      = '\x10\x00\xc4\x02\t\xc7\x83"\x01\xe0\x91\x00!\xde'

函数如下所示

def guessBACnetTagClass(packet, **kargs):

    """ Returns the correct BACnetTag Class needed to dissect
        the current tag

        @type    packet:    binary string
        @param   packet:    the current packet

        @type    cls:       class
        @return  cls:       the correct class for dissection
    """

    struct.unpack("!B", packet) # <------ with this line it works

    # Convert main tag Byte to binary format
    tagByteBinary = "{0:08b}".format(int(struct.unpack("!B", packet[0])[0]))

    # Extract information from main tag Byte
    tagNumber = int(tagByteBinary[0:4], 2)
    tagClass = BACnetTagClass.revDict()[int(tagByteBinary[4:5], 2)]
    lengthValueType = int(tagByteBinary[5:8], 2)

    # Tag is Application Tag
    if tagClass == BACnetTagClass.APPLICATION:
        clsName = BACnetApplicationTagClasses[tagNumber]
        cls = globals()[clsName]
        print cls
        return cls(packet, **kargs)

    # Tag is Context Specific Tag
    if tagClass == BACnetTagClass.CONTEXT_SPECIFIC:
        if lengthValueType == BACnetConstructedLVT.OPENING_TAG:
            cls = BACnetTag_Opening
        if lengthValueType == BACnetConstructedLVT.CLOSING_TAG:
            cls = BACnetTag_Closing

        # Check if a class was selected
        if cls is not None:
            print cls
            return cls(packet, **kargs)

这有什么意义吗?执行这个函数怎么能改变这么多输出


Tags: the函数srclenifpacketversiontype

热门问题