From 78eb31014b0a97145582d8ae4beef598c2659b1f Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Mon, 2 May 2022 00:00:33 +0900 Subject: [PATCH 01/24] Fix: get owning process method from _ETHREAD --- volatility3/framework/symbols/windows/extensions/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/volatility3/framework/symbols/windows/extensions/__init__.py b/volatility3/framework/symbols/windows/extensions/__init__.py index 7d083fbba..fd5e075da 100755 --- a/volatility3/framework/symbols/windows/extensions/__init__.py +++ b/volatility3/framework/symbols/windows/extensions/__init__.py @@ -448,9 +448,9 @@ class KMUTANT(objects.StructType, pool.ExecutiveObject): class ETHREAD(objects.StructType): """A class for executive thread objects.""" - def owning_process(self, kernel_layer: str = None) -> interfaces.objects.ObjectInterface: + def owning_process(self) -> interfaces.objects.ObjectInterface: """Return the EPROCESS that owns this thread.""" - return self.ThreadsProcess.dereference(kernel_layer) + return self.Tcb.Process.dereference().cast("_EPROCESS") def get_cross_thread_flags(self) -> str: dictCrossThreadFlags = { From 51b901960169b5681f4a1cbebf03c19997685232 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Mon, 2 May 2022 10:34:04 +0900 Subject: [PATCH 02/24] Bump: patch version 2.1.1 --- volatility3/framework/constants/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index 5060906d5..e08bc42bc 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -40,7 +40,7 @@ BANG = "!" # We use the SemVer 2.0.0 versioning scheme VERSION_MAJOR = 2 # Number of releases of the library with a breaking change VERSION_MINOR = 1 # Number of changes that only add to the interface -VERSION_PATCH = 0 # Number of changes that do not change the interface +VERSION_PATCH = 1 # Number of changes that do not change the interface VERSION_SUFFIX = "" # TODO: At version 2.0.0, remove the symbol_shift feature From f4dd582f158e8024e3fc5b4fba21a727f0913bfb Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 10 May 2022 12:29:36 +0900 Subject: [PATCH 03/24] Fix: ThreadsProcess for windows older version --- .../framework/symbols/windows/extensions/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/volatility3/framework/symbols/windows/extensions/__init__.py b/volatility3/framework/symbols/windows/extensions/__init__.py index b317f7693..ccfcb4290 100755 --- a/volatility3/framework/symbols/windows/extensions/__init__.py +++ b/volatility3/framework/symbols/windows/extensions/__init__.py @@ -450,7 +450,12 @@ class ETHREAD(objects.StructType): def owning_process(self) -> interfaces.objects.ObjectInterface: """Return the EPROCESS that owns this thread.""" - return self.Tcb.Process.dereference().cast("_EPROCESS") + if(self.has_member("ThreadsProcess")): + return self.ThreadsProcess.dereference().cast("_EPROCESS") + elif(self.has_member("Tcb") and self.Tcb.has_member("Process")): + return self.Tcb.Process.dereference().cast("_EPROCESS") + else: + raise AttributeError("Unable to find the owning process of ethread") def get_cross_thread_flags(self) -> str: dictCrossThreadFlags = { From 1125be122e8d330cad156ba67a279bf83f22c2f0 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 10 May 2022 12:31:56 +0900 Subject: [PATCH 04/24] Add: code comment for windows version --- volatility3/framework/symbols/windows/extensions/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/volatility3/framework/symbols/windows/extensions/__init__.py b/volatility3/framework/symbols/windows/extensions/__init__.py index ccfcb4290..a1c347ed2 100755 --- a/volatility3/framework/symbols/windows/extensions/__init__.py +++ b/volatility3/framework/symbols/windows/extensions/__init__.py @@ -450,6 +450,7 @@ class ETHREAD(objects.StructType): def owning_process(self) -> interfaces.objects.ObjectInterface: """Return the EPROCESS that owns this thread.""" + if(self.has_member("ThreadsProcess")): return self.ThreadsProcess.dereference().cast("_EPROCESS") elif(self.has_member("Tcb") and self.Tcb.has_member("Process")): From 3956f0ecc0406f32482123c0c1866755b8fd7cf7 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 10 May 2022 12:36:56 +0900 Subject: [PATCH 05/24] Add: code comment for windows version --- volatility3/framework/symbols/windows/extensions/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/volatility3/framework/symbols/windows/extensions/__init__.py b/volatility3/framework/symbols/windows/extensions/__init__.py index a1c347ed2..805f8c26b 100755 --- a/volatility3/framework/symbols/windows/extensions/__init__.py +++ b/volatility3/framework/symbols/windows/extensions/__init__.py @@ -451,8 +451,10 @@ class ETHREAD(objects.StructType): def owning_process(self) -> interfaces.objects.ObjectInterface: """Return the EPROCESS that owns this thread.""" + # For Windows XPs if(self.has_member("ThreadsProcess")): return self.ThreadsProcess.dereference().cast("_EPROCESS") + # For Windows Vista and later versions elif(self.has_member("Tcb") and self.Tcb.has_member("Process")): return self.Tcb.Process.dereference().cast("_EPROCESS") else: From 690d8e3efe8ec08d4500b75ba60f14a281a52673 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 10 May 2022 19:07:04 +0900 Subject: [PATCH 06/24] Fix: sync bump version --- volatility3/framework/constants/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index e08bc42bc..472a743e6 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -39,8 +39,8 @@ BANG = "!" # We use the SemVer 2.0.0 versioning scheme VERSION_MAJOR = 2 # Number of releases of the library with a breaking change -VERSION_MINOR = 1 # Number of changes that only add to the interface -VERSION_PATCH = 1 # Number of changes that do not change the interface +VERSION_MINOR = 2 # Number of changes that only add to the interface +VERSION_PATCH = 0 # Number of changes that do not change the interface VERSION_SUFFIX = "" # TODO: At version 2.0.0, remove the symbol_shift feature From a5bf5548b8d7e83ffd3b9065e968e321f6fcc964 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 10 May 2022 19:08:29 +0900 Subject: [PATCH 07/24] Bump: patch version 2.2.1 --- volatility3/framework/constants/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index 472a743e6..44b98b95f 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -40,7 +40,7 @@ BANG = "!" # We use the SemVer 2.0.0 versioning scheme VERSION_MAJOR = 2 # Number of releases of the library with a breaking change VERSION_MINOR = 2 # Number of changes that only add to the interface -VERSION_PATCH = 0 # Number of changes that do not change the interface +VERSION_PATCH = 1 # Number of changes that do not change the interface VERSION_SUFFIX = "" # TODO: At version 2.0.0, remove the symbol_shift feature From e5dfc47cc419d4d1ac929782008bc24765f46428 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 10 May 2022 19:08:56 +0900 Subject: [PATCH 08/24] Fix: required framework version of psscan by bump --- volatility3/framework/plugins/windows/psscan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/plugins/windows/psscan.py b/volatility3/framework/plugins/windows/psscan.py index a0601aef1..cc030b4bf 100644 --- a/volatility3/framework/plugins/windows/psscan.py +++ b/volatility3/framework/plugins/windows/psscan.py @@ -22,7 +22,7 @@ vollog = logging.getLogger(__name__) class PsScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): """Scans for processes present in a particular windows memory image.""" - _required_framework_version = (2, 0, 0) + _required_framework_version = (2, 2, 1) _version = (1, 1, 0) @classmethod From 7755328226af96ba811a63d06c8d222877cf28a8 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Fri, 22 Jul 2022 01:11:35 +0900 Subject: [PATCH 09/24] Fix: psscan required framework version bump --- volatility3/framework/plugins/windows/psscan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/plugins/windows/psscan.py b/volatility3/framework/plugins/windows/psscan.py index cc030b4bf..335624672 100644 --- a/volatility3/framework/plugins/windows/psscan.py +++ b/volatility3/framework/plugins/windows/psscan.py @@ -22,7 +22,7 @@ vollog = logging.getLogger(__name__) class PsScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): """Scans for processes present in a particular windows memory image.""" - _required_framework_version = (2, 2, 1) + _required_framework_version = (2, 3, 1) _version = (1, 1, 0) @classmethod From 989b4c73273b1acfd767f64a63599fbc511d77dc Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Fri, 5 Aug 2022 03:08:18 +0900 Subject: [PATCH 10/24] Fix: cache path for python of Windows Store version --- volatility3/framework/constants/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index 3b499adea..e83d27108 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -64,7 +64,7 @@ CACHE_PATH = os.path.join(os.path.expanduser("~"), ".cache", "volatility3") """Default path to store cached data""" if sys.platform == 'win32': - CACHE_PATH = os.path.join(os.environ.get("APPDATA", os.path.expanduser("~")), "volatility3") + CACHE_PATH = os.path.realpath(os.path.join(os.environ.get("APPDATA", os.path.expanduser("~")), "volatility3")) os.makedirs(CACHE_PATH, exist_ok = True) LINUX_BANNERS_PATH = os.path.join(CACHE_PATH, "linux_banners.cache") From 471551fda0bc5871f8738f05b06fef1f35c5f826 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 03:13:40 +0900 Subject: [PATCH 11/24] Add: initialize for windows.joblinks plugin --- test/test_volatility.py | 5 ++ .../framework/plugins/windows/joblinks.py | 72 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 volatility3/framework/plugins/windows/joblinks.py diff --git a/test/test_volatility.py b/test/test_volatility.py index 515bef1cc..1126aa9d7 100644 --- a/test/test_volatility.py +++ b/test/test_volatility.py @@ -203,6 +203,11 @@ def test_windows_devicetree(image, volatility, python): assert out.find(b"FILE_DEVICE_DISK_FILE_SYSTEM") != -1 assert rc == 0 +def test_windows_joblinks(image, volatility, python): + rc, out, err = runvol_plugin("windows.joblinks.JobLinks", image, volatility, python) + + assert rc == 0 + # LINUX def test_linux_pslist(image, volatility, python): diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py new file mode 100644 index 000000000..c440cad29 --- /dev/null +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -0,0 +1,72 @@ +# 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 typing import Iterable, Iterator, List, Tuple + +from volatility3.framework import exceptions, interfaces, renderers +from volatility3.framework.configuration import requirements +from volatility3.framework.constants import LOGLEVEL_VVVV +from volatility3.framework.objects import utility +from volatility3.framework.renderers import format_hints +from volatility3.plugins.windows import pslist + +vollog = logging.getLogger(__name__) + +class JobLinks(interfaces.plugins.PluginInterface): + """Print process job link information""" + + _required_framework_version = (2, 0, 0) + _version = (1, 0, 0) + + @classmethod + def get_requirements(cls)-> List[interfaces.configuration.RequirementInterface]: + return [ + requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel', + architectures = ["Intel32", "Intel64"]), + requirements.BooleanRequirement(name = 'physical', + description = "Display physical offset instead of virtual", + default = False, + optional = True), + requirements.VersionRequirement(name = 'pslist', component = pslist.PsList, version = (2, 0, 0)) + ] + + def _generator(self) -> Iterator[Tuple]: + kernel = self.context.modules[self.config['kernel']] + memory = self.context.layers[kernel.layer_name] + + for proc in pslist.PsList.list_processes(self.context, kernel.layer_name, + kernel.symbol_table_name): + try: + if not self.config['physical']: + offset = proc.vol.offset + else: + (_, _, offset, _, _) = list(memory.mapping(offset = proc.vol.offset, length = 0))[0] + + job = proc.Job.dereference() + + yield (0, ( + format_hints.Hex(offset), utility.array_to_string(proc.ImageFileName), proc.UniqueProcessId, + proc.InheritedFromUniqueProcessId, proc.get_session_id(), job.SessionId, proc.get_is_wow64(), + job.TotalProcesses, job.ActiveProcesses, job.TotalTerminatedProcesses, + renderers.NotApplicableValue(), + "(Original Process)" + )) + + vollog.log(LOGLEVEL_VVVV, proc.JobLinks) + vollog.log(LOGLEVEL_VVVV, job.JobLinks) + vollog.log(LOGLEVEL_VVVV, job.ProcessListHead) + + except (exceptions.InvalidAddressException): + continue + + def run(self)-> renderers.TreeGrid: + offsettype = "(V)" if not self.config.get('physical', pslist.PsList.PHYSICAL_DEFAULT) else "(P)" + + return renderers.TreeGrid([ + (f"Offset{offsettype}", format_hints.Hex), ("Name", str), ("PID", int), + ("PPID", int), ("Sess", int), ("JobSess", int), ("Wow64", bool), + ("Total", int), ("Active", int), ("Term", int), ("JobLink", str), ("Process", str) + ], self._generator()) \ No newline at end of file From e0edb87d7f15b883aea2fbec5539ec1850307037 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 03:25:21 +0900 Subject: [PATCH 12/24] Add: EOF --- volatility3/framework/plugins/windows/joblinks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index c440cad29..2ca32e09d 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -69,4 +69,4 @@ class JobLinks(interfaces.plugins.PluginInterface): (f"Offset{offsettype}", format_hints.Hex), ("Name", str), ("PID", int), ("PPID", int), ("Sess", int), ("JobSess", int), ("Wow64", bool), ("Total", int), ("Active", int), ("Term", int), ("JobLink", str), ("Process", str) - ], self._generator()) \ No newline at end of file + ], self._generator()) From 7bec33b07d9ab74e798bee315ae9bb8ed8eab26d Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 14:40:35 +0900 Subject: [PATCH 13/24] Add: debug log code --- .../framework/plugins/windows/joblinks.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index 2ca32e09d..e5a206af2 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -56,8 +56,24 @@ class JobLinks(interfaces.plugins.PluginInterface): )) vollog.log(LOGLEVEL_VVVV, proc.JobLinks) + vollog.log(LOGLEVEL_VVVV, hex(proc.JobLinks.Flink)) + vollog.log(LOGLEVEL_VVVV, hex(proc.JobLinks.Blink)) vollog.log(LOGLEVEL_VVVV, job.JobLinks) + vollog.log(LOGLEVEL_VVVV, hex(job.JobLinks.Flink)) + vollog.log(LOGLEVEL_VVVV, hex(job.JobLinks.Blink)) vollog.log(LOGLEVEL_VVVV, job.ProcessListHead) + vollog.log(LOGLEVEL_VVVV, hex(job.ProcessListHead.Flink)) + vollog.log(LOGLEVEL_VVVV, hex(job.ProcessListHead.Blink)) + vollog.log(LOGLEVEL_VVVV, "") + + for entry in job.ProcessListHead.to_list(proc.vol.type_name, "JobLinks"): + yield (1, ( + format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), entry.UniqueProcessId, + entry.InheritedFromUniqueProcessId, entry.get_session_id(), renderers.NotApplicableValue(), entry.get_is_wow64(), + renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), + renderers.NotApplicableValue(), + "(Original Process)" + )) except (exceptions.InvalidAddressException): continue From fa686a9fa69c23361df9410b860823b34e31fe38 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 15:04:24 +0900 Subject: [PATCH 14/24] Add: Peb.ProcessParameters.ImagePathName --- volatility3/framework/plugins/windows/joblinks.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index e5a206af2..1ee64544f 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -55,24 +55,13 @@ class JobLinks(interfaces.plugins.PluginInterface): "(Original Process)" )) - vollog.log(LOGLEVEL_VVVV, proc.JobLinks) - vollog.log(LOGLEVEL_VVVV, hex(proc.JobLinks.Flink)) - vollog.log(LOGLEVEL_VVVV, hex(proc.JobLinks.Blink)) - vollog.log(LOGLEVEL_VVVV, job.JobLinks) - vollog.log(LOGLEVEL_VVVV, hex(job.JobLinks.Flink)) - vollog.log(LOGLEVEL_VVVV, hex(job.JobLinks.Blink)) - vollog.log(LOGLEVEL_VVVV, job.ProcessListHead) - vollog.log(LOGLEVEL_VVVV, hex(job.ProcessListHead.Flink)) - vollog.log(LOGLEVEL_VVVV, hex(job.ProcessListHead.Blink)) - vollog.log(LOGLEVEL_VVVV, "") - for entry in job.ProcessListHead.to_list(proc.vol.type_name, "JobLinks"): yield (1, ( format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), entry.UniqueProcessId, entry.InheritedFromUniqueProcessId, entry.get_session_id(), renderers.NotApplicableValue(), entry.get_is_wow64(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), - renderers.NotApplicableValue(), - "(Original Process)" + "Yes", + entry.get_peb().ProcessParameters.ImagePathName.get_string() )) except (exceptions.InvalidAddressException): From ea65649548d708aabe2b4568aa712ef3e8e58ff2 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 15:08:13 +0900 Subject: [PATCH 15/24] Remove: test_windows_joblinks function for test --- test/test_volatility.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/test_volatility.py b/test/test_volatility.py index 1126aa9d7..515bef1cc 100644 --- a/test/test_volatility.py +++ b/test/test_volatility.py @@ -203,11 +203,6 @@ def test_windows_devicetree(image, volatility, python): assert out.find(b"FILE_DEVICE_DISK_FILE_SYSTEM") != -1 assert rc == 0 -def test_windows_joblinks(image, volatility, python): - rc, out, err = runvol_plugin("windows.joblinks.JobLinks", image, volatility, python) - - assert rc == 0 - # LINUX def test_linux_pslist(image, volatility, python): From 65e7b5302c12068cb78b712d8358f4870eab49dd Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 15:18:11 +0900 Subject: [PATCH 16/24] Fix: job detail info to zero --- volatility3/framework/plugins/windows/joblinks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index 1ee64544f..321e6f791 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -58,8 +58,8 @@ class JobLinks(interfaces.plugins.PluginInterface): for entry in job.ProcessListHead.to_list(proc.vol.type_name, "JobLinks"): yield (1, ( format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), entry.UniqueProcessId, - entry.InheritedFromUniqueProcessId, entry.get_session_id(), renderers.NotApplicableValue(), entry.get_is_wow64(), - renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), + entry.InheritedFromUniqueProcessId, entry.get_session_id(), 0, entry.get_is_wow64(), + 0, 0, 0, "Yes", entry.get_peb().ProcessParameters.ImagePathName.get_string() )) From 3556b2374a3f9593d58564431d057ead5859cea7 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 15:22:07 +0900 Subject: [PATCH 17/24] Fix: indent for prettier code --- volatility3/framework/plugins/windows/joblinks.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index 321e6f791..e88b7a3d3 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -57,12 +57,12 @@ class JobLinks(interfaces.plugins.PluginInterface): for entry in job.ProcessListHead.to_list(proc.vol.type_name, "JobLinks"): yield (1, ( - format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), entry.UniqueProcessId, - entry.InheritedFromUniqueProcessId, entry.get_session_id(), 0, entry.get_is_wow64(), - 0, 0, 0, - "Yes", - entry.get_peb().ProcessParameters.ImagePathName.get_string() - )) + format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), entry.UniqueProcessId, + entry.InheritedFromUniqueProcessId, entry.get_session_id(), 0, entry.get_is_wow64(), + 0, 0, 0, + "Yes", + entry.get_peb().ProcessParameters.ImagePathName.get_string() + )) except (exceptions.InvalidAddressException): continue From 2918c13046b91ecdae1fba6599d291fc7ba95ce7 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 15:24:40 +0900 Subject: [PATCH 18/24] Fix: offset for job entry --- volatility3/framework/plugins/windows/joblinks.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index e88b7a3d3..39089a741 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -56,6 +56,12 @@ class JobLinks(interfaces.plugins.PluginInterface): )) for entry in job.ProcessListHead.to_list(proc.vol.type_name, "JobLinks"): + + if not self.config['physical']: + offset = entry.vol.offset + else: + (_, _, offset, _, _) = list(memory.mapping(offset = entry.vol.offset, length = 0))[0] + yield (1, ( format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), entry.UniqueProcessId, entry.InheritedFromUniqueProcessId, entry.get_session_id(), 0, entry.get_is_wow64(), From cd6a73939ed19426e47209c532481c962b223204 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 15:27:39 +0900 Subject: [PATCH 19/24] Refactor: apply code style by yapf --- .../framework/plugins/windows/joblinks.py | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index 39089a741..e30044538 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -15,6 +15,7 @@ from volatility3.plugins.windows import pslist vollog = logging.getLogger(__name__) + class JobLinks(interfaces.plugins.PluginInterface): """Print process job link information""" @@ -22,62 +23,54 @@ class JobLinks(interfaces.plugins.PluginInterface): _version = (1, 0, 0) @classmethod - def get_requirements(cls)-> List[interfaces.configuration.RequirementInterface]: + def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: return [ - requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel', + requirements.ModuleRequirement(name = 'kernel', + description = 'Windows kernel', architectures = ["Intel32", "Intel64"]), requirements.BooleanRequirement(name = 'physical', description = "Display physical offset instead of virtual", default = False, optional = True), - requirements.VersionRequirement(name = 'pslist', component = pslist.PsList, version = (2, 0, 0)) + requirements.VersionRequirement(name = 'pslist', component = pslist.PsList, version = (2, 0, 0)) ] def _generator(self) -> Iterator[Tuple]: kernel = self.context.modules[self.config['kernel']] memory = self.context.layers[kernel.layer_name] - for proc in pslist.PsList.list_processes(self.context, kernel.layer_name, - kernel.symbol_table_name): + for proc in pslist.PsList.list_processes(self.context, kernel.layer_name, kernel.symbol_table_name): try: if not self.config['physical']: offset = proc.vol.offset else: (_, _, offset, _, _) = list(memory.mapping(offset = proc.vol.offset, length = 0))[0] - + job = proc.Job.dereference() - - yield (0, ( - format_hints.Hex(offset), utility.array_to_string(proc.ImageFileName), proc.UniqueProcessId, - proc.InheritedFromUniqueProcessId, proc.get_session_id(), job.SessionId, proc.get_is_wow64(), - job.TotalProcesses, job.ActiveProcesses, job.TotalTerminatedProcesses, - renderers.NotApplicableValue(), - "(Original Process)" - )) + + yield (0, (format_hints.Hex(offset), utility.array_to_string(proc.ImageFileName), proc.UniqueProcessId, + proc.InheritedFromUniqueProcessId, proc.get_session_id(), job.SessionId, proc.get_is_wow64(), + job.TotalProcesses, job.ActiveProcesses, job.TotalTerminatedProcesses, + renderers.NotApplicableValue(), "(Original Process)")) for entry in job.ProcessListHead.to_list(proc.vol.type_name, "JobLinks"): - if not self.config['physical']: offset = entry.vol.offset else: (_, _, offset, _, _) = list(memory.mapping(offset = entry.vol.offset, length = 0))[0] - yield (1, ( - format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), entry.UniqueProcessId, - entry.InheritedFromUniqueProcessId, entry.get_session_id(), 0, entry.get_is_wow64(), - 0, 0, 0, - "Yes", - entry.get_peb().ProcessParameters.ImagePathName.get_string() - )) + yield (1, (format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName), + entry.UniqueProcessId, entry.InheritedFromUniqueProcessId, entry.get_session_id(), 0, + entry.get_is_wow64(), 0, 0, 0, "Yes", + entry.get_peb().ProcessParameters.ImagePathName.get_string())) except (exceptions.InvalidAddressException): continue - def run(self)-> renderers.TreeGrid: + def run(self) -> renderers.TreeGrid: offsettype = "(V)" if not self.config.get('physical', pslist.PsList.PHYSICAL_DEFAULT) else "(P)" - return renderers.TreeGrid([ - (f"Offset{offsettype}", format_hints.Hex), ("Name", str), ("PID", int), - ("PPID", int), ("Sess", int), ("JobSess", int), ("Wow64", bool), - ("Total", int), ("Active", int), ("Term", int), ("JobLink", str), ("Process", str) - ], self._generator()) + return renderers.TreeGrid([(f"Offset{offsettype}", format_hints.Hex), ("Name", str), + ("PID", int), ("PPID", int), ("Sess", int), ("JobSess", int), ("Wow64", bool), + ("Total", int), ("Active", int), ("Term", int), ("JobLink", str), ("Process", str)], + self._generator()) From 0aedc6a071c9bc0a2b88a7ef978a80be3a9d2e03 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Tue, 9 Aug 2022 15:40:17 +0900 Subject: [PATCH 20/24] Remove: unused module --- volatility3/framework/plugins/windows/joblinks.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/volatility3/framework/plugins/windows/joblinks.py b/volatility3/framework/plugins/windows/joblinks.py index e30044538..40d09b9ea 100644 --- a/volatility3/framework/plugins/windows/joblinks.py +++ b/volatility3/framework/plugins/windows/joblinks.py @@ -4,11 +4,10 @@ import logging -from typing import Iterable, Iterator, List, Tuple +from typing import Iterator, List, Tuple from volatility3.framework import exceptions, interfaces, renderers from volatility3.framework.configuration import requirements -from volatility3.framework.constants import LOGLEVEL_VVVV from volatility3.framework.objects import utility from volatility3.framework.renderers import format_hints from volatility3.plugins.windows import pslist From 154659cd0d0049ba7be1911af9a7add6ba3e5fa8 Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Sun, 21 Aug 2022 04:58:54 +0900 Subject: [PATCH 21/24] Fix: typo for cache sqlite schema version --- volatility3/framework/automagic/symbol_cache.py | 6 +++--- volatility3/framework/constants/__init__.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/volatility3/framework/automagic/symbol_cache.py b/volatility3/framework/automagic/symbol_cache.py index 558bfb2f1..ab19965c7 100644 --- a/volatility3/framework/automagic/symbol_cache.py +++ b/volatility3/framework/automagic/symbol_cache.py @@ -171,11 +171,11 @@ class SqliteCache(CacheManagerInterface): database = sqlite3.connect(path) database.row_factory = sqlite3.Row database.cursor().execute( - f'CREATE TABLE IF NOT EXISTS database_info (schema_version INT DEFAULT {constants.CACHE_SQLITE_SCEMA_VERSION})') + f'CREATE TABLE IF NOT EXISTS database_info (schema_version INT DEFAULT {constants.CACHE_SQLITE_SCHEMA_VERSION})') schema_version = database.cursor().execute('SELECT schema_version FROM database_info').fetchone() if not schema_version: - database.cursor().execute(f'INSERT INTO database_info VALUES ({constants.CACHE_SQLITE_SCEMA_VERSION})') - elif schema_version['schema_version'] == constants.CACHE_SQLITE_SCEMA_VERSION: + database.cursor().execute(f'INSERT INTO database_info VALUES ({constants.CACHE_SQLITE_SCHEMA_VERSION})') + elif schema_version['schema_version'] == constants.CACHE_SQLITE_SCHEMA_VERSION: # All good, so pass and move on pass else: diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index 3b499adea..af3f7c0a0 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -76,7 +76,7 @@ MAC_BANNERS_PATH = os.path.join(CACHE_PATH, "mac_banners.cache") IDENTIFIERS_PATH = os.path.join(CACHE_PATH, "identifiers.cache") """Default location to record information about available identifiers""" -CACHE_SQLITE_SCEMA_VERSION = 1 +CACHE_SQLITE_SCHEMA_VERSION = 1 """Version for the sqlite3 cache schema""" BUG_URL = "https://github.com/volatilityfoundation/volatility3/issues" From 3e071b563d03d69cc06042eb05dfd2136cc49b2e Mon Sep 17 00:00:00 2001 From: Donghyun Kim Date: Sun, 21 Aug 2022 05:02:34 +0900 Subject: [PATCH 22/24] Fix: typo for symbol table --- volatility3/framework/automagic/symbol_cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/automagic/symbol_cache.py b/volatility3/framework/automagic/symbol_cache.py index ab19965c7..a24dc3fd0 100644 --- a/volatility3/framework/automagic/symbol_cache.py +++ b/volatility3/framework/automagic/symbol_cache.py @@ -196,7 +196,7 @@ class SqliteCache(CacheManagerInterface): If multiple locations exist for an identifier, the last found is returned Args: - identifier: string that uniquely identifies a particular symbolt table + identifier: string that uniquely identifies a particular symbol table operating_system: optional string to restrict identifiers to just those for a particular operating system Returns: From ed8d240a7cf1b7d3b39bc467af8ec67d4c8ac190 Mon Sep 17 00:00:00 2001 From: Paul Kermann Date: Wed, 24 Aug 2022 10:24:14 +0300 Subject: [PATCH 23/24] return given layer by base --- volatility3/framework/automagic/windows.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/volatility3/framework/automagic/windows.py b/volatility3/framework/automagic/windows.py index f5dd720d6..08a5027d1 100644 --- a/volatility3/framework/automagic/windows.py +++ b/volatility3/framework/automagic/windows.py @@ -214,6 +214,9 @@ class WindowsIntelStacker(interfaces.automagic.StackerLayerInterface): context.config[interfaces.configuration.path_join( config_path, "page_map_offset")] = base_layer.metadata['page_map_offset'] layer = layer_type(context, config_path = config_path, name = new_layer_name, metadata = {'os': 'Windows'}) + page_map_offset = context.config[interfaces.configuration.path_join(config_path, "page_map_offset")] + vollog.debug(f"DTB was given to as by base layer: {hex(page_map_offset)}") + return layer # Self Referential finder for description, tests, sections in cls.test_sets: From 253c4b5bb1cc7411255277639a866f8b0c9f87ac Mon Sep 17 00:00:00 2001 From: Paul Kermann Date: Wed, 24 Aug 2022 10:26:04 +0300 Subject: [PATCH 24/24] typo --- volatility3/framework/automagic/windows.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/automagic/windows.py b/volatility3/framework/automagic/windows.py index 08a5027d1..aaef3e820 100644 --- a/volatility3/framework/automagic/windows.py +++ b/volatility3/framework/automagic/windows.py @@ -215,7 +215,7 @@ class WindowsIntelStacker(interfaces.automagic.StackerLayerInterface): config_path, "page_map_offset")] = base_layer.metadata['page_map_offset'] layer = layer_type(context, config_path = config_path, name = new_layer_name, metadata = {'os': 'Windows'}) page_map_offset = context.config[interfaces.configuration.path_join(config_path, "page_map_offset")] - vollog.debug(f"DTB was given to as by base layer: {hex(page_map_offset)}") + vollog.debug(f"DTB was given to us by base layer: {hex(page_map_offset)}") return layer # Self Referential finder