[Vol-dev] [Patch] NewObject branch conversion of dlllist module to plugin

Mike Auty mike.auty at gmail.com
Sat Sep 26 17:54:11 CDT 2009


Hi everybody,

Sorry for the patch spam, but here's a new dlllist.  Absolutely no
changes required to the framework for this one (the patch just includes
clean-up of the old module code).  So, it looks like everything's going
according to plan!  5:)

Mike  5:)
-------------- next part --------------
>From 09832b06c751a06ccab5f7d4f850e7f18bcce279 Mon Sep 17 00:00:00 2001
From: Mike Auty <mike.auty at gmail.com>
Date: Sat, 26 Sep 2009 23:47:36 +0100
Subject: [PATCH] Add in dlllist plugin.

---
 Volatility/forensics/win32/tasks.py        |   55 ---------
 Volatility/memory_plugins/internal/dlls.py |   83 +++++++++++++
 Volatility/vmodules.py                     |  176 +---------------------------
 Volatility/volatility.py                   |    4 -
 4 files changed, 86 insertions(+), 232 deletions(-)
 create mode 100644 Volatility/memory_plugins/internal/dlls.py

diff --git a/Volatility/forensics/win32/tasks.py b/Volatility/forensics/win32/tasks.py
index 8a64778..d78150b 100644
--- a/Volatility/forensics/win32/tasks.py
+++ b/Volatility/forensics/win32/tasks.py
@@ -248,18 +248,6 @@ def create_addr_space(kaddr_space, directory_table_base):
 
     return process_address_space
 
-def process_command_line(process_address_space, types, peb_vaddr):
-    process_parameters = read_obj(process_address_space, types,
-                                  ['_PEB', 'ProcessParameters'], peb_vaddr)
-    
-    
-    if process_parameters is None:
-        return None
-    
-    return read_unicode_string(process_address_space, types,
-                               ['_RTL_USER_PROCESS_PARAMETERS', 'CommandLine'],
-                               process_parameters)    
-
 def peb_number_processors(process_address_space, types, peb_vaddr):
     return read_obj(process_address_space, types,
                                   ['_PEB', 'NumberOfProcessors'], peb_vaddr)
@@ -279,49 +267,6 @@ def module_base(process_address_space, types, module_vaddr):
     return read_obj(process_address_space, types,
                     ['_LDR_DATA_TABLE_ENTRY', 'DllBase'], module_vaddr)
 
-def process_ldrs(process_address_space, types, peb_vaddr):
-    ldr = read_obj(process_address_space, types,
-                   ['_PEB', 'Ldr'], peb_vaddr)
-
-    module_list = []
-
-    if ldr is None:
-        print "Unable to read ldr for peb 0x%x" % (peb_vaddr)
-        return module_list
-
-    first_module = read_obj(process_address_space, types,
-                            ['_PEB_LDR_DATA', 'InLoadOrderModuleList', 'Flink'],
-                            ldr)
-
-    if first_module is None:
-        print "Unable to read first module for ldr 0x%x" % (ldr)
-        return module_list        
-    
-    this_module = first_module
-
-    next_module = read_obj(process_address_space, types,
-                         ['_LDR_DATA_TABLE_ENTRY', 'InLoadOrderLinks', 'Flink'],
-                           this_module)
-
-    if next_module is None:
-        print "ModuleList Truncated, unable to read module at 0x%x\n" % (this_module)        
-        return module_list
-    
-    while next_module != first_module:
-        module_list.append(this_module)
-        if not process_address_space.is_valid_address(next_module):
-            print "ModuleList Truncated, unable to read module at 0x%x\n" % (next_module)
-            return module_list
-        _prev_module = this_module
-        this_module = next_module
-        next_module = read_obj(process_address_space, types,
-                         ['_LDR_DATA_TABLE_ENTRY', 'InLoadOrderLinks', 'Flink'],
-                         this_module)
-
-        
-    return module_list
-
-
 def find_csdversion(addr_space, types):
 
     CSDVersionDict = dict()
