mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-30 03:39:51 +02:00
Merge branch 'volatilityfoundation:develop' into linux_issue_1089_module_memory
This commit is contained in:
@@ -107,7 +107,7 @@ The latest generated copy of the documentation can be found at: <https://volatil
|
||||
|
||||
## Licensing and Copyright
|
||||
|
||||
Copyright (C) 2007-2023 Volatility Foundation
|
||||
Copyright (C) 2007-2024 Volatility Foundation
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
|
||||
+1
-1
@@ -169,7 +169,7 @@ master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = "Volatility 3"
|
||||
copyright = "2012-2022, Volatility Foundation"
|
||||
copyright = "2012-2024, Volatility Foundation"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
|
||||
@@ -389,9 +389,11 @@ class JsonRenderer(CLIRenderer):
|
||||
interfaces.renderers.Disassembly: quoted_optional(display_disassembly),
|
||||
format_hints.MultiTypeData: quoted_optional(multitypedata_as_text),
|
||||
bytes: optional(lambda x: " ".join([f"{b:02x}" for b in x])),
|
||||
datetime.datetime: lambda x: x.isoformat()
|
||||
if not isinstance(x, interfaces.renderers.BaseAbsentValue)
|
||||
else None,
|
||||
datetime.datetime: lambda x: (
|
||||
x.isoformat()
|
||||
if not isinstance(x, interfaces.renderers.BaseAbsentValue)
|
||||
else None
|
||||
),
|
||||
"default": lambda x: x,
|
||||
}
|
||||
|
||||
|
||||
@@ -206,9 +206,9 @@ def _zipwalk(path: str):
|
||||
if not file.is_dir():
|
||||
dirlist = zip_results.get(os.path.dirname(file.filename), [])
|
||||
dirlist.append(os.path.basename(file.filename))
|
||||
zip_results[
|
||||
os.path.join(path, os.path.dirname(file.filename))
|
||||
] = dirlist
|
||||
zip_results[os.path.join(path, os.path.dirname(file.filename))] = (
|
||||
dirlist
|
||||
)
|
||||
for value in zip_results:
|
||||
yield value, zip_results[value]
|
||||
|
||||
|
||||
@@ -138,9 +138,9 @@ class MacIntelStacker(interfaces.automagic.StackerLayerInterface):
|
||||
config_path = join("automagic", "MacIntelHelper", new_layer_name)
|
||||
context.config[join(config_path, "memory_layer")] = layer_name
|
||||
context.config[join(config_path, "page_map_offset")] = dtb
|
||||
context.config[
|
||||
join(config_path, MacSymbolFinder.banner_config_key)
|
||||
] = str(banner, "latin-1")
|
||||
context.config[join(config_path, MacSymbolFinder.banner_config_key)] = (
|
||||
str(banner, "latin-1")
|
||||
)
|
||||
|
||||
new_layer = intel.Intel32e(
|
||||
context,
|
||||
|
||||
@@ -34,9 +34,9 @@ class KernelModule(interfaces.automagic.AutomagicInterface):
|
||||
return None
|
||||
# The requirement is unfulfilled and is a ModuleRequirement
|
||||
|
||||
context.config[
|
||||
interfaces.configuration.path_join(new_config_path, "class")
|
||||
] = "volatility3.framework.contexts.Module"
|
||||
context.config[interfaces.configuration.path_join(new_config_path, "class")] = (
|
||||
"volatility3.framework.contexts.Module"
|
||||
)
|
||||
|
||||
for req in requirement.requirements:
|
||||
if (
|
||||
|
||||
@@ -150,12 +150,12 @@ class SymbolFinder(interfaces.automagic.AutomagicInterface):
|
||||
clazz = self.symbol_class
|
||||
# Set the discovered options
|
||||
path_join = interfaces.configuration.path_join
|
||||
context.config[
|
||||
path_join(config_path, requirement.name, "class")
|
||||
] = clazz
|
||||
context.config[
|
||||
path_join(config_path, requirement.name, "isf_url")
|
||||
] = isf_path
|
||||
context.config[path_join(config_path, requirement.name, "class")] = (
|
||||
clazz
|
||||
)
|
||||
context.config[path_join(config_path, requirement.name, "isf_url")] = (
|
||||
isf_path
|
||||
)
|
||||
context.config[
|
||||
path_join(config_path, requirement.name, "symbol_mask")
|
||||
] = layer.address_mask
|
||||
|
||||
@@ -402,19 +402,19 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
|
||||
if swap_location:
|
||||
context.config[current_layer_path] = current_layer_name
|
||||
try:
|
||||
context.config[
|
||||
layer_loc_path
|
||||
] = requirements.URIRequirement.location_from_file(
|
||||
swap_location
|
||||
context.config[layer_loc_path] = (
|
||||
requirements.URIRequirement.location_from_file(
|
||||
swap_location
|
||||
)
|
||||
)
|
||||
except ValueError:
|
||||
vollog.warning(
|
||||
f"Volatility swap_location {swap_location} could not be validated - swap layer disabled"
|
||||
)
|
||||
continue
|
||||
context.config[
|
||||
layer_class_path
|
||||
] = "volatility3.framework.layers.physical.FileLayer"
|
||||
context.config[layer_class_path] = (
|
||||
"volatility3.framework.layers.physical.FileLayer"
|
||||
)
|
||||
|
||||
# Add the requirement
|
||||
new_req = requirements.TranslationLayerRequirement(
|
||||
@@ -424,9 +424,9 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
|
||||
)
|
||||
swap_req.add_requirement(new_req)
|
||||
|
||||
context.config[
|
||||
path_join(swap_sub_config, "number_of_elements")
|
||||
] = counter
|
||||
context.config[path_join(swap_sub_config, "number_of_elements")] = (
|
||||
counter
|
||||
)
|
||||
context.config[swap_sub_config] = True
|
||||
|
||||
swap_req.construct(context, swap_config)
|
||||
|
||||
@@ -550,9 +550,9 @@ class VersionRequirement(interfaces.configuration.RequirementInterface):
|
||||
config_path = interfaces.configuration.path_join(config_path, self.name)
|
||||
if not self.matches_required(self._version, self._component.version):
|
||||
return {config_path: self}
|
||||
context.config[
|
||||
interfaces.configuration.path_join(config_path, self.name)
|
||||
] = True
|
||||
context.config[interfaces.configuration.path_join(config_path, self.name)] = (
|
||||
True
|
||||
)
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -87,7 +87,7 @@ class ContextInterface(metaclass=ABCMeta):
|
||||
offset: int,
|
||||
native_layer_name: str = None,
|
||||
**arguments,
|
||||
):
|
||||
) -> "interfaces.objects.ObjectInterface":
|
||||
"""Object factory, takes a context, symbol, offset and optional
|
||||
layer_name.
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ class AVMLStacker(interfaces.automagic.StackerLayerInterface):
|
||||
except exceptions.LayerException:
|
||||
return None
|
||||
new_name = context.layers.free_layer_name("AVMLLayer")
|
||||
context.config[
|
||||
interfaces.configuration.path_join(new_name, "base_layer")
|
||||
] = layer_name
|
||||
context.config[interfaces.configuration.path_join(new_name, "base_layer")] = (
|
||||
layer_name
|
||||
)
|
||||
return AVMLLayer(context, new_name, new_name)
|
||||
|
||||
@@ -20,7 +20,6 @@ try:
|
||||
except ImportError:
|
||||
HAS_GCSFS = False
|
||||
|
||||
from volatility3.framework import exceptions
|
||||
from volatility3.framework.layers import resources
|
||||
|
||||
vollog = logging.getLogger(__file__)
|
||||
|
||||
@@ -115,9 +115,9 @@ class Elf64Stacker(interfaces.automagic.StackerLayerInterface):
|
||||
vollog.log(constants.LOGLEVEL_VVVV, f"Exception: {excp}")
|
||||
return None
|
||||
new_name = context.layers.free_layer_name("Elf64Layer")
|
||||
context.config[
|
||||
interfaces.configuration.path_join(new_name, "base_layer")
|
||||
] = layer_name
|
||||
context.config[interfaces.configuration.path_join(new_name, "base_layer")] = (
|
||||
layer_name
|
||||
)
|
||||
|
||||
try:
|
||||
return Elf64Layer(context, new_name, new_name)
|
||||
|
||||
@@ -277,9 +277,9 @@ class Intel(linear.LinearlyMappedLayer):
|
||||
This allows translation layers to provide maps of contiguous
|
||||
regions in one layer
|
||||
"""
|
||||
stashed_offset = (
|
||||
stashed_mapped_offset
|
||||
) = stashed_size = stashed_mapped_size = stashed_map_layer = None
|
||||
stashed_offset = stashed_mapped_offset = stashed_size = stashed_mapped_size = (
|
||||
stashed_map_layer
|
||||
) = None
|
||||
for offset, size, mapped_offset, mapped_size, map_layer in self._mapping(
|
||||
offset, length, ignore_errors
|
||||
):
|
||||
|
||||
@@ -104,7 +104,7 @@ class LimeStacker(interfaces.automagic.StackerLayerInterface):
|
||||
except LimeFormatException:
|
||||
return None
|
||||
new_name = context.layers.free_layer_name("LimeLayer")
|
||||
context.config[
|
||||
interfaces.configuration.path_join(new_name, "base_layer")
|
||||
] = layer_name
|
||||
context.config[interfaces.configuration.path_join(new_name, "base_layer")] = (
|
||||
layer_name
|
||||
)
|
||||
return LimeLayer(context, new_name, new_name)
|
||||
|
||||
@@ -486,9 +486,9 @@ class QemuStacker(interfaces.automagic.StackerLayerInterface):
|
||||
except exceptions.LayerException:
|
||||
return None
|
||||
new_name = context.layers.free_layer_name("QemuSuspendLayer")
|
||||
context.config[
|
||||
interfaces.configuration.path_join(new_name, "base_layer")
|
||||
] = layer_name
|
||||
context.config[interfaces.configuration.path_join(new_name, "base_layer")] = (
|
||||
layer_name
|
||||
)
|
||||
layer = QemuSuspendLayer(context, new_name, new_name)
|
||||
cls.stacker_slow_warning()
|
||||
return layer
|
||||
|
||||
@@ -173,8 +173,8 @@ class XenCoreDumpStacker(elf.Elf64Stacker):
|
||||
vollog.log(constants.LOGLEVEL_VVVV, f"Exception: {excp}")
|
||||
return None
|
||||
new_name = context.layers.free_layer_name("XenCoreDumpLayer")
|
||||
context.config[
|
||||
interfaces.configuration.path_join(new_name, "base_layer")
|
||||
] = layer_name
|
||||
context.config[interfaces.configuration.path_join(new_name, "base_layer")] = (
|
||||
layer_name
|
||||
)
|
||||
|
||||
return XenCoreDumpLayer(context, new_name, new_name)
|
||||
|
||||
@@ -768,12 +768,10 @@ class Array(interfaces.objects.ObjectInterface, collections.abc.Sequence):
|
||||
raise IndexError(f"Member not present in array template: {child}")
|
||||
|
||||
@overload
|
||||
def __getitem__(self, i: int) -> interfaces.objects.Template:
|
||||
...
|
||||
def __getitem__(self, i: int) -> interfaces.objects.Template: ...
|
||||
|
||||
@overload
|
||||
def __getitem__(self, s: slice) -> List[interfaces.objects.Template]:
|
||||
...
|
||||
def __getitem__(self, s: slice) -> List[interfaces.objects.Template]: ...
|
||||
|
||||
def __getitem__(self, i):
|
||||
"""Returns the i-th item from the array."""
|
||||
|
||||
@@ -1,12 +1,121 @@
|
||||
from volatility3.plugins.linux import envvars
|
||||
# This file is Copyright 2022 Volatility Foundation and licensed under the Volatility Software License 1.0
|
||||
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
from volatility3.framework import exceptions, renderers
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.interfaces import plugins
|
||||
from volatility3.framework.objects import utility
|
||||
from volatility3.plugins.linux import pslist
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Envars(envvars.Envvars):
|
||||
def run(self, *args, **kwargs):
|
||||
vollog.warning(
|
||||
"The linux.envars plugin has been renamed to linux.envvars and will only be accessible through the new name in a future release"
|
||||
class Envars(plugins.PluginInterface):
|
||||
"""Lists processes with their environment variables"""
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls):
|
||||
# Since we're calling the plugin, make sure we have the plugin's requirements
|
||||
return [
|
||||
requirements.ModuleRequirement(
|
||||
name="kernel",
|
||||
description="Linux kernel",
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.PluginRequirement(
|
||||
name="pslist", plugin=pslist.PsList, version=(2, 0, 0)
|
||||
),
|
||||
requirements.ListRequirement(
|
||||
name="pid",
|
||||
description="Filter on specific process IDs",
|
||||
element_type=int,
|
||||
optional=True,
|
||||
),
|
||||
]
|
||||
|
||||
def _generator(self, tasks):
|
||||
"""Generates a listing of processes along with environment variables"""
|
||||
|
||||
# walk the process list and return the envars
|
||||
for task in tasks:
|
||||
pid = task.pid
|
||||
|
||||
# get process name as string
|
||||
name = utility.array_to_string(task.comm)
|
||||
|
||||
# try and get task parent
|
||||
try:
|
||||
ppid = task.parent.pid
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
f"Unable to read parent pid for task {pid} {name}, setting ppid to 0."
|
||||
)
|
||||
ppid = 0
|
||||
|
||||
# kernel threads never have an mm as they do not have userland mappings
|
||||
try:
|
||||
mm = task.mm
|
||||
except exceptions.InvalidAddressException:
|
||||
# no mm so cannot get envars
|
||||
vollog.debug(
|
||||
f"Unable to access mm for task {pid} {name} it is likely a kernel thread, will not extract any envars."
|
||||
)
|
||||
mm = None
|
||||
continue
|
||||
|
||||
# if mm exists attempt to get envars
|
||||
if mm:
|
||||
# get process layer to read envars from
|
||||
proc_layer_name = task.add_process_layer()
|
||||
if proc_layer_name is None:
|
||||
vollog.debug(
|
||||
f"Unable to construct process layer for task {pid} {name}, will not extract any envars."
|
||||
)
|
||||
continue
|
||||
proc_layer = self.context.layers[proc_layer_name]
|
||||
|
||||
# get the size of the envars with sanity checking
|
||||
envars_size = task.mm.env_end - task.mm.env_start
|
||||
if not (0 < envars_size <= 8192):
|
||||
vollog.debug(
|
||||
f"Task {pid} {name} appears to have envars of size {envars_size} bytes which fails the sanity checking, will not extract any envars."
|
||||
)
|
||||
continue
|
||||
|
||||
# attempt to read all envars data
|
||||
try:
|
||||
envar_data = proc_layer.read(task.mm.env_start, envars_size)
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
f"Unable to read full envars for {pid} {name} starting at virtual offset {hex(task.mm.env_start)} for {envars_size} bytes, will not extract any envars."
|
||||
)
|
||||
continue
|
||||
|
||||
# parse envar data, envars are null terminated, keys and values are separated by '='
|
||||
envar_data = envar_data.rstrip(b"\x00")
|
||||
for envar_pair in envar_data.split(b"\x00"):
|
||||
try:
|
||||
key, value = envar_pair.decode().split("=", 1)
|
||||
except ValueError:
|
||||
vollog.debug(
|
||||
f"Unable to extract envars for {pid} {name} starting at virtual offset {hex(task.mm.env_start)}, they don't appear to be '=' separated"
|
||||
)
|
||||
continue
|
||||
yield (0, (pid, ppid, name, key, value))
|
||||
|
||||
def run(self):
|
||||
filter_func = pslist.PsList.create_pid_filter(self.config.get("pid", None))
|
||||
|
||||
return renderers.TreeGrid(
|
||||
[("PID", int), ("PPID", int), ("COMM", str), ("KEY", str), ("VALUE", str)],
|
||||
self._generator(
|
||||
pslist.PsList.list_tasks(
|
||||
self.context, self.config["kernel"], filter_func=filter_func
|
||||
)
|
||||
),
|
||||
)
|
||||
return super().run(*args, **kwargs)
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
# This file is Copyright 2022 Volatility Foundation and licensed under the Volatility Software License 1.0
|
||||
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
from volatility3.framework import exceptions, renderers
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.interfaces import plugins
|
||||
from volatility3.framework.objects import utility
|
||||
from volatility3.plugins.linux import pslist
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Envvars(plugins.PluginInterface):
|
||||
"""Lists processes with their environment variables"""
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls):
|
||||
# Since we're calling the plugin, make sure we have the plugin's requirements
|
||||
return [
|
||||
requirements.ModuleRequirement(
|
||||
name="kernel",
|
||||
description="Linux kernel",
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.PluginRequirement(
|
||||
name="pslist", plugin=pslist.PsList, version=(2, 0, 0)
|
||||
),
|
||||
requirements.ListRequirement(
|
||||
name="pid",
|
||||
description="Filter on specific process IDs",
|
||||
element_type=int,
|
||||
optional=True,
|
||||
),
|
||||
]
|
||||
|
||||
def _generator(self, tasks):
|
||||
"""Generates a listing of processes along with environment variables"""
|
||||
|
||||
# walk the process list and return the envars
|
||||
for task in tasks:
|
||||
pid = task.pid
|
||||
|
||||
# get process name as string
|
||||
name = utility.array_to_string(task.comm)
|
||||
|
||||
# try and get task parent
|
||||
try:
|
||||
ppid = task.parent.pid
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
f"Unable to read parent pid for task {pid} {name}, setting ppid to 0."
|
||||
)
|
||||
ppid = 0
|
||||
|
||||
# kernel threads never have an mm as they do not have userland mappings
|
||||
try:
|
||||
mm = task.mm
|
||||
except exceptions.InvalidAddressException:
|
||||
# no mm so cannot get envars
|
||||
vollog.debug(
|
||||
f"Unable to access mm for task {pid} {name} it is likely a kernel thread, will not extract any envars."
|
||||
)
|
||||
mm = None
|
||||
continue
|
||||
|
||||
# if mm exists attempt to get envars
|
||||
if mm:
|
||||
# get process layer to read envars from
|
||||
proc_layer_name = task.add_process_layer()
|
||||
if proc_layer_name is None:
|
||||
vollog.debug(
|
||||
f"Unable to construct process layer for task {pid} {name}, will not extract any envars."
|
||||
)
|
||||
continue
|
||||
proc_layer = self.context.layers[proc_layer_name]
|
||||
|
||||
# get the size of the envars with sanity checking
|
||||
envars_size = task.mm.env_end - task.mm.env_start
|
||||
if not (0 < envars_size <= 8192):
|
||||
vollog.debug(
|
||||
f"Task {pid} {name} appears to have envars of size {envars_size} bytes which fails the sanity checking, will not extract any envars."
|
||||
)
|
||||
continue
|
||||
|
||||
# attempt to read all envars data
|
||||
try:
|
||||
envar_data = proc_layer.read(task.mm.env_start, envars_size)
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
f"Unable to read full envars for {pid} {name} starting at virtual offset {hex(task.mm.env_start)} for {envars_size} bytes, will not extract any envars."
|
||||
)
|
||||
continue
|
||||
|
||||
# parse envar data, envars are null terminated, keys and values are separated by '='
|
||||
envar_data = envar_data.rstrip(b"\x00")
|
||||
for envar_pair in envar_data.split(b"\x00"):
|
||||
try:
|
||||
key, value = envar_pair.decode().split("=", 1)
|
||||
except ValueError:
|
||||
vollog.debug(
|
||||
f"Unable to extract envars for {pid} {name} starting at virtual offset {hex(task.mm.env_start)}, they don't appear to be '=' separated"
|
||||
)
|
||||
continue
|
||||
yield (0, (pid, ppid, name, key, value))
|
||||
|
||||
def run(self):
|
||||
filter_func = pslist.PsList.create_pid_filter(self.config.get("pid", None))
|
||||
|
||||
return renderers.TreeGrid(
|
||||
[("PID", int), ("PPID", int), ("COMM", str), ("KEY", str), ("VALUE", str)],
|
||||
self._generator(
|
||||
pslist.PsList.list_tasks(
|
||||
self.context, self.config["kernel"], filter_func=filter_func
|
||||
)
|
||||
),
|
||||
)
|
||||
@@ -49,9 +49,7 @@ class PsList(interfaces.plugins.PluginInterface):
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_list_tasks(
|
||||
cls, method: str
|
||||
) -> Callable[
|
||||
def get_list_tasks(cls, method: str) -> Callable[
|
||||
[interfaces.context.ContextInterface, str, Callable[[int], bool]],
|
||||
Iterable[interfaces.objects.ObjectInterface],
|
||||
]:
|
||||
|
||||
@@ -46,9 +46,9 @@ class Crashinfo(interfaces.plugins.PluginInterface):
|
||||
bitmap_size = format_hints.Hex(summary_header.BitmapSize)
|
||||
bitmap_pages = format_hints.Hex(summary_header.Pages)
|
||||
else:
|
||||
bitmap_header_size = (
|
||||
bitmap_size
|
||||
) = bitmap_pages = renderers.NotApplicableValue()
|
||||
bitmap_header_size = bitmap_size = bitmap_pages = (
|
||||
renderers.NotApplicableValue()
|
||||
)
|
||||
|
||||
yield (
|
||||
0,
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
|
||||
import logging
|
||||
import ntpath
|
||||
import re
|
||||
from typing import List, Tuple, Type, Optional, Generator
|
||||
|
||||
from volatility3.framework import interfaces, renderers, exceptions, constants
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.renderers import format_hints
|
||||
from volatility3.framework.renderers import format_hints, UnreadableValue
|
||||
from volatility3.plugins.windows import handles
|
||||
from volatility3.plugins.windows import pslist
|
||||
|
||||
@@ -53,6 +54,17 @@ class DumpFiles(interfaces.plugins.PluginInterface):
|
||||
description="Dump a single _FILE_OBJECT at this physical address",
|
||||
optional=True,
|
||||
),
|
||||
requirements.StringRequirement(
|
||||
name="filter",
|
||||
description="Dump files matching regular expression FILTER",
|
||||
optional=True,
|
||||
),
|
||||
requirements.BooleanRequirement(
|
||||
name="ignore-case",
|
||||
description="Ignore case in filter match",
|
||||
default=False,
|
||||
optional=True,
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="pslist", component=pslist.PsList, version=(2, 0, 0)
|
||||
),
|
||||
@@ -208,6 +220,10 @@ class DumpFiles(interfaces.plugins.PluginInterface):
|
||||
|
||||
def _generator(self, procs: List, offsets: List):
|
||||
kernel = self.context.modules[self.config["kernel"]]
|
||||
file_re = None
|
||||
if self.config["filter"]:
|
||||
flags = re.I if self.config["ignore-case"] else 0
|
||||
file_re = re.compile(self.config["filter"], flags)
|
||||
|
||||
if procs:
|
||||
# The handles plugin doesn't expose any staticmethod/classmethod, and it also requires stashing
|
||||
@@ -243,6 +259,14 @@ class DumpFiles(interfaces.plugins.PluginInterface):
|
||||
obj_type = entry.get_object_type(type_map, cookie)
|
||||
if obj_type == "File":
|
||||
file_obj = entry.Body.cast("_FILE_OBJECT")
|
||||
|
||||
if file_re:
|
||||
name = file_obj.file_name_with_device()
|
||||
if isinstance(name, UnreadableValue):
|
||||
continue
|
||||
if not file_re.search(name):
|
||||
continue
|
||||
|
||||
for result in self.process_file_object(
|
||||
self.context, kernel.layer_name, self.open, file_obj
|
||||
):
|
||||
@@ -272,6 +296,13 @@ class DumpFiles(interfaces.plugins.PluginInterface):
|
||||
if not file_obj.is_valid():
|
||||
continue
|
||||
|
||||
if file_re:
|
||||
name = file_obj.file_name_with_device()
|
||||
if isinstance(name, UnreadableValue):
|
||||
continue
|
||||
if not file_re.search(name):
|
||||
continue
|
||||
|
||||
for result in self.process_file_object(
|
||||
self.context, kernel.layer_name, self.open, file_obj
|
||||
):
|
||||
@@ -315,6 +346,11 @@ class DumpFiles(interfaces.plugins.PluginInterface):
|
||||
procs = list()
|
||||
kernel = self.context.modules[self.config["kernel"]]
|
||||
|
||||
if self.config["filter"] and (
|
||||
self.config["virtaddr"] or self.config["physaddr"]
|
||||
):
|
||||
raise ValueError("Cannot use filter flag with an address flag")
|
||||
|
||||
if self.config.get("virtaddr", None) is not None:
|
||||
offsets.append((self.config["virtaddr"], True))
|
||||
elif self.config.get("physaddr", None) is not None:
|
||||
|
||||
@@ -141,16 +141,30 @@ class Malfind(interfaces.plugins.PluginInterface):
|
||||
# determine if we're on a 32 or 64 bit kernel
|
||||
kernel = self.context.modules[self.config["kernel"]]
|
||||
|
||||
# set refined criteria to know when to add to "Notes" column
|
||||
refined_criteria = {
|
||||
b"MZ": "MZ header",
|
||||
b"\x55\x8B": "PE header",
|
||||
b"\x55\x48": "Function prologue",
|
||||
b"\x55\x89": "Function prologue",
|
||||
}
|
||||
|
||||
is_32bit_arch = not symbols.symbol_table_is_64bit(
|
||||
self.context, kernel.symbol_table_name
|
||||
)
|
||||
|
||||
for proc in procs:
|
||||
# by default, "Notes" column will be set to N/A
|
||||
notes = renderers.NotApplicableValue()
|
||||
process_name = utility.array_to_string(proc.ImageFileName)
|
||||
|
||||
for vad, data in self.list_injections(
|
||||
self.context, kernel.layer_name, kernel.symbol_table_name, proc
|
||||
):
|
||||
# Check for unique headers and update "Notes" column if criteria is met
|
||||
if data[0:2] in refined_criteria:
|
||||
notes = refined_criteria[data[0:2]]
|
||||
|
||||
# if we're on a 64 bit kernel, we may still need 32 bit disasm due to wow64
|
||||
if is_32bit_arch or proc.get_is_wow64():
|
||||
architecture = "intel"
|
||||
@@ -196,6 +210,7 @@ class Malfind(interfaces.plugins.PluginInterface):
|
||||
vad.get_commit_charge(),
|
||||
vad.get_private_memory(),
|
||||
file_output,
|
||||
notes,
|
||||
format_hints.HexBytes(data),
|
||||
disasm,
|
||||
),
|
||||
@@ -216,6 +231,7 @@ class Malfind(interfaces.plugins.PluginInterface):
|
||||
("CommitCharge", int),
|
||||
("PrivateMemory", int),
|
||||
("File output", str),
|
||||
("Notes", str),
|
||||
("Hexdump", format_hints.HexBytes),
|
||||
("Disasm", interfaces.renderers.Disassembly),
|
||||
],
|
||||
|
||||
@@ -53,7 +53,6 @@ class MFTScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
# get each of the individual Field Sets
|
||||
mft_object = symbol_table + constants.BANG + "MFT_ENTRY"
|
||||
attribute_object = symbol_table + constants.BANG + "ATTRIBUTE"
|
||||
header_object = symbol_table + constants.BANG + "ATTR_HEADER"
|
||||
si_object = symbol_table + constants.BANG + "STANDARD_INFORMATION_ENTRY"
|
||||
fn_object = symbol_table + constants.BANG + "FILE_NAME_ENTRY"
|
||||
|
||||
@@ -176,7 +175,6 @@ class MFTScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
|
||||
|
||||
class ADS(interfaces.plugins.PluginInterface):
|
||||
|
||||
"""Scans for Alternate Data Stream"""
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
|
||||
@@ -487,10 +487,12 @@ class NetScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
if not isinstance(row_data[9], datetime.datetime):
|
||||
continue
|
||||
row_data = [
|
||||
"N/A"
|
||||
if isinstance(i, renderers.UnreadableValue)
|
||||
or isinstance(i, renderers.UnparsableValue)
|
||||
else i
|
||||
(
|
||||
"N/A"
|
||||
if isinstance(i, renderers.UnreadableValue)
|
||||
or isinstance(i, renderers.UnparsableValue)
|
||||
else i
|
||||
)
|
||||
for i in row_data
|
||||
]
|
||||
description = (
|
||||
|
||||
@@ -5,7 +5,7 @@ import datetime
|
||||
import logging
|
||||
from typing import Callable, Dict, Set, Tuple
|
||||
|
||||
from volatility3.framework import objects, interfaces, renderers
|
||||
from volatility3.framework import objects, interfaces, renderers, exceptions
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.renderers import format_hints
|
||||
from volatility3.plugins.windows import pslist
|
||||
@@ -132,6 +132,25 @@ class PsTree(interfaces.plugins.PluginInterface):
|
||||
proc.get_exit_time(),
|
||||
)
|
||||
|
||||
try:
|
||||
audit = proc.SeAuditProcessCreationInfo.ImageFileName.Name
|
||||
# If 'audit' is set to the empty string, display NotAvailableValue
|
||||
row += (audit.get_string() or renderers.NotAvailableValue(),)
|
||||
except exceptions.InvalidAddressException:
|
||||
row += (renderers.NotAvailableValue(),)
|
||||
|
||||
try:
|
||||
process_params = proc.get_peb().ProcessParameters
|
||||
row += (
|
||||
process_params.CommandLine.get_string(),
|
||||
process_params.ImagePathName.get_string(),
|
||||
)
|
||||
except exceptions.InvalidAddressException:
|
||||
row += (
|
||||
renderers.NotAvailableValue(),
|
||||
renderers.NotAvailableValue(),
|
||||
)
|
||||
|
||||
yield (self._levels[pid] - 1, row)
|
||||
for child_pid in self._children.get(pid, []):
|
||||
yield from yield_processes(
|
||||
@@ -161,6 +180,9 @@ class PsTree(interfaces.plugins.PluginInterface):
|
||||
("Wow64", bool),
|
||||
("CreateTime", datetime.datetime),
|
||||
("ExitTime", datetime.datetime),
|
||||
("Audit", str),
|
||||
("Cmd", str),
|
||||
("Path", str),
|
||||
],
|
||||
self._generator(
|
||||
filter_func=pslist.PsList.create_pid_filter(
|
||||
|
||||
@@ -193,9 +193,9 @@ class PrintKey(interfaces.plugins.PluginInterface):
|
||||
vollog.debug(
|
||||
"Couldn't read registry value type, so data is unreadable"
|
||||
)
|
||||
value_data: Union[
|
||||
interfaces.renderers.BaseAbsentValue, bytes
|
||||
] = renderers.UnreadableValue()
|
||||
value_data: Union[interfaces.renderers.BaseAbsentValue, bytes] = (
|
||||
renderers.UnreadableValue()
|
||||
)
|
||||
else:
|
||||
try:
|
||||
value_data = node.decode_data()
|
||||
|
||||
@@ -4,25 +4,42 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import List
|
||||
from typing import Dict, List, NamedTuple, Optional, Tuple, Union, cast
|
||||
|
||||
from volatility3.framework import interfaces, renderers, constants, symbols, exceptions
|
||||
from volatility3.framework import (
|
||||
constants,
|
||||
exceptions,
|
||||
interfaces,
|
||||
objects,
|
||||
renderers,
|
||||
symbols,
|
||||
)
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.layers import scanners
|
||||
from volatility3.framework.renderers import format_hints
|
||||
from volatility3.framework.symbols import intermed
|
||||
from volatility3.framework.symbols.windows import versions
|
||||
from volatility3.framework.symbols.windows.extensions import services
|
||||
from volatility3.plugins.windows import poolscanner, vadyarascan, pslist
|
||||
from volatility3.plugins.windows import poolscanner, pslist, vadyarascan
|
||||
from volatility3.plugins.windows.registry import hivelist
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
ServiceBinaryInfo = NamedTuple(
|
||||
"ServiceBinaryInfo",
|
||||
[
|
||||
("dll", Union[str, interfaces.renderers.BaseAbsentValue]),
|
||||
("binary", Union[str, interfaces.renderers.BaseAbsentValue]),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class SvcScan(interfaces.plugins.PluginInterface):
|
||||
"""Scans for windows services."""
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
_version = (1, 0, 0)
|
||||
_version = (2, 0, 0)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
|
||||
@@ -42,10 +59,16 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
requirements.PluginRequirement(
|
||||
name="vadyarascan", plugin=vadyarascan.VadYaraScan, version=(1, 0, 0)
|
||||
),
|
||||
requirements.PluginRequirement(
|
||||
name="hivelist", plugin=hivelist.HiveList, version=(1, 0, 0)
|
||||
),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_record_tuple(service_record: interfaces.objects.ObjectInterface):
|
||||
def get_record_tuple(
|
||||
service_record: interfaces.objects.ObjectInterface,
|
||||
binary_info: ServiceBinaryInfo,
|
||||
):
|
||||
return (
|
||||
format_hints.Hex(service_record.vol.offset),
|
||||
service_record.Order,
|
||||
@@ -56,8 +79,32 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
service_record.get_name(),
|
||||
service_record.get_display(),
|
||||
service_record.get_binary(),
|
||||
binary_info.binary,
|
||||
binary_info.dll,
|
||||
)
|
||||
|
||||
# These checks must be completed from newest -> oldest OS version.
|
||||
_win_version_file_map: List[Tuple[versions.OsDistinguisher, bool, str]] = [
|
||||
(versions.is_win10_25398_or_later, True, "services-win10-25398-x64"),
|
||||
(versions.is_win10_19041_or_later, True, "services-win10-19041-x64"),
|
||||
(versions.is_win10_19041_or_later, False, "services-win10-19041-x86"),
|
||||
(versions.is_win10_18362_or_later, True, "services-win10-18362-x64"),
|
||||
(versions.is_win10_18362_or_later, False, "services-win10-18362-x86"),
|
||||
(versions.is_win10_17763_or_later, False, "services-win10-17763-x86"),
|
||||
(versions.is_win10_16299_or_later, True, "services-win10-16299-x64"),
|
||||
(versions.is_win10_16299_or_later, False, "services-win10-16299-x86"),
|
||||
(versions.is_win10_15063, True, "services-win10-15063-x64"),
|
||||
(versions.is_win10_15063, False, "services-win10-15063-x86"),
|
||||
(versions.is_win10_up_to_15063, True, "services-win8-x64"),
|
||||
(versions.is_win10_up_to_15063, False, "services-win8-x86"),
|
||||
(versions.is_windows_8_or_later, True, "services-win8-x64"),
|
||||
(versions.is_windows_8_or_later, True, "services-win8-x86"),
|
||||
(versions.is_vista_or_later, True, "services-vista-x64"),
|
||||
(versions.is_vista_or_later, False, "services-vista-x86"),
|
||||
(versions.is_windows_xp, False, "services-xp-x86"),
|
||||
(versions.is_xp_or_2003, True, "services-xp-2003-x64"),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def create_service_table(
|
||||
context: interfaces.context.ContextInterface,
|
||||
@@ -78,67 +125,14 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
native_types = context.symbol_space[symbol_table].natives
|
||||
is_64bit = symbols.symbol_table_is_64bit(context, symbol_table)
|
||||
|
||||
if (
|
||||
versions.is_windows_xp(context=context, symbol_table=symbol_table)
|
||||
and not is_64bit
|
||||
):
|
||||
symbol_filename = "services-xp-x86"
|
||||
elif (
|
||||
versions.is_xp_or_2003(context=context, symbol_table=symbol_table)
|
||||
and is_64bit
|
||||
):
|
||||
symbol_filename = "services-xp-2003-x64"
|
||||
elif (
|
||||
versions.is_win10_16299_or_later(context=context, symbol_table=symbol_table)
|
||||
and is_64bit
|
||||
):
|
||||
symbol_filename = "services-win10-16299-x64"
|
||||
elif (
|
||||
versions.is_win10_16299_or_later(context=context, symbol_table=symbol_table)
|
||||
and not is_64bit
|
||||
):
|
||||
symbol_filename = "services-win10-16299-x86"
|
||||
elif (
|
||||
versions.is_win10_up_to_15063(context=context, symbol_table=symbol_table)
|
||||
and is_64bit
|
||||
):
|
||||
symbol_filename = "services-win8-x64"
|
||||
elif (
|
||||
versions.is_win10_up_to_15063(context=context, symbol_table=symbol_table)
|
||||
and not is_64bit
|
||||
):
|
||||
symbol_filename = "services-win8-x86"
|
||||
elif (
|
||||
versions.is_win10_15063(context=context, symbol_table=symbol_table)
|
||||
and is_64bit
|
||||
):
|
||||
symbol_filename = "services-win10-15063-x64"
|
||||
elif (
|
||||
versions.is_win10_15063(context=context, symbol_table=symbol_table)
|
||||
and not is_64bit
|
||||
):
|
||||
symbol_filename = "services-win10-15063-x86"
|
||||
elif (
|
||||
versions.is_windows_8_or_later(context=context, symbol_table=symbol_table)
|
||||
and is_64bit
|
||||
):
|
||||
symbol_filename = "services-win8-x64"
|
||||
elif (
|
||||
versions.is_windows_8_or_later(context=context, symbol_table=symbol_table)
|
||||
and not is_64bit
|
||||
):
|
||||
symbol_filename = "services-win8-x86"
|
||||
elif (
|
||||
versions.is_vista_or_later(context=context, symbol_table=symbol_table)
|
||||
and is_64bit
|
||||
):
|
||||
symbol_filename = "services-vista-x64"
|
||||
elif (
|
||||
versions.is_vista_or_later(context=context, symbol_table=symbol_table)
|
||||
and not is_64bit
|
||||
):
|
||||
symbol_filename = "services-vista-x86"
|
||||
else:
|
||||
try:
|
||||
symbol_filename = next(
|
||||
filename
|
||||
for version_check, for_64bit, filename in SvcScan._win_version_file_map
|
||||
if is_64bit == for_64bit
|
||||
and version_check(context=context, symbol_table=symbol_table)
|
||||
)
|
||||
except StopIteration:
|
||||
raise NotImplementedError("This version of Windows is not supported!")
|
||||
|
||||
return intermed.IntermediateSymbolTable.create(
|
||||
@@ -150,6 +144,94 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
native_types=native_types,
|
||||
)
|
||||
|
||||
def _get_service_key(self, kernel) -> Optional[objects.StructType]:
|
||||
for hive in hivelist.HiveList.list_hives(
|
||||
context=self.context,
|
||||
base_config_path=interfaces.configuration.path_join(
|
||||
self.config_path, "hivelist"
|
||||
),
|
||||
layer_name=kernel.layer_name,
|
||||
symbol_table=kernel.symbol_table_name,
|
||||
filter_string="machine\\system",
|
||||
):
|
||||
# Get ControlSet\Services.
|
||||
try:
|
||||
return cast(
|
||||
objects.StructType, hive.get_key(r"CurrentControlSet\Services")
|
||||
)
|
||||
except (KeyError, exceptions.InvalidAddressException):
|
||||
try:
|
||||
return cast(
|
||||
objects.StructType, hive.get_key(r"ControlSet001\Services")
|
||||
)
|
||||
except (KeyError, exceptions.InvalidAddressException):
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VVVV,
|
||||
"Could not retrieve any control set from SYSTEM hive",
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _get_service_dll(
|
||||
service_key,
|
||||
) -> Union[str, interfaces.renderers.BaseAbsentValue]:
|
||||
try:
|
||||
param_key = next(
|
||||
key
|
||||
for key in service_key.get_subkeys()
|
||||
if key.get_name() == "Parameters"
|
||||
)
|
||||
return (
|
||||
next(
|
||||
val
|
||||
for val in param_key.get_values()
|
||||
if val.get_name() == "ServiceDll"
|
||||
)
|
||||
.decode_data()
|
||||
.decode("utf-16")
|
||||
.rstrip("\x00")
|
||||
)
|
||||
|
||||
except UnicodeDecodeError:
|
||||
return renderers.UnparsableValue()
|
||||
except StopIteration:
|
||||
return renderers.UnreadableValue()
|
||||
|
||||
@staticmethod
|
||||
def _get_service_binary(
|
||||
service_key,
|
||||
) -> Union[str, interfaces.renderers.BaseAbsentValue]:
|
||||
try:
|
||||
return (
|
||||
next(
|
||||
val
|
||||
for val in service_key.get_values()
|
||||
if val.get_name() == "ImagePath"
|
||||
)
|
||||
.decode_data()
|
||||
.decode("utf-16")
|
||||
.rstrip("\x00")
|
||||
)
|
||||
|
||||
except UnicodeDecodeError:
|
||||
return renderers.UnparsableValue()
|
||||
except StopIteration:
|
||||
return renderers.UnreadableValue()
|
||||
|
||||
@staticmethod
|
||||
def _get_service_binary_map(
|
||||
services_key: interfaces.objects.ObjectInterface,
|
||||
) -> Dict[str, ServiceBinaryInfo]:
|
||||
services = services_key.get_subkeys()
|
||||
return {
|
||||
service_key.get_name(): ServiceBinaryInfo(
|
||||
SvcScan._get_service_dll(service_key),
|
||||
SvcScan._get_service_binary(service_key),
|
||||
)
|
||||
for service_key in services
|
||||
}
|
||||
|
||||
def _generator(self):
|
||||
kernel = self.context.modules[self.config["kernel"]]
|
||||
|
||||
@@ -157,6 +239,15 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
self.context, kernel.symbol_table_name, self.config_path
|
||||
)
|
||||
|
||||
# Building the dictionary ahead of time is much better for performance
|
||||
# vs looking up each service's DLL individually.
|
||||
services_key = self._get_service_key(kernel)
|
||||
service_binary_dll_map = (
|
||||
self._get_service_binary_map(services_key)
|
||||
if services_key is not None
|
||||
else {}
|
||||
)
|
||||
|
||||
relative_tag_offset = self.context.symbol_space.get_type(
|
||||
service_table_name + constants.BANG + "_SERVICE_RECORD"
|
||||
).relative_child_offset("Tag")
|
||||
@@ -209,7 +300,16 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
if not service_record.is_valid():
|
||||
continue
|
||||
|
||||
yield (0, self.get_record_tuple(service_record))
|
||||
service_info = service_binary_dll_map.get(
|
||||
service_record.get_name(),
|
||||
ServiceBinaryInfo(
|
||||
renderers.UnreadableValue(), renderers.UnreadableValue()
|
||||
),
|
||||
)
|
||||
yield (
|
||||
0,
|
||||
self.get_record_tuple(service_record, service_info),
|
||||
)
|
||||
else:
|
||||
service_header = self.context.object(
|
||||
service_table_name + constants.BANG + "_SERVICE_HEADER",
|
||||
@@ -227,7 +327,16 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
if service_record in seen:
|
||||
break
|
||||
seen.append(service_record)
|
||||
yield (0, self.get_record_tuple(service_record))
|
||||
service_info = service_binary_dll_map.get(
|
||||
service_record.get_name(),
|
||||
ServiceBinaryInfo(
|
||||
renderers.UnreadableValue(), renderers.UnreadableValue()
|
||||
),
|
||||
)
|
||||
yield (
|
||||
0,
|
||||
self.get_record_tuple(service_record, service_info),
|
||||
)
|
||||
|
||||
def run(self):
|
||||
return renderers.TreeGrid(
|
||||
@@ -241,6 +350,8 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
("Name", str),
|
||||
("Display", str),
|
||||
("Binary", str),
|
||||
("Binary (Registry)", str),
|
||||
("Dll", str),
|
||||
],
|
||||
self._generator(),
|
||||
)
|
||||
|
||||
@@ -28,9 +28,9 @@ def wintime_to_datetime(
|
||||
def unixtime_to_datetime(
|
||||
unixtime: int,
|
||||
) -> Union[interfaces.renderers.BaseAbsentValue, datetime.datetime]:
|
||||
ret: Union[
|
||||
interfaces.renderers.BaseAbsentValue, datetime.datetime
|
||||
] = renderers.UnparsableValue()
|
||||
ret: Union[interfaces.renderers.BaseAbsentValue, datetime.datetime] = (
|
||||
renderers.UnparsableValue()
|
||||
)
|
||||
|
||||
if unixtime > 0:
|
||||
with contextlib.suppress(ValueError):
|
||||
|
||||
@@ -35,9 +35,9 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface):
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self._dict: Dict[
|
||||
str, interfaces.symbols.BaseSymbolTableInterface
|
||||
] = collections.OrderedDict()
|
||||
self._dict: Dict[str, interfaces.symbols.BaseSymbolTableInterface] = (
|
||||
collections.OrderedDict()
|
||||
)
|
||||
# Permanently cache all resolved symbols
|
||||
self._resolved: Dict[str, interfaces.objects.Template] = {}
|
||||
self._resolved_symbols: Dict[str, interfaces.objects.Template] = {}
|
||||
@@ -73,9 +73,9 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface):
|
||||
self, offset: int, size: int = 0, table_name: str = None
|
||||
) -> Iterable[str]:
|
||||
"""Returns all symbols that exist at a specific relative address."""
|
||||
table_list: Iterable[
|
||||
interfaces.symbols.BaseSymbolTableInterface
|
||||
] = self._dict.values()
|
||||
table_list: Iterable[interfaces.symbols.BaseSymbolTableInterface] = (
|
||||
self._dict.values()
|
||||
)
|
||||
if table_name is not None:
|
||||
if table_name in self._dict:
|
||||
table_list = [self._dict[table_name]]
|
||||
@@ -179,15 +179,15 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface):
|
||||
if child.vol.type_name not in self._resolved:
|
||||
traverse_list.append(child.vol.type_name)
|
||||
try:
|
||||
self._resolved[
|
||||
child.vol.type_name
|
||||
] = self._weak_resolve(
|
||||
SymbolType.TYPE, child.vol.type_name
|
||||
self._resolved[child.vol.type_name] = (
|
||||
self._weak_resolve(
|
||||
SymbolType.TYPE, child.vol.type_name
|
||||
)
|
||||
)
|
||||
except exceptions.SymbolError:
|
||||
self._resolved[
|
||||
child.vol.type_name
|
||||
] = self.UnresolvedTemplate(child.vol.type_name)
|
||||
self._resolved[child.vol.type_name] = (
|
||||
self.UnresolvedTemplate(child.vol.type_name)
|
||||
)
|
||||
# Stash the replacement
|
||||
replacements.add((traverser, child))
|
||||
elif child.children:
|
||||
|
||||
@@ -408,7 +408,7 @@ class maple_tree(objects.StructType):
|
||||
# None. If however you wanted to parse from a node, but ignore some parts of the tree below it then
|
||||
# this could be populated with the addresses of the nodes you wish to ignore.
|
||||
|
||||
if seen == None:
|
||||
if seen is None:
|
||||
seen = set()
|
||||
|
||||
# protect against unlikely loop
|
||||
|
||||
@@ -452,9 +452,9 @@ class FILE_OBJECT(objects.StructType, pool.ExecutiveObject):
|
||||
].is_valid(self.FileName.Buffer)
|
||||
|
||||
def file_name_with_device(self) -> Union[str, interfaces.renderers.BaseAbsentValue]:
|
||||
name: Union[
|
||||
str, interfaces.renderers.BaseAbsentValue
|
||||
] = renderers.UnreadableValue()
|
||||
name: Union[str, interfaces.renderers.BaseAbsentValue] = (
|
||||
renderers.UnreadableValue()
|
||||
)
|
||||
|
||||
# this pointer needs to be checked against native_layer_name because the object may
|
||||
# be instantiated from a primary (virtual) layer or a memory (physical) layer.
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"symbols": {},
|
||||
"enums": {
|
||||
"StateEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_START_PENDING": 2,
|
||||
"SERVICE_STOP_PENDING": 3,
|
||||
"SERVICE_STOPPED": 1,
|
||||
"SERVICE_CONTINUE_PENDING": 5,
|
||||
"SERVICE_PAUSE_PENDING": 6,
|
||||
"SERVICE_PAUSED": 7,
|
||||
"SERVICE_RUNNING": 4
|
||||
},
|
||||
"size": 4
|
||||
},
|
||||
"StartEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_DEMAND_START": 3,
|
||||
"SERVICE_AUTO_START": 2,
|
||||
"SERVICE_BOOT_START": 0,
|
||||
"SERVICE_DISABLED": 4,
|
||||
"SERVICE_SYSTEM_START": 1
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"pointer": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned int": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned short": {
|
||||
"kind": "int",
|
||||
"size": 2,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
}
|
||||
},
|
||||
"user_types": {
|
||||
"_SERVICE_LIST_ENTRY": {
|
||||
"fields": {
|
||||
"Flink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 4
|
||||
},
|
||||
"Blink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 0
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 8
|
||||
},
|
||||
"_SERVICE_PROCESS": {
|
||||
"fields": {
|
||||
"BinaryPath": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
},
|
||||
"ProcessId": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 20
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 20
|
||||
},
|
||||
"_SERVICE_HEADER": {
|
||||
"fields": {
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"ServiceRecord": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 12
|
||||
},
|
||||
"_SERVICE_RECORD": {
|
||||
"fields": {
|
||||
"DisplayName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 48
|
||||
},
|
||||
"ServiceProcess": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_PROCESS"
|
||||
}
|
||||
},
|
||||
"offset": 160
|
||||
},
|
||||
"PrevEntry": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
},
|
||||
"Start": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StartEnum"
|
||||
},
|
||||
"offset": 24
|
||||
},
|
||||
"State": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StateEnum"
|
||||
},
|
||||
"offset": 56
|
||||
},
|
||||
"ServiceName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 44
|
||||
},
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"DriverName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 160
|
||||
},
|
||||
"Type": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
},
|
||||
"offset": 52
|
||||
},
|
||||
"Order": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 20
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 156
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "vtypes_to_json.py",
|
||||
"datetime": "2019-04-17T13:45:16.417006"
|
||||
},
|
||||
"format": "4.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
{
|
||||
"symbols": {},
|
||||
"enums": {
|
||||
"StateEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_START_PENDING": 2,
|
||||
"SERVICE_STOP_PENDING": 3,
|
||||
"SERVICE_STOPPED": 1,
|
||||
"SERVICE_CONTINUE_PENDING": 5,
|
||||
"SERVICE_PAUSE_PENDING": 6,
|
||||
"SERVICE_PAUSED": 7,
|
||||
"SERVICE_RUNNING": 4
|
||||
},
|
||||
"size": 4
|
||||
},
|
||||
"StartEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_DEMAND_START": 3,
|
||||
"SERVICE_AUTO_START": 2,
|
||||
"SERVICE_BOOT_START": 0,
|
||||
"SERVICE_DISABLED": 4,
|
||||
"SERVICE_SYSTEM_START": 1
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"pointer": {
|
||||
"kind": "int",
|
||||
"size": 8,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned int": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned short": {
|
||||
"kind": "int",
|
||||
"size": 2,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
}
|
||||
},
|
||||
"user_types": {
|
||||
"_SERVICE_LIST_ENTRY": {
|
||||
"fields": {
|
||||
"Flink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
},
|
||||
"Blink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 0
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
},
|
||||
"_SERVICE_PROCESS": {
|
||||
"fields": {
|
||||
"BinaryPath": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 24
|
||||
},
|
||||
"ProcessId": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 40
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 40
|
||||
},
|
||||
"_SERVICE_HEADER": {
|
||||
"fields": {
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"ServiceRecord": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
},
|
||||
"_SERVICE_RECORD": {
|
||||
"fields": {
|
||||
"ServiceList": {
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 32
|
||||
},
|
||||
"DisplayName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 64
|
||||
},
|
||||
"ServiceProcess": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_PROCESS"
|
||||
}
|
||||
},
|
||||
"offset": 240
|
||||
},
|
||||
"PrevEntry": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
},
|
||||
"Start": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StartEnum"
|
||||
},
|
||||
"offset": 36
|
||||
},
|
||||
"State": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StateEnum"
|
||||
},
|
||||
"offset": 76
|
||||
},
|
||||
"ServiceName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 56
|
||||
},
|
||||
"DriverName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 240
|
||||
},
|
||||
"Type": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
},
|
||||
"offset": 72
|
||||
},
|
||||
"Order": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 32
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 248
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "vtypes_to_json.py",
|
||||
"datetime": "2019-04-17T13:45:16.417006"
|
||||
},
|
||||
"format": "4.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"symbols": {},
|
||||
"enums": {
|
||||
"StateEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_START_PENDING": 2,
|
||||
"SERVICE_STOP_PENDING": 3,
|
||||
"SERVICE_STOPPED": 1,
|
||||
"SERVICE_CONTINUE_PENDING": 5,
|
||||
"SERVICE_PAUSE_PENDING": 6,
|
||||
"SERVICE_PAUSED": 7,
|
||||
"SERVICE_RUNNING": 4
|
||||
},
|
||||
"size": 4
|
||||
},
|
||||
"StartEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_DEMAND_START": 3,
|
||||
"SERVICE_AUTO_START": 2,
|
||||
"SERVICE_BOOT_START": 0,
|
||||
"SERVICE_DISABLED": 4,
|
||||
"SERVICE_SYSTEM_START": 1
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"pointer": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned int": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned short": {
|
||||
"kind": "int",
|
||||
"size": 2,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
}
|
||||
},
|
||||
"user_types": {
|
||||
"_SERVICE_LIST_ENTRY": {
|
||||
"fields": {
|
||||
"Flink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 4
|
||||
},
|
||||
"Blink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 0
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 8
|
||||
},
|
||||
"_SERVICE_PROCESS": {
|
||||
"fields": {
|
||||
"BinaryPath": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
},
|
||||
"ProcessId": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 20
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 20
|
||||
},
|
||||
"_SERVICE_HEADER": {
|
||||
"fields": {
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"ServiceRecord": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 12
|
||||
},
|
||||
"_SERVICE_RECORD": {
|
||||
"fields": {
|
||||
"DisplayName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 48
|
||||
},
|
||||
"ServiceProcess": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_PROCESS"
|
||||
}
|
||||
},
|
||||
"offset": 164
|
||||
},
|
||||
"PrevEntry": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
},
|
||||
"Start": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StartEnum"
|
||||
},
|
||||
"offset": 24
|
||||
},
|
||||
"State": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StateEnum"
|
||||
},
|
||||
"offset": 56
|
||||
},
|
||||
"ServiceName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 44
|
||||
},
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"DriverName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 164
|
||||
},
|
||||
"Type": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
},
|
||||
"offset": 52
|
||||
},
|
||||
"Order": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 20
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 156
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "vtypes_to_json.py",
|
||||
"datetime": "2019-04-17T13:45:16.417006"
|
||||
},
|
||||
"format": "4.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
{
|
||||
"symbols": {},
|
||||
"enums": {
|
||||
"StateEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_START_PENDING": 2,
|
||||
"SERVICE_STOP_PENDING": 3,
|
||||
"SERVICE_STOPPED": 1,
|
||||
"SERVICE_CONTINUE_PENDING": 5,
|
||||
"SERVICE_PAUSE_PENDING": 6,
|
||||
"SERVICE_PAUSED": 7,
|
||||
"SERVICE_RUNNING": 4
|
||||
},
|
||||
"size": 4
|
||||
},
|
||||
"StartEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_DEMAND_START": 3,
|
||||
"SERVICE_AUTO_START": 2,
|
||||
"SERVICE_BOOT_START": 0,
|
||||
"SERVICE_DISABLED": 4,
|
||||
"SERVICE_SYSTEM_START": 1
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"pointer": {
|
||||
"kind": "int",
|
||||
"size": 8,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned int": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned short": {
|
||||
"kind": "int",
|
||||
"size": 2,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
}
|
||||
},
|
||||
"user_types": {
|
||||
"_SERVICE_LIST_ENTRY": {
|
||||
"fields": {
|
||||
"Flink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
},
|
||||
"Blink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 0
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
},
|
||||
"_SERVICE_PROCESS": {
|
||||
"fields": {
|
||||
"BinaryPath": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 24
|
||||
},
|
||||
"ProcessId": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 40
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 40
|
||||
},
|
||||
"_SERVICE_HEADER": {
|
||||
"fields": {
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"ServiceRecord": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
},
|
||||
"_SERVICE_RECORD": {
|
||||
"fields": {
|
||||
"ServiceList": {
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 32
|
||||
},
|
||||
"DisplayName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 64
|
||||
},
|
||||
"ServiceProcess": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_PROCESS"
|
||||
}
|
||||
},
|
||||
"offset": 296
|
||||
},
|
||||
"PrevEntry": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
},
|
||||
"Start": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StartEnum"
|
||||
},
|
||||
"offset": 36
|
||||
},
|
||||
"State": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StateEnum"
|
||||
},
|
||||
"offset": 76
|
||||
},
|
||||
"ServiceName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 56
|
||||
},
|
||||
"DriverName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 296
|
||||
},
|
||||
"Type": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
},
|
||||
"offset": 72
|
||||
},
|
||||
"Order": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 32
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 296
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "David McDonald",
|
||||
"datetime": "2023-11-16T15:05:35-06:00"
|
||||
},
|
||||
"format": "4.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"symbols": {},
|
||||
"enums": {
|
||||
"StateEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_START_PENDING": 2,
|
||||
"SERVICE_STOP_PENDING": 3,
|
||||
"SERVICE_STOPPED": 1,
|
||||
"SERVICE_CONTINUE_PENDING": 5,
|
||||
"SERVICE_PAUSE_PENDING": 6,
|
||||
"SERVICE_PAUSED": 7,
|
||||
"SERVICE_RUNNING": 4
|
||||
},
|
||||
"size": 4
|
||||
},
|
||||
"StartEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_DEMAND_START": 3,
|
||||
"SERVICE_AUTO_START": 2,
|
||||
"SERVICE_BOOT_START": 0,
|
||||
"SERVICE_DISABLED": 4,
|
||||
"SERVICE_SYSTEM_START": 1
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"pointer": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned int": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned short": {
|
||||
"kind": "int",
|
||||
"size": 2,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
}
|
||||
},
|
||||
"user_types": {
|
||||
"_SERVICE_LIST_ENTRY": {
|
||||
"fields": {
|
||||
"Flink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 4
|
||||
},
|
||||
"Blink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 0
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 8
|
||||
},
|
||||
"_SERVICE_PROCESS": {
|
||||
"fields": {
|
||||
"BinaryPath": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
},
|
||||
"ProcessId": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 20
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 20
|
||||
},
|
||||
"_SERVICE_HEADER": {
|
||||
"fields": {
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"ServiceRecord": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 12
|
||||
},
|
||||
"_SERVICE_RECORD": {
|
||||
"fields": {
|
||||
"DisplayName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 48
|
||||
},
|
||||
"ServiceProcess": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_PROCESS"
|
||||
}
|
||||
},
|
||||
"offset": 192
|
||||
},
|
||||
"PrevEntry": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 12
|
||||
},
|
||||
"Start": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StartEnum"
|
||||
},
|
||||
"offset": 24
|
||||
},
|
||||
"State": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StateEnum"
|
||||
},
|
||||
"offset": 56
|
||||
},
|
||||
"ServiceName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 44
|
||||
},
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"DriverName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 192
|
||||
},
|
||||
"Type": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
},
|
||||
"offset": 52
|
||||
},
|
||||
"Order": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 20
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 192
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "vtypes_to_json.py",
|
||||
"datetime": "2019-04-17T13:45:16.417006"
|
||||
},
|
||||
"format": "4.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
{
|
||||
"symbols": {},
|
||||
"enums": {
|
||||
"StateEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_START_PENDING": 2,
|
||||
"SERVICE_STOP_PENDING": 3,
|
||||
"SERVICE_STOPPED": 1,
|
||||
"SERVICE_CONTINUE_PENDING": 5,
|
||||
"SERVICE_PAUSE_PENDING": 6,
|
||||
"SERVICE_PAUSED": 7,
|
||||
"SERVICE_RUNNING": 4
|
||||
},
|
||||
"size": 4
|
||||
},
|
||||
"StartEnum": {
|
||||
"base": "long",
|
||||
"constants": {
|
||||
"SERVICE_DEMAND_START": 3,
|
||||
"SERVICE_AUTO_START": 2,
|
||||
"SERVICE_BOOT_START": 0,
|
||||
"SERVICE_DISABLED": 4,
|
||||
"SERVICE_SYSTEM_START": 1
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"pointer": {
|
||||
"kind": "int",
|
||||
"size": 8,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned int": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned short": {
|
||||
"kind": "int",
|
||||
"size": 2,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"long": {
|
||||
"kind": "int",
|
||||
"size": 4,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
}
|
||||
},
|
||||
"user_types": {
|
||||
"_SERVICE_LIST_ENTRY": {
|
||||
"fields": {
|
||||
"Flink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
},
|
||||
"Blink": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
}
|
||||
},
|
||||
"offset": 0
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
},
|
||||
"_SERVICE_PROCESS": {
|
||||
"fields": {
|
||||
"BinaryPath": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 24
|
||||
},
|
||||
"ProcessId": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 40
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 40
|
||||
},
|
||||
"_SERVICE_HEADER": {
|
||||
"fields": {
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"ServiceRecord": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
},
|
||||
"_SERVICE_RECORD": {
|
||||
"fields": {
|
||||
"ServiceList": {
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_LIST_ENTRY"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"Tag": {
|
||||
"type": {
|
||||
"count": 4,
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
},
|
||||
"kind": "array"
|
||||
},
|
||||
"offset": 32
|
||||
},
|
||||
"DisplayName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 64
|
||||
},
|
||||
"ServiceProcess": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_PROCESS"
|
||||
}
|
||||
},
|
||||
"offset": 336
|
||||
},
|
||||
"PrevEntry": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "struct",
|
||||
"name": "_SERVICE_RECORD"
|
||||
}
|
||||
},
|
||||
"offset": 16
|
||||
},
|
||||
"Start": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StartEnum"
|
||||
},
|
||||
"offset": 36
|
||||
},
|
||||
"State": {
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "StateEnum"
|
||||
},
|
||||
"offset": 84
|
||||
},
|
||||
"ServiceName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 56
|
||||
},
|
||||
"DriverName": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"offset": 296
|
||||
},
|
||||
"Type": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
},
|
||||
"offset": 80
|
||||
},
|
||||
"Order": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned int"
|
||||
},
|
||||
"offset": 32
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 336
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "David McDonald",
|
||||
"datetime": "2023-11-16T15:05:35-06:00"
|
||||
},
|
||||
"format": "4.1.0"
|
||||
}
|
||||
}
|
||||
@@ -151,11 +151,45 @@ is_win10_16299_or_later = OsDistinguisher(
|
||||
],
|
||||
)
|
||||
|
||||
is_win10_17763_or_later = OsDistinguisher(
|
||||
version_check=lambda x: x >= (10, 0, 17763),
|
||||
fallback_checks=[
|
||||
("_EPROCESS", "TrustletIdentity", False),
|
||||
("ParentSecurityDomain", None, True),
|
||||
],
|
||||
)
|
||||
|
||||
is_win10_18362_or_later = OsDistinguisher(
|
||||
version_check=lambda x: x >= (10, 0, 18362),
|
||||
fallback_checks=[
|
||||
("ObHeaderCookie", None, True),
|
||||
("_CM_CACHED_VALUE_INDEX", None, False),
|
||||
("_WNF_PROCESS_CONTEXT", None, True),
|
||||
],
|
||||
)
|
||||
|
||||
is_win10_18363_or_later = OsDistinguisher(
|
||||
version_check=lambda x: x >= (10, 0, 18363),
|
||||
fallback_checks=[("_KQOS_GROUPING_SETS", None, True)],
|
||||
)
|
||||
|
||||
is_win10_19041_or_later = OsDistinguisher(
|
||||
version_check=lambda x: x >= (10, 0, 19041),
|
||||
fallback_checks=[
|
||||
("_EPROCESS", "TimerResolutionIgnore", True),
|
||||
("_EPROCESS", "VmProcessorHostTransition", True),
|
||||
("_KQOS_GROUPING_SETS", None, True),
|
||||
],
|
||||
)
|
||||
|
||||
is_win10_25398_or_later = OsDistinguisher(
|
||||
version_check=lambda x: x >= (10, 0, 25398),
|
||||
fallback_checks=[
|
||||
("_EPROCESS", "MmSlabIdentity", True),
|
||||
("_EPROCESS", "EnableProcessImpersonationLogging", True),
|
||||
],
|
||||
)
|
||||
|
||||
is_windows_10 = OsDistinguisher(
|
||||
version_check=lambda x: x >= (10, 0),
|
||||
fallback_checks=[("ObHeaderCookie", None, True)],
|
||||
|
||||
@@ -31,13 +31,9 @@ class Statistics(plugins.PluginInterface):
|
||||
# Do mass mapping and determine the number of different layers and how many pages go to each one
|
||||
layer = self.context.layers[self.config["primary"]]
|
||||
|
||||
page_count = (
|
||||
swap_count
|
||||
) = (
|
||||
invalid_page_count
|
||||
) = (
|
||||
large_page_count
|
||||
) = large_swap_count = large_invalid_count = other_invalid = 0
|
||||
page_count = swap_count = invalid_page_count = large_page_count = (
|
||||
large_swap_count
|
||||
) = large_invalid_count = other_invalid = 0
|
||||
|
||||
if isinstance(layer, intel.Intel):
|
||||
page_addr = 0
|
||||
|
||||
Reference in New Issue
Block a user