mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-06 01:37:39 +02:00
Merge pull request #1586 from gcmoreira/framework_improve_conversion_to_strings
Framework improve conversion to strings
This commit is contained in:
@@ -356,8 +356,9 @@ class String(PrimitiveObject, str):
|
||||
),
|
||||
**params,
|
||||
)
|
||||
if value.find("\x00") >= 0:
|
||||
value = value[: value.find("\x00")]
|
||||
index = value.find("\x00")
|
||||
if index >= 0:
|
||||
value = value[:index]
|
||||
return value
|
||||
|
||||
class VolTemplateProxy(interfaces.objects.ObjectInterface.VolTemplateProxy):
|
||||
|
||||
@@ -29,9 +29,23 @@ def bswap_64(value: int) -> int:
|
||||
|
||||
|
||||
def array_to_string(
|
||||
array: "objects.Array", count: Optional[int] = None, errors: str = "replace"
|
||||
) -> interfaces.objects.ObjectInterface:
|
||||
"""Takes a volatility Array of characters and returns a string."""
|
||||
array: "objects.Array",
|
||||
count: Optional[int] = None,
|
||||
errors: str = "replace",
|
||||
block_size=32,
|
||||
) -> str:
|
||||
"""Takes a Volatility 'Array' of characters and returns a Python string.
|
||||
|
||||
Args:
|
||||
array: The Volatility `Array` object containing character elements.
|
||||
count: Optional maximum number of characters to convert. If None, the function
|
||||
processes the entire array.
|
||||
errors: Specifies error handling behavior for decoding, defaulting to "replace".
|
||||
block_size: Reading block size. Defaults to 32
|
||||
|
||||
Returns:
|
||||
A decoded string representation of the character array.
|
||||
"""
|
||||
# TODO: Consider checking the Array's target is a native char
|
||||
if not isinstance(array, objects.Array):
|
||||
raise TypeError("Array_to_string takes an Array of char")
|
||||
@@ -39,19 +53,91 @@ def array_to_string(
|
||||
if count is None:
|
||||
count = array.vol.count
|
||||
|
||||
return array.cast("string", max_length=count, errors=errors)
|
||||
return address_to_string(
|
||||
context=array._context,
|
||||
layer_name=array.vol.layer_name,
|
||||
address=array.vol.offset,
|
||||
count=count,
|
||||
errors=errors,
|
||||
block_size=block_size,
|
||||
)
|
||||
|
||||
|
||||
def pointer_to_string(pointer: "objects.Pointer", count: int, errors: str = "replace"):
|
||||
"""Takes a volatility Pointer to characters and returns a string."""
|
||||
def pointer_to_string(
|
||||
pointer: "objects.Pointer",
|
||||
count: int,
|
||||
errors: str = "replace",
|
||||
block_size=32,
|
||||
) -> str:
|
||||
"""Takes a Volatility 'Pointer' to characters and returns a Python string.
|
||||
|
||||
Args:
|
||||
pointer: A `Pointer` object containing character elements.
|
||||
count: Optional maximum number of characters to convert. If None, the function
|
||||
processes the entire array.
|
||||
errors: Specifies error handling behavior for decoding, defaulting to "replace".
|
||||
block_size: Reading block size. Defaults to 32
|
||||
|
||||
Returns:
|
||||
A decoded string representation of the data referenced by the pointer.
|
||||
"""
|
||||
if not isinstance(pointer, objects.Pointer):
|
||||
raise TypeError("pointer_to_string takes a Pointer")
|
||||
|
||||
if count < 1:
|
||||
raise ValueError("pointer_to_string requires a positive count")
|
||||
|
||||
char = pointer.dereference()
|
||||
return char.cast("string", max_length=count, errors=errors)
|
||||
return address_to_string(
|
||||
context=pointer._context,
|
||||
layer_name=pointer.vol.layer_name,
|
||||
address=pointer,
|
||||
count=count,
|
||||
errors=errors,
|
||||
block_size=block_size,
|
||||
)
|
||||
|
||||
|
||||
def address_to_string(
|
||||
context: interfaces.context.ContextInterface,
|
||||
layer_name: str,
|
||||
address: int,
|
||||
count: int,
|
||||
errors: str = "replace",
|
||||
block_size=32,
|
||||
) -> str:
|
||||
"""Reads a null-terminated string from a given specified memory address, processing
|
||||
it in blocks for efficiency.
|
||||
|
||||
Args:
|
||||
context: The context used to retrieve memory layers and symbol tables
|
||||
layer_name: The name of the memory layer to read from
|
||||
address: The address where the string is located in memory
|
||||
count: The number of bytes to read
|
||||
errors: The error handling scheme to use for encoding errors. Defaults to "replace"
|
||||
block_size: Reading block size. Defaults to 32
|
||||
|
||||
Returns:
|
||||
The decoded string extracted from memory.
|
||||
"""
|
||||
if not isinstance(address, int):
|
||||
raise TypeError("It takes an int")
|
||||
|
||||
if count < 1:
|
||||
raise ValueError("It requires a positive count")
|
||||
|
||||
layer = context.layers[layer_name]
|
||||
text = b""
|
||||
while len(text) < count:
|
||||
current_block_size = min(count - len(text), block_size)
|
||||
temp_text = layer.read(address + len(text), current_block_size)
|
||||
idx = temp_text.find(b"\x00")
|
||||
if idx != -1:
|
||||
temp_text = temp_text[:idx]
|
||||
text += temp_text
|
||||
break
|
||||
text += temp_text
|
||||
|
||||
return text.decode(errors=errors)
|
||||
|
||||
|
||||
def array_of_pointers(
|
||||
|
||||
Reference in New Issue
Block a user