Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make a generic DLL enumeration function that ensures the base address… #1607

Merged
merged 2 commits into from
Feb 8, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 49 additions & 54 deletions volatility3/framework/symbols/windows/extensions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -848,69 +848,64 @@ def set_types(self, peb) -> str:
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."""
def _walk_ldr_list(
self, list_member: str, link_member: str
) -> Iterable[interfaces.objects.ObjectInterface]:
"""
Walks LDR_DATA_TABLEs and enforces the entries at least have a valid base address
This function also breaks up exception handling as much as possible to ensure the
most data is returned as possible
"""
pebs = []

try:
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",
)
peb = self.get_peb()
if peb:
pebs.append(peb)
except exceptions.InvalidAddressException:
return None
vollog.debug(f"Process at {self.vol.offset:#x} has invalid PEB")

try:
peb32 = self.get_peb32()
if peb32:
pebs.append(peb32)
except exceptions.InvalidAddressException:
vollog.debug(f"Process at {self.vol.offset:#x} has invalid 32 bit PEB")

for peb in pebs:
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)

for ldr in peb.Ldr.member(list_member).to_list(
f"{sym_table}{constants.BANG}" + "_LDR_DATA_TABLE_ENTRY", link_member
):
try:
# Several samples in testing crashed from DLLs being returned
# where DllBase was on the next page and that page was not in memory
# Not being able to retrieve the base makes the entry pretty useless
# So we enforce here its presence
ldr.DllBase
yield ldr
except exceptions.InvalidAddressException:
continue

def load_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Generator for DLLs in the order that they were loaded."""

yield from self._walk_ldr_list("InLoadOrderModuleList", "InLoadOrderLinks")

def init_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Generator for DLLs in the order that they were initialized"""

try:
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
yield from self._walk_ldr_list(
"InInitializationOrderModuleList", "InInitializationOrderLinks"
)

def mem_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Generator for DLLs in the order that they appear in memory"""
try:
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

yield from self._walk_ldr_list("InMemoryOrderModuleList", "InMemoryOrderLinks")

def get_handle_count(self):
try:
Expand Down
Loading