Add in new multistring scanner based on re

Unfortunately in tests it turned out re was faster than a python
implementation of Wu-Manber.  The Wu-Manber code has been left (because
why not) but it's not really advantageous over the re builtin since
it's compiled in C.
This commit is contained in:
Mike Auty
2018-01-24 20:22:00 +00:00
parent 4bb1161490
commit ccd00afdb2
2 changed files with 25 additions and 2 deletions
@@ -2,7 +2,7 @@ import re
import typing
from volatility.framework.interfaces import layers
from volatility.framework.layers.scanners import wumanber
from volatility.framework.layers.scanners import multiregexp
class BytesScanner(layers.ScannerInterface):
@@ -44,7 +44,7 @@ class MultiStringScanner(layers.ScannerInterface):
def __init__(self, patterns: typing.List[bytes]) -> None:
super().__init__()
self._check_type(patterns, list)
self._patterns = wumanber.WuManber()
self._patterns = multiregexp.MultiRegexp()
for pattern in patterns:
self._check_type(pattern, bytes)
self._patterns.add_pattern(pattern)
@@ -0,0 +1,23 @@
import re
import typing
class MultiRegexp(object):
"""Algorithm for multi-string matching"""
def __init__(self) -> None:
self._pattern_strings = [] # type: typing.List[bytes]
self._regex = re.compile(b'')
def add_pattern(self, pattern: bytes) -> None:
self._pattern_strings.append(pattern)
def preprocess(self) -> None:
self._regex = re.compile(b'|'.join(map(re.escape, self._pattern_strings)))
def search(self, haystack: bytes) \
-> typing.Generator[typing.Tuple[int, typing.Union[str, bytes]], None, None]:
if not isinstance(haystack, bytes):
raise TypeError("Search haystack must be a byte string")
for match in re.finditer(self._regex, haystack):
yield (match.start(0), match.group())