Package rekall :: Package plugins :: Package windows :: Module procinfo
[frames] | no frames]

Source Code for Module rekall.plugins.windows.procinfo

  1  # Rekall Memory Forensics 
  2  # Copyright (C) 2012 Michael Cohen 
  3  # Copyright 2013 Google Inc. All Rights Reserved. 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or (at 
  8  # your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, but 
 11  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 13  # General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with this program; if not, write to the Free Software 
 17  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 18  # 
 19   
 20  """This module print details information about PE files and processes. 
 21   
 22  Output is similar to objdump or pefile. 
 23  """ 
 24   
 25  __author__ = "Michael Cohen <scudette@gmail.com>" 
 26   
 27  from rekall import plugin 
 28  from rekall import testlib 
 29   
 30  from rekall.plugins.overlays.windows import pe_vtypes 
 31  from rekall.plugins.windows import common 
 32   
 33   
34 -class PEInfo(plugin.TypedProfileCommand, plugin.Command):
35 """Print information about a PE binary.""" 36 37 __name = "peinfo" 38 39 __args = [ 40 dict(name="image_base", type="SymbolAddress", positional=True, 41 help="The base of the image."), 42 43 dict(name="executable", positional=True, required=False, 44 help="If provided we create an address space " 45 "from this file."), 46 47 dict(name="address_space", default=None, 48 help="The address space to use.") 49 ] 50
51 - def __init__(self, *args, **kwargs):
52 """Dump a PE binary from memory. 53 54 Status is shown for each exported function: 55 56 - M: The function is mapped into memory. 57 58 Args: 59 image_base: The address of the image base (dos header). Can be a 60 module name. 61 62 address_space: The address space which contains the PE image. Can be 63 specified as "K" or "P". 64 65 filename: If provided we create an address space from this file. 66 """ 67 super(PEInfo, self).__init__(*args, **kwargs) 68 if (self.plugin_args.executable is None and 69 self.plugin_args.address_space is None): 70 # Resolve the correct address space. This allows the address space 71 # to be specified from the command line (e.g. "P") 72 load_as = self.session.plugins.load_as(session=self.session) 73 self.plugin_args.address_space = load_as.ResolveAddressSpace( 74 self.plugin_args.address_space) 75 76 if self.plugin_args.image_base is None: 77 self.plugin_args.image_base = self.session.GetParameter( 78 "default_image_base", 0) 79 80 self.pe_helper = pe_vtypes.PE( 81 address_space=self.plugin_args.address_space, session=self.session, 82 filename=self.plugin_args.executable, 83 image_base=self.plugin_args.image_base) 84 85 self.disassembler = self.session.plugins.dis( 86 address_space=self.pe_helper.vm, 87 session=self.session, length=4)
88
89 - def render(self, renderer):
90 """Print information about a PE file from memory.""" 91 # Get our helper object to parse the PE file. 92 renderer.table_header([('Attribute', 'attribute', '<30'), 93 ('Value', 'value', '60')]) 94 95 for field in ["Machine", "TimeDateStamp", "Characteristics"]: 96 renderer.table_row( 97 field, 98 getattr(self.pe_helper.nt_header.FileHeader, field)) 99 100 renderer.table_row("GUID/Age", self.pe_helper.RSDS.GUID_AGE) 101 renderer.table_row("PDB", self.pe_helper.RSDS.Filename) 102 103 for field in ["MajorOperatingSystemVersion", 104 "MinorOperatingSystemVersion", 105 "MajorImageVersion", 106 "MinorImageVersion", 107 "MajorSubsystemVersion", 108 "MinorSubsystemVersion"]: 109 renderer.table_row( 110 field, 111 getattr(self.pe_helper.nt_header.OptionalHeader, field)) 112 113 renderer.format( 114 "\nSections (Relative to {0:addrpad}):\n", 115 self.pe_helper.image_base) 116 117 renderer.table_header([('Perm', 'perm', '4'), 118 ('Name', 'name', '<8'), 119 ('Raw Off', 'raw', '[addrpad]'), 120 ('VMA', 'vma', '[addrpad]'), 121 ('Size', 'size', '[addrpad]')]) 122 123 for section in self.pe_helper.nt_header.Sections: 124 renderer.table_row(section.execution_flags, section.Name, 125 section.PointerToRawData, 126 section.VirtualAddress, 127 section.SizeOfRawData) 128 129 renderer.format("\nData Directories:\n") 130 renderer.table_header([('', 'name', '<40'), 131 ('VMA', 'vma', '[addrpad]'), 132 ('Size', 'size', '[addrpad]')]) 133 134 for d in self.pe_helper.nt_header.OptionalHeader.DataDirectory: 135 renderer.table_row(d.obj_name, d.VirtualAddress, d.Size) 136 137 138 # Export/Import directory only if verbosity is higher than 1. 139 if self.plugin_args.verbosity >= 1: 140 renderer.format("\nImport Directory (Original):\n") 141 renderer.table_header([('Name', 'name', '<50'), 142 ('Mapped Function', 'function', '60'), 143 ('Ord', 'ord', '5')]) 144 145 resolver = self.session.address_resolver 146 # Merge the results from both the Import table and the 147 # IAT. Sometimes the original Import Table is no longer mapped into 148 # memory (since its usually only used by the loader in order to 149 # build the IAT). In this case we can show something sensible using 150 # the address resolver. 151 for (dll, name, ordinal), (_, func, _) in zip( 152 self.pe_helper.ImportDirectory(), 153 self.pe_helper.IAT()): 154 renderer.table_row( 155 u"%s!%s" % (dll, name or ""), 156 resolver.format_address(func.v()), 157 ordinal) 158 159 if self.plugin_args.verbosity >= 2: 160 renderer.format("\nImport Address Table:\n") 161 renderer.table_header( 162 [('Name', 'name', '<20'), 163 ('Address', 'address', '[addrpad]'), 164 ('Disassembly', 'disassembly', '30')]) 165 166 for name, function, ordinal in self.pe_helper.IAT(): 167 disassembly = [] 168 169 for x in self.disassembler.disassemble(function): 170 disassembly.append(x[-1].strip()) 171 172 renderer.table_row(name, function, "\n".join(disassembly)) 173 174 renderer.format("\nExport Directory:\n") 175 renderer.table_header([('Entry', 'entry', '[addrpad]'), 176 ('Stat', 'status', '4'), 177 ('Ord', 'ord', '5'), 178 ('Name', 'name', '')]) 179 180 resolver = self.session.address_resolver 181 182 for _ in self.pe_helper.ExportDirectory(): 183 dll, function, name, ordinal = _ 184 status = 'M' if function.dereference() else "-" 185 186 # Resolve the exported function through the symbol resolver. 187 symbol_name = resolver.format_address(function) 188 if symbol_name: 189 symbol_name = u"%s!%s (%s)" % ( 190 dll, name or "", ", ".join(symbol_name)) 191 else: 192 symbol_name = u"%s!%s" % (dll, name or "") 193 194 renderer.table_row( 195 function, 196 status, 197 ordinal, 198 symbol_name) 199 200 renderer.format("Version Information:\n") 201 renderer.table_header([('key', 'key', '<20'), 202 ('value', 'value', '')]) 203 204 for k, v in self.pe_helper.VersionInformation(): 205 renderer.table_row(k, v)
206 207
208 -class TestPEInfo(testlib.SimpleTestCase):
209 PARAMETERS = dict( 210 commandline="peinfo nt" 211 )
212 213 214
215 -class ProcInfo(common.WinProcessFilter):
216 """Dump detailed information about a running process.""" 217 218 __name = "procinfo" 219
220 - def render(self, renderer):
221 for task in self.filter_processes(): 222 renderer.section() 223 renderer.format("Pid: {0} {1}\n", 224 task.UniqueProcessId, task.ImageFileName) 225 226 task_address_space = task.get_process_address_space() 227 if not task_address_space: 228 renderer.format("Peb Not mapped.\n") 229 continue 230 231 renderer.format("\nProcess Environment\n") 232 # The environment is just a sentinel terminated array of strings. 233 for line in task.Peb.ProcessParameters.Environment: 234 renderer.format(" {0}\n", line) 235 236 renderer.format("\nPE Infomation\n") 237 cc = self.session.plugins.cc() 238 with cc: 239 cc.SwitchProcessContext(task) 240 241 # Parse the PE file of the main process's executable. 242 pe = PEInfo(session=self.session, 243 image_base=task.Peb.ImageBaseAddress) 244 245 pe.render(renderer)
246 247
248 -class TestProcInfo(testlib.SimpleTestCase):
249 PARAMETERS = dict( 250 commandline="procinfo %(pids)s" 251 )
252