Objects: Don't try to read 0 bytes when unmarshalling

This commit is contained in:
Mike Auty
2022-02-23 22:53:54 +00:00
parent 9a0ba988ab
commit 265b282569
2 changed files with 15 additions and 7 deletions
+5 -1
View File
@@ -141,7 +141,11 @@ class PrimitiveObject(interfaces.objects.ObjectInterface):
@classmethod
def _unmarshall(cls, context: interfaces.context.ContextInterface, data_format: DataFormatInfo,
object_info: interfaces.objects.ObjectInformation) -> TUnion[int, float, bool, bytes, str]:
data = context.layers.read(object_info.layer_name, object_info.offset, data_format.length)
# Don't try to lookup a 0 length data format, incase it's at an invalid offset. Length 0 means b''
if data_format.length > 0:
data = context.layers.read(object_info.layer_name, object_info.offset, data_format.length)
else:
data = b''
return convert_data_to_value(data, cls._struct_type, data_format)
class VolTemplateProxy(interfaces.objects.ObjectInterface.VolTemplateProxy):
@@ -7,16 +7,17 @@ import datetime
import functools
import logging
import math
from typing import Iterable, Iterator, Optional, Union, Tuple, List
from typing import Iterable, Iterator, List, Optional, Tuple, Union
from volatility3.framework import constants, exceptions, interfaces, objects, renderers, symbols
from volatility3.framework.layers import intel
from volatility3.framework.renderers import conversion
from volatility3.framework.symbols import generic
from volatility3.framework.symbols.windows.extensions import pool, pe, kdbg
from volatility3.framework.symbols.windows.extensions import kdbg, pe, pool
vollog = logging.getLogger(__name__)
# Keep these in a basic module, to prevent import cycles when symbol providers require them
@@ -461,10 +462,13 @@ class UNICODE_STRING(objects.StructType):
# We explicitly do *not* catch errors here, we allow an exception to be thrown
# (otherwise there's no way to determine anything went wrong)
# It's up to the user of this method to catch exceptions
return self.Buffer.dereference().cast("string",
max_length = self.Length,
errors = "replace",
encoding = "utf16")
# We manually construct an object rather than casting a dereferenced pointer in case
# the buffer length is 0 and the pointer is a NULL pointer
return self._context.object(self.vol.type_name.split(constants.BANG)[0] + constants.BANG + 'string',
layer_name = self.Buffer.vol.layer_name,
offset = self.Buffer,
max_length = self.Length, errors = 'replace', encoding = 'utf16')
String = property(get_string)