linux: page_cache plugin: Refactor to make _generator more readable

This commit is contained in:
Gustavo Moreira
2025-01-16 19:50:21 +11:00
parent c1497410b4
commit 5502a54198
@@ -6,7 +6,7 @@ import math
import logging
import datetime
from dataclasses import dataclass, astuple
from typing import List, Set, Type, Iterable
from typing import List, Set, Type, Iterable, Tuple
from volatility3.framework import renderers, interfaces, exceptions
from volatility3.framework.renderers import format_hints
@@ -489,6 +489,44 @@ class InodePages(plugins.PluginInterface):
except OSError as e:
vollog.error("Unable to write to file (%s): %s", filename, e)
def _generate_inode_fields(
self,
inode: interfaces.objects.ObjectInterface,
vmlinux_layer: interfaces.layers.TranslationLayerInterface,
) -> Iterable[Tuple[int, int, int, int, bool, str]]:
inode_size = inode.i_size
try:
for page_obj in inode.get_pages():
if page_obj.mapping != inode.i_mapping:
vollog.warning(
f"Cached page at {page_obj.vol.offset:#x} has a mismatched address space with the inode. Skipping page"
)
continue
page_vaddr = page_obj.vol.offset
page_paddr = page_obj.to_paddr()
page_mapping_addr = page_obj.mapping
page_index = int(page_obj.index)
page_file_offset = page_index * vmlinux_layer.page_size
dump_safe = (
page_file_offset < inode_size
and page_mapping_addr
and page_mapping_addr.is_readable()
)
page_flags_list = page_obj.get_flags_list()
page_flags = ",".join([x.replace("PG_", "") for x in page_flags_list])
fields = (
page_vaddr,
page_paddr,
page_mapping_addr,
page_index,
dump_safe,
page_flags,
)
yield 0, fields
except exceptions.LinuxPageCacheException:
vollog.warning(f"Page cache for inode at {inode.vol.offset:#x} is corrupt")
def _generator(self):
vmlinux_module_name = self.config["kernel"]
vmlinux = self.context.modules[vmlinux_module_name]
@@ -510,7 +548,6 @@ class InodePages(plugins.PluginInterface):
else:
vollog.error("Unable to find inode with path %s", self.config["find"])
return None
elif self.config["inode"]:
inode = vmlinux.object("inode", self.config["inode"], absolute=True)
else:
@@ -525,45 +562,7 @@ class InodePages(plugins.PluginInterface):
vollog.error("The inode is not a regular file")
return None
inode_size = inode.i_size
if not self.config["dump"]:
try:
for page_obj in inode.get_pages():
if page_obj.mapping != inode.i_mapping:
vollog.warning(
f"Cached page at {page_obj.vol.offset:#x} has a mismatched address space with the inode. Skipping page"
)
continue
page_vaddr = page_obj.vol.offset
page_paddr = page_obj.to_paddr()
page_mapping_addr = page_obj.mapping
page_index = int(page_obj.index)
page_file_offset = page_index * vmlinux_layer.page_size
dump_safe = (
page_file_offset < inode_size
and page_mapping_addr
and page_mapping_addr.is_readable()
)
page_flags_list = page_obj.get_flags_list()
page_flags = ",".join(
[x.replace("PG_", "") for x in page_flags_list]
)
fields = (
page_vaddr,
page_paddr,
page_mapping_addr,
page_index,
dump_safe,
page_flags,
)
yield 0, fields
except exceptions.LinuxPageCacheException:
vollog.warning(
f"Page cache for inode at {inode.vol.offset:#x} is corrupt"
)
else:
if self.config["dump"]:
open_method = self.open
inode_address = inode.vol.offset
filename = open_method.sanitize_filename(f"inode_0x{inode_address:x}.dmp")
@@ -571,6 +570,8 @@ class InodePages(plugins.PluginInterface):
self.write_inode_content_to_file(
inode, filename, open_method, vmlinux_layer
)
else:
yield from self._generate_inode_fields(inode, vmlinux_layer)
def run(self):
headers = [