了解Python struct.pack和二进制输入

了解Python struct.pack和二进制输入,python,scapy,Python,Scapy,以下函数为键接受二进制4字节键buf是二进制输入,与4字节键进行异或运算 def four_byte_xor(buf, key): #key = struct.pack(b">I", key) # removed for binary processing buf = bytearray(buf) for offset in range(0, len(buf), 4): for i, byte in enumerate(key):

以下函数为
接受二进制4字节键
buf
是二进制输入,与4字节键进行异或运算

def four_byte_xor(buf, key):
    #key = struct.pack(b">I", key) # removed for binary processing
    buf = bytearray(buf)
    for offset in range(0, len(buf), 4):
        for i, byte in enumerate(key):
            buf[offset + i] = chr(buf[offset + i] ^ ord(byte))
    return str(buf)
为了通过
str(p.payload.payload.payload)[:4]
key
指定二进制数据,我从
四字节异或()中删除了
key=struct.pack(b>I),key)
。如果长度以4个字节结束,则可以正常工作,否则会触发以下错误(请参阅下面的测试)

以下是一些测试,包括输入xor'd和一个导致00的键,第一个测试成功:

'ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD'
'ABCD'

bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
'ABCD'
第二次测试未成功,并以A或1个额外字节结束:

'ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDA'
'ABCD'
Traceback (most recent call last):
  File "./decode.py", line 36, in <module>
    process_packets()
  File "./decode.py", line 34, in process_packets
    out_buf.write(bin_four_byte_xor(pkt_payload, pkt_offset))
  File "./decode.py", line 22, in bin_four_byte_xor
    buf[offset + i] = chr(buf[offset + i] ^ ord(byte))
IndexError: bytearray index out of range
“ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDA”
“ABCD”
回溯(最近一次呼叫最后一次):
文件“/decode.py”,第36行,在
处理数据包()
文件“/decode.py”,第34行,正在处理的数据包
out buf.write(二进制四字节异或(pkt_有效负载,pkt_偏移量))
文件“/decode.py”,第22行,二进制四字节
buf[offset+i]=chr(buf[offset+i]^ord(字节))
索引器:bytearray索引超出范围

可以修改
four\u byte\u xor()
以接受不同的
buf
长度吗?

当然,可以修改函数以接受不同的键长度。比如说

def many_byte_xor(buf, key):
    buf = bytearray(buf)
    for i, bufbyte in enumerate(buf):
        buf[i] = chr(bufbyte ^ ord(key[i % len(key)]))
    return str(buf)
循环键的所有字符(模版本的
itertools.cycle
)。这就产生了

>>> many_byte_xor("AABAA", "AB")
'\x00\x03\x03\x03\x00'
>>> many_byte_xor("ABCDABCD", "ABCD")
'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> many_byte_xor("ABCDABCDA", "ABCD")
'\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> many_byte_xor("ABCDABCDAB", "ABCD")
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> many_byte_xor("ABCDABCDAB", "ABC")
'\x00\x00\x00\x05\x03\x01\x02\x06\x02\x03'

哪个IIUC是您想要的。

您在
linehextump
中出现的错误是因为该函数不返回十六进制值,而只是打印它们。我很高兴看到你放弃了那种方法。直接使用二进制数据作为密钥更有意义。
buff
bytearray是长度为4的精确倍数吗?如果没有,当你在最后得到额外的1-3字节时,你会得到一个超出范围的错误。虽然我已经测试了单个数据包,但可能不是这样,它似乎工作正常。当我尝试通过缓冲区传送多个数据包时,就是当我收到超出范围的索引时。它们应该是在迭代之间清除
buf
键的东西,还是自动的?这个问题几乎提供了一个答案,但并不完全如此。在您提到您尝试的其他方法之前,您是否可以包括失败的精确代码、未排序(涉及文件名时除外)错误消息和函数调用(例如
four\u byte\u xor(b'a',42)
),以便程序成为一个自包含的示例?如果您不知道确切的参数,可以使用
print(repr(buf))
在实时系统中显示它们。似乎存在一些差异。更新了问题,输出来自
print(repr(buf))
。为了提高效率,您可以在循环之前添加
key=bytearray(key)
key\u len=len(key)
,然后将循环中的赋值简化为
buf[i]=bufbyte^key[i%key\u len]
。因为
bytearray
s只是小整数的可变序列,所以不需要
ord()
chr()
函数调用。