From 153b3b7d3912bd46b6d96c380496eb97519a2fef Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Fri, 27 Sep 2019 11:13:56 +0100 Subject: [PATCH] Make sure we catch the most general exception for what we mean. --- volatility/framework/automagic/mac.py | 4 +-- volatility/framework/exceptions.py | 30 +++++++++++-------- .../framework/plugins/mac/check_sysctl.py | 12 ++++---- volatility/framework/plugins/mac/netstat.py | 6 ++-- volatility/framework/plugins/mac/psaux.py | 4 +-- .../framework/plugins/mac/trustedbsd.py | 4 +-- .../framework/plugins/windows/cmdline.py | 4 +++ .../framework/plugins/windows/handles.py | 8 ++--- .../framework/plugins/windows/poolscanner.py | 2 +- .../framework/plugins/windows/procdump.py | 10 +++++-- .../plugins/windows/registry/userassist.py | 3 ++ .../symbols/linux/extensions/__init__.py | 2 +- .../symbols/linux/extensions/bash.py | 2 +- .../symbols/mac/extensions/__init__.py | 16 +++++----- .../symbols/windows/extensions/__init__.py | 8 ++--- 15 files changed, 65 insertions(+), 50 deletions(-) diff --git a/volatility/framework/automagic/mac.py b/volatility/framework/automagic/mac.py index ae5afe2eb..49413414d 100644 --- a/volatility/framework/automagic/mac.py +++ b/volatility/framework/automagic/mac.py @@ -238,7 +238,7 @@ class MacUtilities(object): try: table_addr = task.p_fd.fd_ofiles.dereference() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return fds = objects.utility.array_of_pointers(table_addr, count = num_fds, subtype = file_type, context = context) @@ -247,7 +247,7 @@ class MacUtilities(object): if f != 0: try: ftype = f.f_fglob.get_fg_type() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: continue if ftype == 'DTYPE_VNODE': diff --git a/volatility/framework/exceptions.py b/volatility/framework/exceptions.py index 1fa197601..a565729d6 100644 --- a/volatility/framework/exceptions.py +++ b/volatility/framework/exceptions.py @@ -31,8 +31,16 @@ class SymbolError(VolatilityException): """Thrown when a symbol lookup has failed.""" +class LayerException(VolatilityException): + """Thrown when an error occurs dealing with memory and layers.""" + + def __init__(self, layer_name: str, *args) -> None: + super().__init__(*args) + self.layer_name = layer_name + + class InvalidAddressException(VolatilityException): - """Thrown when an address is not valid in the space it was requested.""" + """Thrown when an address is not valid in the layer it was requested.""" def __init__(self, layer_name: str, invalid_address: int, *args) -> None: super().__init__(*args) @@ -42,7 +50,10 @@ class InvalidAddressException(VolatilityException): class PagedInvalidAddressException(InvalidAddressException): """Thrown when an address is not valid in the paged space in which it was - request. + request. This is a subclass of InvalidAddressException and is only + thrown from a paged layer. In most circumstances :class:`InvalidAddressException` + is the correct exception to throw, since this will catch all invalid + mappings (including paged ones). Includes the invalid address and the number of bits of the address that are invalid @@ -55,10 +66,11 @@ class PagedInvalidAddressException(InvalidAddressException): class SwappedInvalidAddressException(PagedInvalidAddressException): - """Thrown when an address is not valid in the paged space in which it was - requested, but expected to be in swap space. + """Thrown when an address is not valid in the paged layer in which it was + requested, but expected to be in an associated swap layer. - Includes the swap lookup + Includes the swap lookup, as well as the invalid address and the bits of + the lookup that were invalid. """ def __init__(self, layer_name: str, invalid_address: int, invalid_bits: int, entry: int, swap_offset: int, @@ -71,14 +83,6 @@ class SymbolSpaceError(VolatilityException): """Thrown when an error occurs dealing with Symbolspaces and SymbolTables.""" -class LayerException(VolatilityException): - """Thrown when an error occurs dealing with memory and layers.""" - - def __init__(self, layer_name: str, *args) -> None: - super().__init__(*args) - self.layer_name = layer_name - - class UnsatisfiedException(VolatilityException): def __init__(self, unsatisfied: Dict[str, interfaces.configuration.RequirementInterface]) -> None: diff --git a/volatility/framework/plugins/mac/check_sysctl.py b/volatility/framework/plugins/mac/check_sysctl.py index 2e5fba112..768e33b85 100644 --- a/volatility/framework/plugins/mac/check_sysctl.py +++ b/volatility/framework/plugins/mac/check_sysctl.py @@ -58,13 +58,13 @@ class Check_sysctl(plugins.PluginInterface): if recursive != 0: try: sysctl = sysctl.oid_link.sle_next.dereference() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return while sysctl: try: name = utility.pointer_to_string(sysctl.oid_name, 128) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: name = "" if len(name) == 0: @@ -74,7 +74,7 @@ class Check_sysctl(plugins.PluginInterface): try: arg1_ptr = sysctl.oid_arg1.dereference().vol.offset - except exceptions.InvalidPagedAddressException: + except exceptions.InvalidAddressException: arg1_ptr = 0 arg1 = sysctl.oid_arg1 @@ -91,13 +91,13 @@ class Check_sysctl(plugins.PluginInterface): elif ctltype in ['CTLTYPE_INT', 'CTLTYPE_QUAD', 'CTLTYPE_OPAQUE']: try: val = str(arg1.dereference().cast("int")) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: val = "-1" elif ctltype == 'CTLTYPE_STRING': try: val = utility.pointer_to_string(sysctl.oid_arg1, 64) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: val = "" else: val = ctltype @@ -106,7 +106,7 @@ class Check_sysctl(plugins.PluginInterface): try: sysctl = sysctl.oid_link.sle_next - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: break def _generator(self): diff --git a/volatility/framework/plugins/mac/netstat.py b/volatility/framework/plugins/mac/netstat.py index a3a8a96f7..ef1f7258b 100644 --- a/volatility/framework/plugins/mac/netstat.py +++ b/volatility/framework/plugins/mac/netstat.py @@ -36,7 +36,7 @@ class Netstat(plugins.PluginInterface): for filp, _, _ in mac.MacUtilities.files_descriptors_for_process(self.config, self.context, task): try: ftype = filp.f_fglob.get_fg_type() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: continue if ftype != 'DTYPE_SOCKET': @@ -44,7 +44,7 @@ class Netstat(plugins.PluginInterface): try: socket = filp.f_fglob.fg_data.dereference().cast("socket") - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: continue family = socket.get_family() @@ -53,7 +53,7 @@ class Netstat(plugins.PluginInterface): try: upcb = socket.so_pcb.dereference().cast("unpcb") path = utility.array_to_string(upcb.unp_addr.sun_path) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: continue yield (0, (format_hints.Hex(socket.vol.offset), "UNIX", path, 0, "", 0, "", diff --git a/volatility/framework/plugins/mac/psaux.py b/volatility/framework/plugins/mac/psaux.py index 7e8eb3824..085f92872 100644 --- a/volatility/framework/plugins/mac/psaux.py +++ b/volatility/framework/plugins/mac/psaux.py @@ -51,7 +51,7 @@ class Psaux(plugins.PluginInterface): while argc > 0: try: arg = proc_layer.read(argsstart, 256) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: break idx = arg.find(b'\x00') @@ -65,7 +65,7 @@ class Psaux(plugins.PluginInterface): while argsstart < task.user_stack: try: check = proc_layer.read(argsstart, 1) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: break if check != b"\x00": diff --git a/volatility/framework/plugins/mac/trustedbsd.py b/volatility/framework/plugins/mac/trustedbsd.py index de44b42c5..2c51cce82 100644 --- a/volatility/framework/plugins/mac/trustedbsd.py +++ b/volatility/framework/plugins/mac/trustedbsd.py @@ -51,12 +51,12 @@ class Check_syscall(plugins.PluginInterface): try: mpc = ent.mpc.dereference() ops = mpc.mpc_ops.dereference() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: continue try: ent_name = utility.pointer_to_string(mpc.mpc_name, 255) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: ent_name = "N/A" for check in ops.vol.members: diff --git a/volatility/framework/plugins/windows/cmdline.py b/volatility/framework/plugins/windows/cmdline.py index 3d3f4009d..3fbe54e1d 100644 --- a/volatility/framework/plugins/windows/cmdline.py +++ b/volatility/framework/plugins/windows/cmdline.py @@ -48,6 +48,10 @@ class CmdLine(interfaces_plugins.PluginInterface): except exceptions.PagedInvalidAddressException as exp: result_text = "Required memory at {0:#x} is not valid (process exited?)".format(exp.invalid_address) + except exceptions.InvalidAddressException as exp: + result_text = "Required memory at {0:#x} is not valid (incomplete layer {1}?)".format( + exp.invalid_address, exp.layer_name) + yield (0, (proc.UniqueProcessId, process_name, result_text)) def run(self): diff --git a/volatility/framework/plugins/windows/handles.py b/volatility/framework/plugins/windows/handles.py index 693523d45..d69c22ea7 100644 --- a/volatility/framework/plugins/windows/handles.py +++ b/volatility/framework/plugins/windows/handles.py @@ -180,7 +180,7 @@ class Handles(interfaces_plugins.PluginInterface): try: type_name = objt.Name.String - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: vollog.log(constants.LOGLEVEL_VVV, "Cannot access _OBJECT_HEADER.Name at {0:#x}".format(objt.Name.vol.offset)) continue @@ -254,7 +254,7 @@ class Handles(interfaces_plugins.PluginInterface): except AttributeError: if item.Type.Name: yield item - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: continue def handles(self, handle_table): @@ -262,7 +262,7 @@ class Handles(interfaces_plugins.PluginInterface): try: TableCode = handle_table.TableCode & ~self._level_mask table_levels = handle_table.TableCode & self._level_mask - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: vollog.log(constants.LOGLEVEL_VVV, "Handle table parsing was aborted due to an invalid address exception") return @@ -282,7 +282,7 @@ class Handles(interfaces_plugins.PluginInterface): try: object_table = proc.ObjectTable - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: vollog.log(constants.LOGLEVEL_VVV, "Cannot access _EPROCESS.ObjectType at {0:#x}".format(proc.ObjectTable.vol.offset)) continue diff --git a/volatility/framework/plugins/windows/poolscanner.py b/volatility/framework/plugins/windows/poolscanner.py index 046792014..b30c3915a 100644 --- a/volatility/framework/plugins/windows/poolscanner.py +++ b/volatility/framework/plugins/windows/poolscanner.py @@ -215,7 +215,7 @@ class PoolScanner(plugins.PluginInterface): elif constraint.object_type == "File": try: name = mem_object.FileName.String - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: vollog.log(constants.LOGLEVEL_VVV, "Skipping file at {0:#x}".format(mem_object.vol.offset)) continue else: diff --git a/volatility/framework/plugins/windows/procdump.py b/volatility/framework/plugins/windows/procdump.py index a4e54124f..000a9125b 100644 --- a/volatility/framework/plugins/windows/procdump.py +++ b/volatility/framework/plugins/windows/procdump.py @@ -5,17 +5,17 @@ import logging from typing import List +import volatility.plugins.windows.pslist as pslist + import volatility.framework.constants as constants import volatility.framework.exceptions as exceptions import volatility.framework.interfaces.plugins as interfaces_plugins import volatility.framework.renderers as renderers -import volatility.plugins.windows.pslist as pslist from volatility.framework import interfaces from volatility.framework.configuration import requirements from volatility.framework.objects import utility -from volatility.framework.symbols.windows.extensions import pe - from volatility.framework.symbols import intermed +from volatility.framework.symbols.windows.extensions import pe vollog = logging.getLogger(__name__) @@ -77,6 +77,10 @@ class ProcDump(interfaces_plugins.PluginInterface): except exceptions.PagedInvalidAddressException as exp: result_text = "Required memory at {0:#x} is not valid (process exited?)".format(exp.invalid_address) + except exceptions.InvalidAddressException as exp: + result_text = "Required memory at {0:#x} is not valid (incomplete layer {1}?)".format( + exp.invalid_address, exp.layer_name) + yield (0, (proc.UniqueProcessId, process_name, result_text)) def run(self): diff --git a/volatility/framework/plugins/windows/registry/userassist.py b/volatility/framework/plugins/windows/registry/userassist.py index 62748f71d..f06d26d54 100644 --- a/volatility/framework/plugins/windows/registry/userassist.py +++ b/volatility/framework/plugins/windows/registry/userassist.py @@ -227,6 +227,9 @@ class UserAssist(interfaces.plugins.PluginInterface): continue except exceptions.PagedInvalidAddressException as excp: vollog.debug("Invalid address identified in Hive: {}".format(hex(excp.invalid_address))) + except exceptions.InvalidAddressException as excp: + vollog.debug("Invalid address identified in lower layer {}: {}".format( + excp.layer_name, excp.invalid_address)) except KeyError: vollog.debug("Key '{}' not found in Hive at offset {}.".format( "software\\microsoft\\windows\\currentversion\\explorer\\userassist", hex(hive.hive_offset))) diff --git a/volatility/framework/symbols/linux/extensions/__init__.py b/volatility/framework/symbols/linux/extensions/__init__.py index 1ac787f2c..5384c408e 100644 --- a/volatility/framework/symbols/linux/extensions/__init__.py +++ b/volatility/framework/symbols/linux/extensions/__init__.py @@ -49,7 +49,7 @@ class task_struct(generic.GenericIntelProcess): parent_layer = self._context.layers[self.vol.layer_name] try: pgd = self.mm.pgd - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return None if not isinstance(parent_layer, linear.LinearlyMappedLayer): diff --git a/volatility/framework/symbols/linux/extensions/bash.py b/volatility/framework/symbols/linux/extensions/bash.py index c6a0ebdf9..c583b67a4 100644 --- a/volatility/framework/symbols/linux/extensions/bash.py +++ b/volatility/framework/symbols/linux/extensions/bash.py @@ -14,7 +14,7 @@ class hist_entry(objects.StructType): try: cmd = self.get_command() ts = utility.array_to_string(self.timestamp.dereference()) - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return False if not cmd or len(cmd) == 0: diff --git a/volatility/framework/symbols/mac/extensions/__init__.py b/volatility/framework/symbols/mac/extensions/__init__.py index f71b65252..a03bd5ae9 100644 --- a/volatility/framework/symbols/mac/extensions/__init__.py +++ b/volatility/framework/symbols/mac/extensions/__init__.py @@ -28,7 +28,7 @@ class proc(generic.GenericIntelProcess): try: dtb = self.get_task().map.pmap.pm_cr3 - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return None if preferred_name is None: @@ -40,12 +40,12 @@ class proc(generic.GenericIntelProcess): def get_map_iter(self) -> Iterable[interfaces.objects.ObjectInterface]: try: task = self.get_task() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return try: current_map = task.map.hdr.links.next - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return seen = set() # type: Set[int] @@ -92,7 +92,7 @@ class fileglob(objects.StructType): elif self.fg_ops != 0: try: ret = self.fg_ops.fo_type - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: pass return ret.description @@ -239,7 +239,7 @@ class vm_map_entry(objects.StructType): while not found_end: try: tmp_vnode_object = vnode_object.shadow.dereference() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: break if tmp_vnode_object.vol.offset == 0: @@ -249,7 +249,7 @@ class vm_map_entry(objects.StructType): try: ops = vnode_object.pager.mo_pager_ops.dereference() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return None found = False @@ -274,7 +274,7 @@ class socket(objects.StructType): def get_inpcb(self): try: ret = self.so_pcb.dereference().cast("inpcb") - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: ret = None return ret @@ -335,7 +335,7 @@ class inpcb(objects.StructType): try: tcpcb = self.inp_ppcb.dereference().cast("tcpcb") - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: return "" state_type = tcpcb.t_state diff --git a/volatility/framework/symbols/windows/extensions/__init__.py b/volatility/framework/symbols/windows/extensions/__init__.py index 32d755efa..26be6ec9c 100644 --- a/volatility/framework/symbols/windows/extensions/__init__.py +++ b/volatility/framework/symbols/windows/extensions/__init__.py @@ -449,7 +449,7 @@ class _MMVAD(_MMVAD_SHORT): file_name = self.Subsection.ControlArea.FilePointer.dereference().cast( "_FILE_OBJECT").FileName.get_string() - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: pass return file_name @@ -546,7 +546,7 @@ class _FILE_OBJECT(objects.StructType, ExecutiveObject): try: name += self.FileName.String - except (TypeError, exceptions.PagedInvalidAddressException): + except (TypeError, exceptions.InvalidAddressException): pass return name @@ -756,7 +756,7 @@ class _EPROCESS(generic.GenericIntelProcess, ExecutiveObject): if self.ObjectTable.has_member("HandleCount"): return self.ObjectTable.HandleCount - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: vollog.log(constants.LOGLEVEL_VVV, "Cannot access _EPROCESS.ObjectTable.HandleCount at {0:#x}".format(self.vol.offset)) @@ -779,7 +779,7 @@ class _EPROCESS(generic.GenericIntelProcess, ExecutiveObject): if session.has_member("SessionId"): return session.SessionId - except exceptions.PagedInvalidAddressException: + except exceptions.InvalidAddressException: vollog.log(constants.LOGLEVEL_VVV, "Cannot access _EPROCESS.Session.SessionId at {0:#x}".format(self.vol.offset))