Skip to content

Commit 1500d2e

Browse files
authored
Merge pull request #1314 from gcmoreira/linux_add_hlist_head_object_extension_fix_1313
Linux adds hlist_head object extension
2 parents 65daab6 + db8667f commit 1500d2e

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

volatility3/framework/contexts/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def object(
245245
"""
246246
if constants.BANG not in object_type:
247247
object_type = self.symbol_table_name + constants.BANG + object_type
248-
else:
248+
elif not object_type.startswith(self.symbol_table_name + constants.BANG):
249249
raise ValueError(
250250
"Cannot reference another module when constructing an object"
251251
)

volatility3/framework/symbols/linux/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def __init__(self, *args, **kwargs) -> None:
2222
# Set-up Linux specific types
2323
self.set_type_class("file", extensions.struct_file)
2424
self.set_type_class("list_head", extensions.list_head)
25+
self.set_type_class("hlist_head", extensions.hlist_head)
2526
self.set_type_class("mm_struct", extensions.mm_struct)
2627
self.set_type_class("super_block", extensions.super_block)
2728
self.set_type_class("task_struct", extensions.task_struct)

volatility3/framework/symbols/linux/extensions/__init__.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ def get_subdirs(self) -> interfaces.objects.ObjectInterface:
887887
if self.has_member("d_sib") and self.has_member("d_children"):
888888
# kernels >= 6.8
889889
walk_member = "d_sib"
890-
list_head_member = self.d_children.first
890+
list_head_member = self.d_children
891891
elif self.has_member("d_child") and self.has_member("d_subdirs"):
892892
# 2.5.0 <= kernels < 6.8
893893
walk_member = "d_child"
@@ -1004,6 +1004,40 @@ def __iter__(self) -> Iterator[interfaces.objects.ObjectInterface]:
10041004
return self.to_list(self.vol.parent.vol.type_name, self.vol.member_name)
10051005

10061006

1007+
class hlist_head(objects.StructType, collections.abc.Iterable):
1008+
def to_list(
1009+
self,
1010+
symbol_type: str,
1011+
member: str,
1012+
) -> Iterator[interfaces.objects.ObjectInterface]:
1013+
"""Returns an iterator of the entries in the list.
1014+
1015+
This is a doubly linked list; however, it is not circular, so the 'forward' field
1016+
doesn't make sense. Also, the sentinel concept doesn't make sense here either;
1017+
unlike list_head, the head and nodes each have their own distinct types. A list_head
1018+
cannot be a node by itself.
1019+
- The 'pprev' of the first 'hlist_node' points to the 'hlist_head', not to the last node.
1020+
- The last element 'next' member is NULL
1021+
1022+
Args:
1023+
symbol_type: Type of the list elements
1024+
member: Name of the list_head member in the list elements
1025+
1026+
Yields:
1027+
Objects of the type specified via the "symbol_type" argument.
1028+
1029+
"""
1030+
vmlinux = linux.LinuxUtilities.get_module_from_volobj_type(self._context, self)
1031+
1032+
current = self.first
1033+
while current and current.is_readable():
1034+
yield linux.LinuxUtilities.container_of(
1035+
current, symbol_type, member, vmlinux
1036+
)
1037+
1038+
current = current.next
1039+
1040+
10071041
class files_struct(objects.StructType):
10081042
def get_fds(self) -> interfaces.objects.ObjectInterface:
10091043
if self.has_member("fdt"):

0 commit comments

Comments
 (0)