Files
volatility3/volatility/framework/layers/scanners/__init__.py
T
Mike Auty 29d41470a4 Mass reformat of typing imports
Relented on the strict import of direct objects/classes for the typing
module only.  Typing module components can be directly imported because
it makes the code really painful to read and write otherwise.

This is still in-line with the python style guide adopted from Google at
http://google.github.io/styleguide/pyguide.html section 2.2.
2018-12-16 13:04:22 +00:00

60 lines
2.2 KiB
Python

import re
from typing import Generator, List, Tuple, Union
from volatility.framework.interfaces import layers
from volatility.framework.layers.scanners import multiregexp
class BytesScanner(layers.ScannerInterface):
thread_safe = True
def __init__(self, needle: bytes) -> None:
super().__init__()
self.needle = self._check_type(needle, bytes)
def __call__(self, data: bytes, data_offset: int) -> Generator[int, None, None]:
"""Runs through the data looking for the needle, and yields all offsets where the needle is found
"""
find_pos = data.find(self.needle)
while find_pos >= 0:
if find_pos < self.chunk_size:
yield find_pos + data_offset
find_pos = data.find(self.needle, find_pos + 1)
class RegExScanner(layers.ScannerInterface):
# TODO: Document why this isn't thread safe?
thread_safe = False
def __init__(self, pattern: bytes, flags: int = 0) -> None:
super().__init__()
self.regex = re.compile(self._check_type(pattern, bytes), self._check_type(flags, int))
def __call__(self, data: bytes, data_offset: int) -> Generator[int, None, None]:
"""Runs through the data looking for the needle, and yields all offsets where the needle is found
"""
find_pos = self.regex.finditer(data)
for match in find_pos:
offset = match.start()
if offset < self.chunk_size:
yield offset + data_offset
class MultiStringScanner(layers.ScannerInterface):
thread_safe = True
def __init__(self, patterns: List[bytes]) -> None:
super().__init__()
self._check_type(patterns, list)
self._patterns = multiregexp.MultiRegexp()
for pattern in patterns:
self._check_type(pattern, bytes)
self._patterns.add_pattern(pattern)
self._patterns.preprocess()
def __call__(self, data: bytes, data_offset: int) -> Generator[Tuple[int, Union[str, bytes]], None, None]:
"""Runs through the data looking for the needles"""
for offset, pattern in self._patterns.search(data):
if offset < self.chunk_size:
yield offset + data_offset, pattern