Skip to content

ql.mem.search uses regular expression #1135

@LukeSerne

Description

@LukeSerne

Describe the bug
ql.mem.search raises an exception for some input needles, and wrong results for other needles. This is because the needle is interpreted as a regular expression, which is not documented anywhere and quite unusual.

Sample Code

import qiling
from qiling.const import QL_ARCH

ql = qiling.Qiling(code=bytes(10), archtype=QL_ARCH.ARM, ostype='linux')

assert ql.mem.search(b"(") == []  # exception here (see below)
assert ql.mem.search(b".") == []  # wrong result (and thus assertion error) here

Real behavior

$ python main.py 
Traceback (most recent call last):
  File "main.py", line 6, in <module>
    assert ql.mem.search(b"(") == []  # exception here (see below)
  File "~/lib/python3.8/site-packages/qiling/os/memory.py", line 351, in search
    local_results = (match.start(0) + lbound for match in re.finditer(needle, haystack))
  File "/usr/lib/python3.8/re.py", line 248, in finditer
    return _compile(pattern, flags).finditer(string)
  File "/usr/lib/python3.8/re.py", line 304, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/usr/lib/python3.8/sre_compile.py", line 764, in compile
    p = sre_parse.parse(p, flags)
  File "/usr/lib/python3.8/sre_parse.py", line 948, in parse
    p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0)
  File "/usr/lib/python3.8/sre_parse.py", line 443, in _parse_sub
    itemsappend(_parse(source, state, verbose, nested + 1,
  File "/usr/lib/python3.8/sre_parse.py", line 836, in _parse
    raise source.error("missing ), unterminated subpattern",
re.error: missing ), unterminated subpattern at position 0

Expected behavior
No exception and both assertions succeeding.

Additional context
The problem is the use of re.finditer in the below line of code. This interprets the value 40 as the character (, which in turn is interpreted as a regular expression.

local_results = (match.start(0) + lbound for match in re.finditer(needle, haystack))

This issue can be fixed by escaping the provided needle using something like needle = re.escape(needle) at some earlier part in the ql.mem.search function.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions