mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-10-01 22:14:53 +02:00
Ensure scanners don't return duplicates in the overlap.
This commit is contained in:
@@ -24,6 +24,7 @@ PAGE_SIZE = 0x1000
|
||||
PHYS_MASK = 0xfffffffffff
|
||||
PML4_ENTRY_SIZE = int((2 ** 64) / 512)
|
||||
|
||||
|
||||
class PML4EScanner(interfaces.layers.ScannerInterface):
|
||||
overlap = 0x4000
|
||||
|
||||
@@ -32,7 +33,7 @@ class PML4EScanner(interfaces.layers.ScannerInterface):
|
||||
|
||||
# go through each page in the data, look for signs of PML4
|
||||
for page_offset in range(0, len(data), PAGE_SIZE):
|
||||
entries = struct.unpack('<512Q', data[page_offset:page_offset+PAGE_SIZE])
|
||||
entries = struct.unpack('<512Q', data[page_offset:page_offset + PAGE_SIZE])
|
||||
valid_entries = []
|
||||
invalid_count = 0
|
||||
user_count = 0
|
||||
@@ -57,7 +58,8 @@ class PML4EScanner(interfaces.layers.ScannerInterface):
|
||||
|
||||
# print("[%x] inv: %d val: %d" % (data_offset + page_offset, invalid_count, len(valid_entries)))
|
||||
if invalid_count == 0 and len(valid_entries) > 4 and user_count != 0 and supervisor_count != 0:
|
||||
yield (data_offset + page_offset, valid_entries)
|
||||
if page_offset < self.chunk_size:
|
||||
yield (data_offset + page_offset, valid_entries)
|
||||
|
||||
|
||||
def find_pt_mapping(ctx, layer_name, entries):
|
||||
@@ -69,6 +71,7 @@ def find_pt_mapping(ctx, layer_name, entries):
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def find_pd_mapping(ctx, layer_name, entries):
|
||||
for entry in entries:
|
||||
# valid entry?
|
||||
@@ -92,6 +95,7 @@ def find_pd_mapping(ctx, layer_name, entries):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def find_pdpt_mapping(ctx, layer_name, entries):
|
||||
for entry in entries:
|
||||
# valid entry?
|
||||
|
||||
@@ -135,7 +135,8 @@ class NlpDtbScanner(interfaces.layers.ScannerInterface):
|
||||
entry_num = entry_num + 1
|
||||
|
||||
if invalid_count == 0 and len(valid_entries) > 3 and user_count != 0 and supervisor_count != 0:
|
||||
yield (data_offset + page_offset, valid_entries)
|
||||
if page_offset < self.chunk_size:
|
||||
yield (data_offset + page_offset, valid_entries)
|
||||
|
||||
|
||||
class NlpDtbfinder(interfaces.automagic.AutomagicInterface):
|
||||
|
||||
@@ -59,7 +59,8 @@ class PdbSignatureScanner(interfaces.layers.ScannerInterface):
|
||||
self._RSDS_format.unpack(data[sig + 4:name_offset])
|
||||
|
||||
GUID = (16 * '{:02X}').format(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, ga, gb, gc, gd, ge, gf)
|
||||
yield (GUID, a, pdb_name, data_offset + sig)
|
||||
if sig < self.chunk_size:
|
||||
yield (GUID, a, pdb_name, data_offset + sig)
|
||||
sig = data.find(b"RSDS", sig + 1)
|
||||
|
||||
|
||||
|
||||
@@ -226,7 +226,8 @@ class PageMapScanner(interfaces.layers.ScannerInterface):
|
||||
for page_offset in range(0, len(data), 0x1000):
|
||||
result = test(data, data_offset, page_offset)
|
||||
if result is not None:
|
||||
yield (test, result[0])
|
||||
if result[0] < self.chunk_size:
|
||||
yield (test, result[0])
|
||||
|
||||
|
||||
class WintelHelper(interfaces.automagic.AutomagicInterface):
|
||||
|
||||
@@ -43,6 +43,10 @@ class ScannerInterface(validity.ValidityRoutines, metaclass = ABCMeta):
|
||||
scanning the chunk will take (ie, do not set an excessively large chunksize
|
||||
and try not to take a significant amount of time in the __call__ method).
|
||||
|
||||
Scanners must NOT return results found *after* self.chunk_size (ie, entirely contained
|
||||
within the overlap). It is the responsibility of the scanner not to return such
|
||||
duplicate results.
|
||||
|
||||
Scanners can mark themselves as thread_safe, if they do not require state
|
||||
in either their own class or the context. This will allow the scanner to be run
|
||||
in parallel against multiple blocks.
|
||||
|
||||
@@ -17,7 +17,8 @@ class BytesScanner(layers.ScannerInterface):
|
||||
"""
|
||||
find_pos = data.find(self.needle)
|
||||
while find_pos >= 0:
|
||||
yield find_pos + data_offset
|
||||
if find_pos < self.chunk_size:
|
||||
yield find_pos + data_offset
|
||||
find_pos = data.find(self.needle, find_pos + 1)
|
||||
|
||||
|
||||
@@ -35,7 +36,8 @@ class RegExScanner(layers.ScannerInterface):
|
||||
find_pos = self.regex.finditer(data)
|
||||
for match in find_pos:
|
||||
offset = match.start()
|
||||
yield offset + data_offset
|
||||
if offset < self.chunk_size:
|
||||
yield offset + data_offset
|
||||
|
||||
|
||||
class MultiStringScanner(layers.ScannerInterface):
|
||||
@@ -54,4 +56,5 @@ class MultiStringScanner(layers.ScannerInterface):
|
||||
-> typing.Generator[typing.Tuple[int, typing.Union[str, bytes]], None, None]:
|
||||
"""Runs through the data looking for the needles"""
|
||||
for offset, pattern in self._patterns.search(data):
|
||||
yield offset + data_offset, pattern
|
||||
if offset < self.chunk_size:
|
||||
yield offset + data_offset, pattern
|
||||
|
||||
Reference in New Issue
Block a user