diff --git a/Volatility/memory_plugins/internal/dlls.py b/Volatility/memory_plugins/internal/dlls.py
new file mode 100644
index 0000000..277a6ca
--- /dev/null
+++ b/Volatility/memory_plugins/internal/dlls.py
@@ -0,0 +1,83 @@
+'''
+Created on 26 Sep 2009
+
+ at author: Mike Auty
+'''
+
+#pylint: disable-msg=C0111
+
+import forensics.commands
+import forensics.win32 as win32
+import forensics.object2 as object2
+import forensics.utils as utils
+
+class dlllist(forensics.commands.command):
+    """Print list of loaded dlls for each process"""
+
+    def __init__(self, args=None):
+        forensics.commands.command.__init__(self, args)
+        self.profile = None
+
+    def parser(self):
+        """Sets up the parser before execution"""
+        forensics.commands.command.parser(self)
+
+        self.op.add_option('-o', '--offset',
+            help='EPROCESS Offset (in hex) in physical address space',
+            action='store', type='string', dest='offset')
+
+        self.op.add_option('-p', '--pid',
+            help='Get info for this Pid', default=None,
+            action='store', type='int', dest='pid')
+
+    def render_text(self, outfd, data):
+        first = True
+        for pid in data:
+            if not first:
+                outfd.write("*" * 72 + "\n")
+
+            task = data[pid]['task']
+            outfd.write("%s pid: %-6d\n" % (task.ImageFileName, pid))
+            first = False
+
+            if task.Peb:
+                outfd.write("Command line : %s\n" % (task.Peb.ProcessParameters.CommandLine))
+                outfd.write("%s\n" % task.Peb.CSDVersion)
+                outfd.write("\n")
+                modules = data[pid]['modules']
+                outfd.write("%-12s %-12s %s\n" % ('Base', 'Size', 'Path'))
+                for m in modules:
+                    outfd.write("0x%0.8x   0x%0.6x     %s\n" % (int(m.BaseAddress), int(m.SizeOfImage), m.FullDllName))
+            else:
+                outfd.write("Unable to read PEB for task.\n")
+
+    def calculate(self):
+        result = {}
+        self.profile = object2.Profile()
+
+        addr_space = utils.load_as(self.opts)
+        
+        if self.opts.offset:
+            try:
+                offset = int(self.opts.offset, 16)
+            except ValueError:
+                self.op.error("EPROCESS offset must be a hexadecimal number.")
+            
+            tasks = [object2.NewObject("_EPROCESS", offset, addr_space, profile=self.profile)]
+
+        else:
+            tasks = win32.tasks.pslist(addr_space, self.profile)
+        
+        for task in tasks:
+            if task.UniqueProcessId:
+                pid = int(task.UniqueProcessId)
+                if self.opts.pid and pid != self.opts.pid:
+                    continue
+                
+                result[pid] = {'task': task, 'modules': []}
+
+                if task.Peb.Ldr.InLoadOrderModuleList:
+                    for l in task.Peb.Ldr.InLoadOrderModuleList.list_of_type("_LDR_MODULE", "InLoadOrderModuleList"):
+                        result[pid]['modules'].append(l)
+
+        return result
\ No newline at end of file
diff --git a/Volatility/vmodules.py b/Volatility/vmodules.py
index 2082b73..b4f583f 100644
--- a/Volatility/vmodules.py
+++ b/Volatility/vmodules.py
@@ -36,9 +36,9 @@ from vutils import get_standard_parser, is_hiberfil, is_crash_dump, types, get_d
 from forensics.addrspace import FileAddressSpace
 from forensics.win32.hiber_addrspace import WindowsHiberFileSpace32
 from forensics.win32.crash_addrspace import WindowsCrashDumpSpace32
-from forensics.object import read_unicode_string, read_obj
-from forensics.win32.tasks import module_base, module_path, module_size, create_addr_space, process_addr_space, process_command_line, process_dtb, process_find_pid
-from forensics.win32.tasks import process_imagename, process_ldrs, process_list, process_peb, process_pid, process_handle_table, process_create_time, process_handle_count
+from forensics.object import read_obj
+from forensics.win32.tasks import create_addr_space, process_addr_space, process_dtb, process_find_pid
+from forensics.win32.tasks import process_imagename, process_list, process_peb, process_pid, process_handle_table, process_create_time, process_handle_count
 from forensics.win32.tasks import process_inherited_from, process_num_active_threads, process_vadroot
 from forensics.win32.handles import handle_entries, handle_process_id, handle_tables
 from forensics.win32.vad import vad_dump, vad_info, print_vad_dot_infix, print_vad_dot_prefix, print_vad_table, print_vad_tree, traverse_vad
@@ -125,176 +125,6 @@ def get_pslist(cmdname, argv):
                                                    create_time)
 
 ###################################
