Skip to content

Commit

Permalink
Convert vadinfo calls to classmethods.
Browse files Browse the repository at this point in the history
  • Loading branch information
ikelos committed Jun 16, 2018
1 parent c4c6d30 commit ecb9d5c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 25 deletions.
10 changes: 7 additions & 3 deletions volatility/plugins/windows/dlldump.py
Expand Up @@ -27,14 +27,16 @@ def _generator(self, procs):
"windows",
"pe")

vadinfo_plugin = vadinfo.VadInfo(self.context, self.config_path)
filter = lambda _: False
if self.config.get('address', None) is not None:
filter = lambda x: x.get_start() not in [self.config['address']]

for proc in procs:
process_name = utility.array_to_string(proc.ImageFileName)
# TODO: what kind of exceptions could this raise and what should we do?
proc_layer_name = proc.add_process_layer()

for vad in vadinfo_plugin.list_vads(proc):
for vad in vadinfo.VadInfo.list_vads(proc, filter = filter):

# this parameter is inherited from the VadInfo plugin. if a user specifies
# an address, then it bypasses the DLL identification heuristics
Expand All @@ -43,7 +45,9 @@ def _generator(self, procs):
# rather than relying on the PEB for DLLs, which can be swapped,
# it requires special handling on wow64 processes, and its
# unreliable from an integrity standpoint, let's use the VADs instead
protection_string = vad.get_protection(vadinfo_plugin.protect_values(),
protection_string = vad.get_protection(vadinfo.VadInfo.protect_values(self.context,
self.config['primary'],
self.config['nt_symbols']),
vadinfo.winnt_protections)

# DLLs are write copy...
Expand Down
7 changes: 5 additions & 2 deletions volatility/plugins/windows/vaddump.py
Expand Up @@ -19,7 +19,10 @@ def get_requirements(cls):

def _generator(self, procs):

plugin = vadinfo.VadInfo(self.context, self.config_path)
filter = lambda _: False
if self.config.get('address', None) is not None:
filter = lambda x: x.get_start() not in [self.config['address']]

chunk_size = 1024 * 1024 * 10

for proc in procs:
Expand All @@ -29,7 +32,7 @@ def _generator(self, procs):
proc_layer_name = proc.add_process_layer()
proc_layer = self.context.memory[proc_layer_name]

for vad in plugin.list_vads(proc):
for vad in vadinfo.VadInfo.list_vads(proc, filter = filter):
try:
filedata = interfaces_plugins.FileInterface(
"pid.{0}.vad.{1:#x}-{2:#x}.dmp".format(proc.UniqueProcessId,
Expand Down
46 changes: 26 additions & 20 deletions volatility/plugins/windows/vadinfo.py
@@ -1,8 +1,9 @@
import logging
import typing

import volatility.framework.interfaces.plugins as interfaces_plugins
import volatility.plugins.windows.pslist as pslist
from volatility.framework import renderers
from volatility.framework import renderers, interfaces
from volatility.framework.configuration import requirements
from volatility.framework.objects import utility
from volatility.framework.renderers import format_hints
Expand Down Expand Up @@ -44,46 +45,51 @@ def get_requirements(cls):
"a base address, not an address within the desired range.",
optional = True)]

def protect_values(self):
@classmethod
def protect_values(cls,
context: interfaces.context.ContextInterface,
virtual_layer: str,
nt_symbols: str) -> typing.Iterable[int]:
"""Look up the array of memory protection constants from the memory sample.
These don't change often, but if they do in the future, then finding them
# dynamically versus hard-coding here will ensure we parse them properly."""

if self._protect_values is None:
virtual_layer = self.config["primary"]
kvo = self.context.memory[virtual_layer].config["kernel_virtual_offset"]
ntkrnlmp = self.context.module(self.config["nt_symbols"], layer_name = virtual_layer, offset = kvo)
addr = ntkrnlmp.get_symbol("MmProtectToValue").address
values = ntkrnlmp.object(type_name = "array", offset = kvo + addr,
subtype = ntkrnlmp.get_type("int"),
count = 32)
self._protect_values = values

return self._protect_values

def list_vads(self, proc):
kvo = context.memory[virtual_layer].config["kernel_virtual_offset"]
ntkrnlmp = context.module(nt_symbols, layer_name = virtual_layer, offset = kvo)
addr = ntkrnlmp.get_symbol("MmProtectToValue").address
values = ntkrnlmp.object(type_name = "array", offset = kvo + addr,
subtype = ntkrnlmp.get_type("int"),
count = 32)
return values

filter = lambda _: False
if self.config.get('address', None) is not None:
filter = lambda x: x.get_start() not in [self.config['address']]
@classmethod
def list_vads(cls, proc: interfaces.objects.ObjectInterface,
filter: typing.Callable[[int], bool] = lambda _: False) -> \
typing.Generator[interfaces.objects.ObjectInterface, None, None]:

for vad in proc.get_vad_root().traverse():
if not filter(vad):
yield vad

def _generator(self, procs):

filter = lambda _: False
if self.config.get('address', None) is not None:
filter = lambda x: x.get_start() not in [self.config['address']]

for proc in procs:
process_name = utility.array_to_string(proc.ImageFileName)

for vad in self.list_vads(proc):
for vad in self.list_vads(proc, filter = filter):
yield (0, (proc.UniqueProcessId,
process_name,
format_hints.Hex(vad.vol.offset),
format_hints.Hex(vad.get_start()),
format_hints.Hex(vad.get_end()),
vad.get_tag(),
vad.get_protection(self.protect_values(), winnt_protections),
vad.get_protection(self.protect_values(self.context,
self.config['primary'],
self.config['nt_symbols']), winnt_protections),
vad.get_commit_charge(),
vad.get_private_memory(),
format_hints.Hex(vad.get_parent()),
Expand Down

0 comments on commit ecb9d5c

Please sign in to comment.