From 306b7ff42bde54830be3e1c34880d981b9c35743 Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Fri, 6 Jun 2025 23:55:12 +0300 Subject: [PATCH 1/5] use maxsize argument --- volatility3/framework/plugins/regexscan.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/volatility3/framework/plugins/regexscan.py b/volatility3/framework/plugins/regexscan.py index 7df89f841..c5ec97fd6 100644 --- a/volatility3/framework/plugins/regexscan.py +++ b/volatility3/framework/plugins/regexscan.py @@ -49,24 +49,24 @@ class RegExScan(plugins.PluginInterface): def _generator(self, regex_pattern): regex_pattern = bytes(regex_pattern, "UTF-8") vollog.debug(f"RegEx Pattern: {regex_pattern}") - + maxsize = self.config.get("maxsize", self.MAXSIZE_DEFAULT) layer = self.context.layers[self.config["primary"]] for offset in layer.scan( context=self.context, scanner=scanners.RegExScanner(regex_pattern) ): - result_data = layer.read(offset, self.MAXSIZE_DEFAULT, pad=True) + result_data = layer.read(offset, maxsize, pad=True) # reapply the regex in order to extract just the match regex_result = re.match(regex_pattern, result_data) if regex_result: - # the match is within the results_data (e.g. it fits within MAXSIZE_DEFAULT) + # the match is within the results_data (e.g. it fits within maxsize) # extract just the match itself regex_match = regex_result.group(0) text_result = str(regex_match, encoding="UTF-8", errors="replace") bytes_result = regex_match else: - # the match is not with the results_data (e.g. it doesn't fit within MAXSIZE_DEFAULT) + # the match is not with the results_data (e.g. it doesn't fit within maxsize) text_result = str(result_data, encoding="UTF-8", errors="replace") bytes_result = result_data From f01310c238d7b7d4f47814d4c482454f7b928dd0 Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Sat, 7 Jun 2025 11:39:56 +0300 Subject: [PATCH 2/5] use search instead of match --- volatility3/framework/plugins/regexscan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/volatility3/framework/plugins/regexscan.py b/volatility3/framework/plugins/regexscan.py index c5ec97fd6..4df00a583 100644 --- a/volatility3/framework/plugins/regexscan.py +++ b/volatility3/framework/plugins/regexscan.py @@ -48,6 +48,7 @@ class RegExScan(plugins.PluginInterface): def _generator(self, regex_pattern): regex_pattern = bytes(regex_pattern, "UTF-8") + compiled_pattern = re.compile(regex_pattern) vollog.debug(f"RegEx Pattern: {regex_pattern}") maxsize = self.config.get("maxsize", self.MAXSIZE_DEFAULT) layer = self.context.layers[self.config["primary"]] @@ -57,7 +58,7 @@ class RegExScan(plugins.PluginInterface): result_data = layer.read(offset, maxsize, pad=True) # reapply the regex in order to extract just the match - regex_result = re.match(regex_pattern, result_data) + regex_result = compiled_pattern.search(result_data) if regex_result: # the match is within the results_data (e.g. it fits within maxsize) From eba4e4b50c8842e286410bcd62a0930b0c9b9602 Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Sat, 7 Jun 2025 11:50:07 +0300 Subject: [PATCH 3/5] generator overhead --- volatility3/framework/plugins/regexscan.py | 38 ++++++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/volatility3/framework/plugins/regexscan.py b/volatility3/framework/plugins/regexscan.py index 4df00a583..e95986899 100644 --- a/volatility3/framework/plugins/regexscan.py +++ b/volatility3/framework/plugins/regexscan.py @@ -46,14 +46,12 @@ class RegExScan(plugins.PluginInterface): ), ] - def _generator(self, regex_pattern): - regex_pattern = bytes(regex_pattern, "UTF-8") - compiled_pattern = re.compile(regex_pattern) - vollog.debug(f"RegEx Pattern: {regex_pattern}") - maxsize = self.config.get("maxsize", self.MAXSIZE_DEFAULT) + def _generator(self, compiled_pattern, raw_pattern, maxsize): + vollog.debug(f"RegEx Pattern: {raw_pattern}") layer = self.context.layers[self.config["primary"]] + for offset in layer.scan( - context=self.context, scanner=scanners.RegExScanner(regex_pattern) + context=self.context, scanner=scanners.RegExScanner(raw_pattern) ): result_data = layer.read(offset, maxsize, pad=True) @@ -74,11 +72,37 @@ class RegExScan(plugins.PluginInterface): yield 0, (format_hints.Hex(offset), text_result, bytes_result) def run(self): + pattern = self.config.get("pattern") + + # Handle pattern encoding robustly + if isinstance(pattern, str): + try: + raw_pattern = pattern.encode("utf-8") + except UnicodeEncodeError: + raw_pattern = pattern.encode("latin1", errors="replace") + else: + raw_pattern = pattern + + try: + compiled_pattern = re.compile(raw_pattern) + except re.error as e: + vollog.error(f"Invalid regex pattern: {e}") + return renderers.TreeGrid( + [ + ("Offset", format_hints.Hex), + ("Text", str), + ("Hex", bytes), + ], + [], + ) + + maxsize = self.config.get("maxsize", self.MAXSIZE_DEFAULT) + return renderers.TreeGrid( [ ("Offset", format_hints.Hex), ("Text", str), ("Hex", bytes), ], - self._generator(self.config.get("pattern")), + self._generator(compiled_pattern, raw_pattern, maxsize), ) From 742b0634b931855a74f39fdb3e9ebbe8142ee7db Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Wed, 11 Jun 2025 19:30:29 +0300 Subject: [PATCH 4/5] readjust _run to contain less code & removal of redundant code --- volatility3/framework/plugins/regexscan.py | 43 ++++++++-------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/volatility3/framework/plugins/regexscan.py b/volatility3/framework/plugins/regexscan.py index e95986899..1f199658e 100644 --- a/volatility3/framework/plugins/regexscan.py +++ b/volatility3/framework/plugins/regexscan.py @@ -46,12 +46,21 @@ class RegExScan(plugins.PluginInterface): ), ] - def _generator(self, compiled_pattern, raw_pattern, maxsize): - vollog.debug(f"RegEx Pattern: {raw_pattern}") - layer = self.context.layers[self.config["primary"]] + def _generator(self, layer, pattern, maxsize): + vollog.debug(f"RegEx Pattern: {pattern}") + + # Convert string pattern to bytes for RegExScanner + pattern_bytes = pattern.encode("utf-8") + + # Compile the pattern here to ensure consistency + try: + compiled_pattern = re.compile(pattern_bytes) + except re.error as e: + vollog.error(f"Invalid regex pattern: {e}") + raise ValueError(f"Invalid regex pattern: {e}") for offset in layer.scan( - context=self.context, scanner=scanners.RegExScanner(raw_pattern) + context=self.context, scanner=scanners.RegExScanner(pattern_bytes) ): result_data = layer.read(offset, maxsize, pad=True) @@ -73,30 +82,8 @@ class RegExScan(plugins.PluginInterface): def run(self): pattern = self.config.get("pattern") - - # Handle pattern encoding robustly - if isinstance(pattern, str): - try: - raw_pattern = pattern.encode("utf-8") - except UnicodeEncodeError: - raw_pattern = pattern.encode("latin1", errors="replace") - else: - raw_pattern = pattern - - try: - compiled_pattern = re.compile(raw_pattern) - except re.error as e: - vollog.error(f"Invalid regex pattern: {e}") - return renderers.TreeGrid( - [ - ("Offset", format_hints.Hex), - ("Text", str), - ("Hex", bytes), - ], - [], - ) - maxsize = self.config.get("maxsize", self.MAXSIZE_DEFAULT) + layer = self.context.layers[self.config["primary"]] return renderers.TreeGrid( [ @@ -104,5 +91,5 @@ class RegExScan(plugins.PluginInterface): ("Text", str), ("Hex", bytes), ], - self._generator(compiled_pattern, raw_pattern, maxsize), + self._generator(layer, pattern, maxsize), ) From c270cf4b15123662c2ca2d0af48bc5144fafd78e Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Thu, 12 Jun 2025 20:09:28 +0300 Subject: [PATCH 5/5] RegexScan: parameterize _generator --- volatility3/framework/plugins/regexscan.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/volatility3/framework/plugins/regexscan.py b/volatility3/framework/plugins/regexscan.py index 1f199658e..2c188ba4c 100644 --- a/volatility3/framework/plugins/regexscan.py +++ b/volatility3/framework/plugins/regexscan.py @@ -46,7 +46,8 @@ class RegExScan(plugins.PluginInterface): ), ] - def _generator(self, layer, pattern, maxsize): + def _generator(self, context, layer_name, pattern, maxsize): + layer = self.context.layers[layer_name] vollog.debug(f"RegEx Pattern: {pattern}") # Convert string pattern to bytes for RegExScanner @@ -60,7 +61,7 @@ class RegExScan(plugins.PluginInterface): raise ValueError(f"Invalid regex pattern: {e}") for offset in layer.scan( - context=self.context, scanner=scanners.RegExScanner(pattern_bytes) + context=context, scanner=scanners.RegExScanner(pattern_bytes) ): result_data = layer.read(offset, maxsize, pad=True) @@ -83,7 +84,8 @@ class RegExScan(plugins.PluginInterface): def run(self): pattern = self.config.get("pattern") maxsize = self.config.get("maxsize", self.MAXSIZE_DEFAULT) - layer = self.context.layers[self.config["primary"]] + layer_name = self.config["primary"] + context = self.context return renderers.TreeGrid( [ @@ -91,5 +93,5 @@ class RegExScan(plugins.PluginInterface): ("Text", str), ("Hex", bytes), ], - self._generator(layer, pattern, maxsize), + self._generator(context, layer_name, pattern, maxsize), )