mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-11 04:07:39 +02:00
leverage the existing Array facility
This commit is contained in:
@@ -3,11 +3,13 @@
|
||||
#
|
||||
|
||||
import re
|
||||
|
||||
from typing import List, Optional, Union
|
||||
import logging
|
||||
from typing import Optional, Union
|
||||
|
||||
from volatility3.framework import interfaces, objects, constants, exceptions
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def rol(value: int, count: int, max_bits: int = 64) -> int:
|
||||
"""A rotate-left instruction in Python"""
|
||||
@@ -254,51 +256,46 @@ def array_of_pointers(
|
||||
|
||||
def dynamically_sized_array_of_pointers(
|
||||
context: interfaces.context.ContextInterface,
|
||||
layer_name: str,
|
||||
symbol_table_name: str,
|
||||
array_offset: int,
|
||||
array: interfaces.objects.ObjectInterface,
|
||||
iterator_guard_value: int,
|
||||
subtype: Union[str, interfaces.objects.Template],
|
||||
stop_value: int = 0,
|
||||
iterator_guard_value: int = None,
|
||||
stop_on_invalid_pointers: bool = True,
|
||||
) -> List[interfaces.objects.ObjectInterface]:
|
||||
) -> interfaces.objects.ObjectInterface:
|
||||
"""Iterates over a dynamically sized array of pointers (e.g. NULL-terminated).
|
||||
Array iteration should always be performed with an arbitrary guard value as maximum size,
|
||||
to prevent running forever in case something unexpected happens.
|
||||
|
||||
Args:
|
||||
context: The context on which to operate.
|
||||
layer_name: The layer on which the array should be constructed.
|
||||
symbol_table_name: The symbol table to use to construct object types.
|
||||
array_offset: The array offset within the layer, from which to start iterating.
|
||||
stop_value: Stop value used to determine when to terminate iteration once it is encountered. Defaults to 0 (NULL-terminated arrays).
|
||||
array: The object to cast to an array.
|
||||
iterator_guard_value: Stop iterating when the iterator index is greater than this value. This is an extra-safety against smearing.
|
||||
subtype: The subtype of the array's pointers.
|
||||
stop_value: Stop value used to determine when to terminate iteration once it is encountered. Defaults to 0 (NULL-terminated arrays).
|
||||
stop_on_invalid_pointers: Determines whether to stop iterating or not when an invalid pointer is encountered. This can be useful for arrays
|
||||
that are known to have smeared entries before the end.
|
||||
|
||||
Returns:
|
||||
An array of pointer objects
|
||||
"""
|
||||
pointer_type = context.symbol_space.get_type(
|
||||
symbol_table_name + constants.BANG + "pointer"
|
||||
)
|
||||
entry = context.object(
|
||||
pointer_type,
|
||||
layer_name=layer_name,
|
||||
offset=array_offset,
|
||||
)
|
||||
i = 0
|
||||
array = []
|
||||
# entry and entry.vol.offset aren't the same thing, as
|
||||
# - entry is naturally represented by the address that the pointer refers to;
|
||||
# - entry.vol.offset is the offset at which the pointer lives.
|
||||
while entry != stop_value:
|
||||
if (not entry.is_readable() and stop_on_invalid_pointers) or (
|
||||
iterator_guard_value is not None and i >= iterator_guard_value
|
||||
new_count = 0
|
||||
for entry in array_of_pointers(
|
||||
array=array, count=iterator_guard_value, subtype=subtype, context=context
|
||||
):
|
||||
# "entry" is naturally represented by the address that the pointer refers to
|
||||
if (entry == stop_value) or (
|
||||
not entry.is_readable() and stop_on_invalid_pointers
|
||||
):
|
||||
break
|
||||
array.append(entry)
|
||||
entry = context.object(
|
||||
pointer_type,
|
||||
layer_name=layer_name,
|
||||
offset=entry.vol.offset + pointer_type.size,
|
||||
new_count += 1
|
||||
else:
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_V,
|
||||
f"""Iterator guard value {iterator_guard_value} reached while iterating over array at offset {array.vol.offset:#x}.\
|
||||
This means that there is a bug (e.g. smearing) with this array, or that it may contain valid entries past the iterator guard value.""",
|
||||
)
|
||||
i += 1
|
||||
return array
|
||||
|
||||
# Leverage the "Array" object instead of returning a Python list
|
||||
return array_of_pointers(
|
||||
array=array, count=new_count, subtype=subtype, context=context
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user