繁体   English   中英

Python对二进制字符串的重新搜索

[英]Python re search on binary strings

我正在尝试使用 python re 来查找二进制子字符串,但出现了一个令人费解的错误。

这是一个演示该问题的小示例(python3):

import re

memory = b"\x07\x00\x42\x13"

query1 = (7).to_bytes(1, byteorder="little", signed=False)
query2 = (42).to_bytes(1, byteorder="little", signed=False)

# Works
for match in re.finditer(query1, memory):
    print(match.group(0))

# Causes error
for match in re.finditer(query2, memory):
    print(match.group(0))

第一个循环正确打印b'\\x07'而第二个给出以下错误:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python3.7/re.py", line 230, in finditer
    return _compile(pattern, flags).finditer(string)
  File "/usr/lib/python3.7/re.py", line 286, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/usr/lib/python3.7/sre_compile.py", line 764, in compile
    p = sre_parse.parse(p, flags)
  File "/usr/lib/python3.7/sre_parse.py", line 930, in parse
    p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0)
  File "/usr/lib/python3.7/sre_parse.py", line 426, in _parse_sub
    not nested and not items))
  File "/usr/lib/python3.7/sre_parse.py", line 651, in _parse
    source.tell() - here + len(this))
re.error: nothing to repeat at position 

对于上下文,我试图以与作弊引擎等工具类似的方式在程序的内存空间中找到特定的整数。 它是在 gdb 中使用 python 脚本完成的。

-- 注 1 --

我怀疑这可能与 42 在 ascii 中可以表示为*而 7 不是这样的事实有关。 例如,如果您打印您得到的查询字符串:

>>> print(query1)
b'\x07'
>>> print(query2)
b'*'

- 笔记2 -

实际上看起来这与字符串是否可以用 ascii 表示无关。 如果你运行:

import re

memory = b"\x07\x00\x42\x13"

for i in range(255):
    query = i.to_bytes(1, byteorder="little", signed=False)

    try:
        for match in re.finditer(query, memory):
            pass
    except:
        print(str(i) + " failed -- as ascii: " + chr(i))

它给:

40 failed -- as ascii: (
41 failed -- as ascii: )
42 failed -- as ascii: *
43 failed -- as ascii: +
63 failed -- as ascii: ?
91 failed -- as ascii: [
92 failed -- as ascii: \

所有失败的字节都代表特殊的重新语法的字符。 这让我认为 python re 首先打印查询字符串,然后对其进行解析以进行搜索。 我想这并非完全不合理,但仍然很奇怪。

实际上在写这个问题时,我找到了一个解决方案,它首先将查询包装在re.escape(query) ,它将在每个特殊字符之前插入一个\\但我仍然会发布这个问题,以防它对其他人有帮助或如果有人要添加更多。

\\x42对应于* ,这是一个特殊的正则表达式字符。 您可以改为使用

re.finditer(re.escape(query2), memory)

这将转义查询(将*转换为\\* )并在字符串中找到字符*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM