Merge pull request #1586 from gcmoreira/framework_improve_conversion_to_strings

Framework improve conversion to strings
This commit is contained in:
ikelos
2025-01-31 09:04:33 +00:00
committed by GitHub
2 changed files with 97 additions and 10 deletions
+3 -2
View File
@@ -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):
+94 -8
View File
@@ -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(