-#  dlllist - DLL list
-###################################
-def get_dlllist(cmdname, argv):
-    """
-    Function prints a list of dlls loaded in each process
-    """
-    op = get_standard_parser(cmdname)
-
-    op.add_option('-o', '--offset',
-               help='EPROCESS Offset (in hex) in physical address space',
-               action='store', type='string', dest='offset')
-    op.add_option('-p', '--pid',
-                  help='Get info for this Pid',
-                  action='store', type='int', dest='pid')
-
-    opts, _args = op.parse_args(argv)
-
-    filename = opts.filename
-
-    (addr_space, symtab, types) = load_and_identify_image(op, opts)
-
-    if not opts.offset is None:
- 
-        try:
-            offset = int(opts.offset, 16)
-        except:
-            op.error("EPROCESS offset must be a hexadecimal number.")
-        
-        try:
-            flat_address_space = FileAddressSpace(filename)
-        except:
-            op.error("Unable to open image file %s" % (filename))
-
-        directory_table_base = process_dtb(flat_address_space, types, offset)
-
-        process_address_space = create_addr_space(addr_space, directory_table_base)
-
-        process_id = process_pid(flat_address_space, types, offset)
-                            
-        if process_address_space is None:
-            print "Error obtaining address space for process [%d]" % (process_id)
-            return
-
-
-        image_file_name = process_imagename(flat_address_space, types, offset)
-
-        print "%s pid: %d" % (image_file_name, process_id)
-
-        peb = process_peb(flat_address_space, types, offset)
-
-        if not process_address_space.is_valid_address(peb):
-            print "Unable to read PEB for task."
-            return
-
-        command_line = process_command_line(process_address_space, types, peb)
-
-        if command_line is None:
-            command_line = "UNKNOWN"
-
-        print "Command line : %s" % (command_line)
-
-        print
-        
-        modules = process_ldrs(process_address_space, types, peb)
-
-        if len(modules) > 0:
-            print "%-12s %-12s %s" % ('Base', 'Size', 'Path')
-        
-        for module in modules:
-            if not process_address_space.is_valid_address(module):
-                return
-            path = module_path(process_address_space, types, module)
-            if path is None:
-                path = "%-10s  " % ('UNKNOWN')
-                
-            base = module_base(process_address_space, types, module)
-            if base is None:
-                base = "%-10s  " % ('UNKNOWN')
-            else:
-                base = "0x%-10x" % (base)
-                
-            size = module_size(process_address_space, types, module)
-            if size is None:
-                size = "%-10s  " % ('UNKNOWN')
-            else:
-                size = "0x%-10x" % (size)
-                
-            print "%s %s %s" % (base, size, path)            
-            
-        print
-
-    else:
-    
-        # get list of windows processes
-        all_tasks = process_list(addr_space, types, symtab)        
-
-        if not opts.pid == None:
-            all_tasks = process_find_pid(addr_space, types, symtab, all_tasks, opts.pid)
-            if len(all_tasks) == 0:
-                print "Error process [%d] not found" % opts.pid
-
-        star_line = '*'*72
-    
-        for task in all_tasks:
-
-            if not addr_space.is_valid_address(task):
-                continue
-            
-            if len(all_tasks) > 1:
-                print "%s" % star_line
-        
-            image_file_name = process_imagename(addr_space, types, task)
-
-            process_id = process_pid(addr_space, types, task)
-
-        
-            print "%s pid: %d" % (image_file_name, process_id)
-        
-            process_address_space = process_addr_space(addr_space, types, task, opts.filename)
-            if process_address_space is None:
-                print "Error obtaining address space for process [%d]" % (process_id)
-                continue
-                            
-            peb = process_peb(addr_space, types, task)
-
-            if not process_address_space.is_valid_address(peb):
-                print "Unable to read PEB for task."
-                continue
-
-            command_line = process_command_line(process_address_space, types, peb)
-
-            if command_line is None:
-                command_line = "UNKNOWN"
-
-            print "Command line : %s" % (command_line)
-      
-            print read_unicode_string(process_address_space, types,
-                ['_PEB', 'CSDVersion'], peb)
-
-            print
-        
-            modules = process_ldrs(process_address_space, types, peb)
-
-            if len(modules) > 0:
-                print "%-12s %-12s %s" % ('Base', 'Size', 'Path')
-        
-            for module in modules:
-                if not process_address_space.is_valid_address(module):
-                    continue
-                path = module_path(process_address_space, types, module)
-                if path is None:
-                    path = "%-10s  " % ('UNKNOWN')
-                
-                base = module_base(process_address_space, types, module)
-                if base is None:
-                    base = "%-10s  " % ('UNKNOWN')
-                else:
-                    base = "0x%-10x" % (base)
-                
-                size = module_size(process_address_space, types, module)
-                if size is None:
-                    size = "%-10s  " % ('UNKNOWN')
-                else:
-                    size = "0x%-10x" % (size)
-                
-                print "%s %s %s" % (base, size, path)            
-            
-            print
-
-###################################
 #  strings - identify pid(s) associated with a string
 ###################################
 def print_string(offset, pidlist, string):
diff --git a/Volatility/volatility.py b/Volatility/volatility.py
index baee253..ff50b51 100644
--- a/Volatility/volatility.py
+++ b/Volatility/volatility.py
@@ -44,10 +44,6 @@ modules = {
     VolatoolsModule('pslist',
                     'Print list of running processes',
                     get_pslist),
-    'dlllist':
-    VolatoolsModule('dlllist',
-                    'Print list of loaded dlls for each process',
-                    get_dlllist),
     'strings':
     VolatoolsModule('strings',
                     'Match physical offsets to virtual addresses (may take a while, VERY verbose)',
-- 
1.6.5.rc1



More information about the Vol-dev mailing list