簡體   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