如何从 pcap 文件中获取原始十六进制值?
How to get raw hex values from pcap file?
我一直在玩弄scapy,想通读并分析每个十六进制字节。到目前为止,我一直在使用 scapy 只是因为我目前不知道另一种方式。在我自己编写工具来浏览 pcap 文件之前,我想知道是否有一种简单的方法可以做到这一点。这是我到目前为止所做的。
packets = rdpcap('file.pcap')
tcpPackets = []
for packet in packets:
if packet.haslayer(TCP):
tcpPackets.append(packet)
当我 运行 type(tcpPackets[0])
我得到的类型是:
<class 'scapy.layers.l2.Ether'>
然后,当我尝试将 Ether 对象转换为字符串时,它给了我十六进制和 ascii 的混合(如随机括号和方括号所示)。
str(tcpPackets[0])
"b'$\xa2\xe1\xe6\xee\x9b(\xcf\xe9!\x14\x8f\x08\x00E\x00\x00[:\xc6@\x00@\x06\x0f\xb9\n\x00\x01\x04\xc6)\x1e\xf1\xc0\xaf\x07[\xc1\xe1\xff0y<\x11\xe3\x80\x18 1(\xb8\x00\x00\x01\x01\x08\n8!\xd1\x888\xac\xc2\x9c\x10%\x00\x06MQIsdp\x03\x02\x00\x05\x00\x17paho/34AAE54A75D839566E'"
我也尝试过使用 hexdump,但找不到解析它的方法。
我现在找不到合适的复制品,但这只是 str()
的 miss-use/miss-understanding。原始数据为字节格式,例如 x = b'moo'
.
当 str()
检索您的字节字符串时,它将通过调用 bytes
class/object 的 __str__
函数来实现。那将 return 代表自己。该表示形式将在开头保留 b
因为它被认为可以区分并使人们更容易理解它是一个字节对象,并且可以避免编码问题我猜 (所有这些都是猜测).
就像您尝试从终端访问 tcpPackets[0]
一样,它会调用 __repr__
并最有可能向您显示类似 <class 'scapy.layers.l2.Ether'>
的内容。
作为您可以试验的示例代码,试试这个:
class YourEther(bytes):
def __str__(self):
return '<Made Up Representation>'
print(YourEther())
显然 scapy 的 return 是另一种表示形式,而不仅仅是表示 "made up representation" 的静态字符串。但你可能明白了。
所以在 <class 'scapy.layers.l2.Ether'>
的情况下,它是 __repr__
或 __str__
函数可能 returns b'$\xa2\.......
而不是默认的 class表示 (这里可能会有一些更正,因为我没有 remember/know 行为的所有技术命名)。
作为解决方法,this 可能会解决您的问题:
hexlify(str(tcpPackets[0]))
您可能必须考虑所有前缀 b'
以及尾随 '
并相应地删除它们。 (注意:"
不会添加在开头或结尾,它们只是打印时控制台中的第二个表示。它们实际上并不存在于数据中)
Scapy 可能更倾向于使用 tcpPackets[0].dst
而不是抓取原始数据。但我对 Scapy 的经验很少,但它是一个抽象层是有原因的,它可能隐藏了原始数据,或者它在我现在找不到的核心文档中。
有关 __str__
描述的更多信息:
最后一点,那就是如果你真的想访问原始数据,你可以使用 Raw class: Raw load found, how to access?
来访问它
您可以将数据包的所有字节放入一个 numpy
数组,如下所示:
for p in tcpPackets:
raw_pack_data = np.frombuffer(p.load, dtype = np.uint8)
# Manipulate the bytes stored in raw_pack_data as you like.
这很快。在我的例子中,rdpcap
比将所有数据包放入一个类似 for
循环的大数组中用于 1.5GB 文件的时间长约 20 倍。
我一直在玩弄scapy,想通读并分析每个十六进制字节。到目前为止,我一直在使用 scapy 只是因为我目前不知道另一种方式。在我自己编写工具来浏览 pcap 文件之前,我想知道是否有一种简单的方法可以做到这一点。这是我到目前为止所做的。
packets = rdpcap('file.pcap')
tcpPackets = []
for packet in packets:
if packet.haslayer(TCP):
tcpPackets.append(packet)
当我 运行 type(tcpPackets[0])
我得到的类型是:
<class 'scapy.layers.l2.Ether'>
然后,当我尝试将 Ether 对象转换为字符串时,它给了我十六进制和 ascii 的混合(如随机括号和方括号所示)。
str(tcpPackets[0])
"b'$\xa2\xe1\xe6\xee\x9b(\xcf\xe9!\x14\x8f\x08\x00E\x00\x00[:\xc6@\x00@\x06\x0f\xb9\n\x00\x01\x04\xc6)\x1e\xf1\xc0\xaf\x07[\xc1\xe1\xff0y<\x11\xe3\x80\x18 1(\xb8\x00\x00\x01\x01\x08\n8!\xd1\x888\xac\xc2\x9c\x10%\x00\x06MQIsdp\x03\x02\x00\x05\x00\x17paho/34AAE54A75D839566E'"
我也尝试过使用 hexdump,但找不到解析它的方法。
我现在找不到合适的复制品,但这只是 str()
的 miss-use/miss-understanding。原始数据为字节格式,例如 x = b'moo'
.
当 str()
检索您的字节字符串时,它将通过调用 bytes
class/object 的 __str__
函数来实现。那将 return 代表自己。该表示形式将在开头保留 b
因为它被认为可以区分并使人们更容易理解它是一个字节对象,并且可以避免编码问题我猜 (所有这些都是猜测).
就像您尝试从终端访问 tcpPackets[0]
一样,它会调用 __repr__
并最有可能向您显示类似 <class 'scapy.layers.l2.Ether'>
的内容。
作为您可以试验的示例代码,试试这个:
class YourEther(bytes):
def __str__(self):
return '<Made Up Representation>'
print(YourEther())
显然 scapy 的 return 是另一种表示形式,而不仅仅是表示 "made up representation" 的静态字符串。但你可能明白了。
所以在 <class 'scapy.layers.l2.Ether'>
的情况下,它是 __repr__
或 __str__
函数可能 returns b'$\xa2\.......
而不是默认的 class表示 (这里可能会有一些更正,因为我没有 remember/know 行为的所有技术命名)。
作为解决方法,this 可能会解决您的问题:
hexlify(str(tcpPackets[0]))
您可能必须考虑所有前缀 b'
以及尾随 '
并相应地删除它们。 (注意:"
不会添加在开头或结尾,它们只是打印时控制台中的第二个表示。它们实际上并不存在于数据中)
Scapy 可能更倾向于使用 tcpPackets[0].dst
而不是抓取原始数据。但我对 Scapy 的经验很少,但它是一个抽象层是有原因的,它可能隐藏了原始数据,或者它在我现在找不到的核心文档中。
有关 __str__
描述的更多信息:
最后一点,那就是如果你真的想访问原始数据,你可以使用 Raw class: Raw load found, how to access?
来访问它您可以将数据包的所有字节放入一个 numpy
数组,如下所示:
for p in tcpPackets:
raw_pack_data = np.frombuffer(p.load, dtype = np.uint8)
# Manipulate the bytes stored in raw_pack_data as you like.
这很快。在我的例子中,rdpcap
比将所有数据包放入一个类似 for
循环的大数组中用于 1.5GB 文件的时间长约 20 倍。