Python3中re.search匹配二进制XOR加密数据失败问题求助
问题描述
我读取32位Windows可执行文件为二进制数据:
with open('file.exe', 'rb') as f: blob = f.read()
文件中存在一段单字节XOR加密的内容,已知解密后的片段,因此编写暴力破解代码尝试找出密钥:
for x in range(0, 255): known_string = bytearray('\x00\x01\x00\x01\x00'.encode()) for i in range(len(known_string)): known_string[i] ^= x if re.search(bytes(known_string), blob): return x
这段代码在部分场景有效,但当密钥x大于31时,异或后的字节显示为ASCII字符而非\x..格式,导致re.search匹配失败。比如目标密钥为0x50时,预期得到bytearray(b'\x50\x51\x50\x51\x50'),实际得到bytearray(b'23232'),我误以为格式差异导致无法匹配。
补充上下文
后来了解到字节的显示形式不影响实际值,但新增一段已知解密序列后,两段序列间隔3个未知字节,因此用正则搜索实现:
for x in range(256): sequence_1 = bytes(byte ^ x for byte in b'\x00\x01\x00\x01\x00') sequence_2 = bytes(byte ^ x for byte in b'\x00\x02\x00\x01\x00') full_sequence = sequence_1 + b'...' + sequence_2 if re.search(full_sequence, blob): return x
当x=0x50时,full_sequence为b'PQPQP...PRPQP',而blob中实际存在b'...PQPQPRPPPRPQP...'序列,但re.search始终无法匹配。
解决方案
字节显示形式的误解:
b'23232'和b'\x50\x51\x50\x51\x50'是完全等价的二进制数据,只是Python的显示方式不同——当字节对应可打印ASCII字符时,会显示字符,否则显示十六进制转义。实际存储的二进制值没有区别,这不是匹配失败的原因。正则表达式的错误使用:你用
b'...'作为间隔的三个未知字节,但在正则语法中,.是匹配任意单个字符的通配符,而b'...'是字面量的三个.字符(ASCII码0x2E),这和blob中实际的三个任意字节不匹配。正确的做法是使用正则表达式语法b'.{3}'来表示任意三个字节,修改后的代码如下:
import re for x in range(256): sequence_1 = bytes(byte ^ x for byte in b'\x00\x01\x00\x01\x00') sequence_2 = bytes(byte ^ x for byte in b'\x00\x02\x00\x01\x00') # 构造正则模式:sequence_1 + 任意3字节 + sequence_2 pattern = sequence_1 + b'.{3}' + sequence_2 if re.search(pattern, blob): print(f"找到密钥:0x{x:02X}") break
这样就能正确匹配两段序列之间间隔任意三个字节的情况。
内容的提问来源于stack exchange,提问作者user4414119

