mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-28 04:24:53 +02:00
Merge pull request #1572 from hsarkey/hsarkey/wow64-dlllist
Windows: Allow windows.dlllist to report back DLLs from wow64 processes
This commit is contained in:
@@ -24,6 +24,7 @@ from volatility3.framework.objects import utility
|
||||
from volatility3.framework.renderers import conversion
|
||||
from volatility3.framework.symbols import generic
|
||||
from volatility3.framework.symbols.windows.extensions import pool
|
||||
from volatility3.framework.symbols import windows
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
@@ -781,15 +782,90 @@ class EPROCESS(generic.GenericIntelProcess, pool.ExecutiveObject):
|
||||
)
|
||||
return peb
|
||||
|
||||
def get_peb32(self) -> Optional[interfaces.objects.ObjectInterface]:
|
||||
"""Constructs a PEB32 object"""
|
||||
if constants.BANG not in self.vol.type_name:
|
||||
raise ValueError(
|
||||
f"Invalid symbol table name syntax (no {constants.BANG} found)"
|
||||
)
|
||||
|
||||
# add_process_layer can raise InvalidAddressException.
|
||||
# if that happens, we let the exception propagate upwards
|
||||
proc_layer_name = self.add_process_layer()
|
||||
proc_layer = self._context.layers[proc_layer_name]
|
||||
|
||||
# Determine if process is running under WOW64.
|
||||
if self.get_is_wow64():
|
||||
proc = self.get_wow_64_process()
|
||||
else:
|
||||
return None
|
||||
# Confirm WoW64Process points to a valid process address
|
||||
if not proc_layer.is_valid(proc):
|
||||
raise exceptions.InvalidAddressException(
|
||||
proc_layer_name, proc, f"Invalid Wow64Process address at {self.Peb:0x}"
|
||||
)
|
||||
|
||||
# Leverage the context of existing symbol table to help configure
|
||||
# a new symbol table for 32-bit types
|
||||
sym_table = self.get_symbol_table_name()
|
||||
config_path = self._context.symbol_space[sym_table].config_path
|
||||
|
||||
# Load the 32-bit types into a new symbol space
|
||||
# We use the WindowsKernelIntermedSymbols class to make
|
||||
# sure we get all the object helpers. For example, traversing
|
||||
# linked-lists.
|
||||
self._32bit_table_name = windows.WindowsKernelIntermedSymbols.create(
|
||||
self._context, config_path, "windows", "wow64"
|
||||
)
|
||||
|
||||
# windows 10
|
||||
if self._context.symbol_space.has_type(
|
||||
sym_table + constants.BANG + "_EWOW64PROCESS"
|
||||
):
|
||||
offset = proc.Peb
|
||||
|
||||
# vista sp0-sp1 and 2003 sp1-sp2
|
||||
elif self._context.symbol_space.has_type(
|
||||
sym_table + constants.BANG + "_WOW64_PROCESS"
|
||||
):
|
||||
offset = proc.Wow64
|
||||
|
||||
else:
|
||||
offset = proc
|
||||
|
||||
peb32 = self._context.object(
|
||||
f"{self._32bit_table_name}{constants.BANG}_PEB32",
|
||||
layer_name=proc_layer_name,
|
||||
offset=offset,
|
||||
)
|
||||
return peb32
|
||||
|
||||
def set_types(self, peb) -> str:
|
||||
ldr_data = self._context.symbol_space.get_type(
|
||||
self._32bit_table_name + constants.BANG + "_PEB_LDR_DATA"
|
||||
)
|
||||
peb.Ldr = peb.Ldr.cast("pointer", subtype=ldr_data)
|
||||
sym_table = self._32bit_table_name
|
||||
return sym_table
|
||||
|
||||
def load_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]:
|
||||
"""Generator for DLLs in the order that they were loaded."""
|
||||
|
||||
try:
|
||||
peb = self.get_peb()
|
||||
yield from peb.Ldr.InLoadOrderModuleList.to_list(
|
||||
f"{self.get_symbol_table_name()}{constants.BANG}_LDR_DATA_TABLE_ENTRY",
|
||||
"InLoadOrderLinks",
|
||||
)
|
||||
pebs = [
|
||||
self.get_peb(),
|
||||
self.get_peb32(),
|
||||
]
|
||||
for peb in pebs:
|
||||
if peb:
|
||||
sym_table = self.get_symbol_table_name()
|
||||
if peb.Ldr.vol.type_name.split(constants.BANG)[-1] == (
|
||||
"unsigned long"
|
||||
):
|
||||
sym_table = self.set_types(peb)
|
||||
yield from peb.Ldr.InLoadOrderModuleList.to_list(
|
||||
f"{sym_table}{constants.BANG}" + "_LDR_DATA_TABLE_ENTRY",
|
||||
"InLoadOrderLinks",
|
||||
)
|
||||
except exceptions.InvalidAddressException:
|
||||
return None
|
||||
|
||||
@@ -797,23 +873,42 @@ class EPROCESS(generic.GenericIntelProcess, pool.ExecutiveObject):
|
||||
"""Generator for DLLs in the order that they were initialized"""
|
||||
|
||||
try:
|
||||
peb = self.get_peb()
|
||||
yield from peb.Ldr.InInitializationOrderModuleList.to_list(
|
||||
f"{self.get_symbol_table_name()}{constants.BANG}_LDR_DATA_TABLE_ENTRY",
|
||||
"InInitializationOrderLinks",
|
||||
)
|
||||
pebs = [
|
||||
self.get_peb(),
|
||||
self.get_peb32(),
|
||||
]
|
||||
for peb in pebs:
|
||||
if peb:
|
||||
sym_table = self.get_symbol_table_name()
|
||||
if peb.Ldr.vol.type_name.split(constants.BANG)[-1] == (
|
||||
"unsigned long"
|
||||
):
|
||||
sym_table = self.set_types(peb)
|
||||
yield from peb.Ldr.InInitializationOrderModuleList.to_list(
|
||||
f"{sym_table}{constants.BANG}" + "_LDR_DATA_TABLE_ENTRY",
|
||||
"InInitializationOrderLinks",
|
||||
)
|
||||
except exceptions.InvalidAddressException:
|
||||
return None
|
||||
|
||||
def mem_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]:
|
||||
"""Generator for DLLs in the order that they appear in memory"""
|
||||
|
||||
try:
|
||||
peb = self.get_peb()
|
||||
yield from peb.Ldr.InMemoryOrderModuleList.to_list(
|
||||
f"{self.get_symbol_table_name()}{constants.BANG}_LDR_DATA_TABLE_ENTRY",
|
||||
"InMemoryOrderLinks",
|
||||
)
|
||||
pebs = [
|
||||
self.get_peb(),
|
||||
self.get_peb32(),
|
||||
]
|
||||
for peb in pebs:
|
||||
if peb:
|
||||
sym_table = self.get_symbol_table_name()
|
||||
if peb.Ldr.vol.type_name.split(constants.BANG)[-1] == (
|
||||
"unsigned long"
|
||||
):
|
||||
sym_table = self.set_types(peb)
|
||||
yield from peb.Ldr.InMemoryOrderModuleList.to_list(
|
||||
f"{sym_table}{constants.BANG}" + "_LDR_DATA_TABLE_ENTRY",
|
||||
"InMemoryOrderLinks",
|
||||
)
|
||||
except exceptions.InvalidAddressException:
|
||||
return None
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user