def driver_dump(self): procs = list(tasks.pslist(self.addr_space)) mods = dict( (mod.DllBase.v(), mod) for mod in modules.lsmod(self.addr_space)) for mod in mods.values(): mod_base = mod.DllBase.v() mode_end = mod_base + mod.SizeOfImage space = tasks.find_space(self.addr_space, procs, mod_base) if space: pe_data = self.get_pe_content(space, mod_base) if self._config.LIST_SECTIONS: yield PESection(mod.BaseDllName, self.get_pe_sections(pe_data)) else: sections = self.process_section(None, self._config.SECTION, pe_data) for sec in sections: for engine in self.hash_engines: yield DriverObject(sec['data'], mod_base, mode_end, mod.FullDllName, engine, sec['section']) if self._config.TMP_FOLDER: dump_path = os.path.join( self._config.TMP_FOLDER, 'driver.{0:x}.{1}{2}.sys'.format( mod_base, mod.BaseDllName, sec['section'])) self.backup_file(dump_path, sec['data'])
def calculate(self): addr_space = utils.load_as(self._config) ## Get a sorted list of module addresses mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space)) mod_addrs = sorted(mods.keys()) ssdts = set() if addr_space.profile.metadata.get('memory_model', '32bit') == '32bit': # Gather up all SSDTs referenced by threads debug.info("[x86] Gathering all referenced SSDTs from KTHREADs...") for proc in tasks.pslist(addr_space): for thread in proc.ThreadListHead.list_of_type( "_ETHREAD", "ThreadListEntry"): ssdt_obj = thread.Tcb.ServiceTable.dereference_as( '_SERVICE_DESCRIPTOR_TABLE') ssdts.add(ssdt_obj) else: debug.info( "[x64] Gathering all referenced SSDTs from KeAddSystemServiceTable..." ) # The NT module always loads first ntos = list(modules.lsmod(addr_space))[0] func_rva = ntos.getprocaddress("KeAddSystemServiceTable") if func_rva == None: raise StopIteration("Cannot locate KeAddSystemServiceTable") KeAddSystemServiceTable = ntos.DllBase + func_rva for table_rva in find_tables(KeAddSystemServiceTable, addr_space): ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE", ntos.DllBase + table_rva, addr_space) ssdts.add(ssdt_obj) # Get a list of *unique* SSDT entries. Typically we see only two. tables = set() for ssdt_obj in ssdts: for i, desc in enumerate(ssdt_obj.Descriptors): # Apply some extra checks - KiServiceTable should reside in kernel memory and ServiceLimit # should be greater than 0 but not unbelievably high if not desc.is_valid( ) or desc.ServiceLimit <= 0 or desc.ServiceLimit >= 0xFFFF or desc.KiServiceTable <= 0x80000000: break else: tables.add( (i, desc.KiServiceTable.v(), desc.ServiceLimit.v())) debug.info("Finding appropriate address space for tables...") tables_with_vm = [] procs = list(tasks.pslist(addr_space)) for idx, table, n in tables: vm = tasks.find_space(addr_space, procs, table) if vm: tables_with_vm.append((idx, table, n, vm)) else: debug.debug("[SSDT not resident at 0x{0:08X}]\n".format(table)) for idx, table, n, vm in sorted(tables_with_vm, key=itemgetter(0)): yield idx, table, n, vm, mods, mod_addrs
def generator(self, data): for addr_space, procs, mod_base, mod_name in data: space = tasks.find_space(addr_space, procs, mod_base) if space == None: result = "Error: Cannot acquire AS" else: dump_file = "driver.{0:x}.sys".format(mod_base) result = self.dump_pe(space, mod_base, dump_file) yield (0, [Address(mod_base), str(mod_name), str(result)])
def calculate(self): addr_space = utils.load_as(self._config) ## Get a sorted list of module addresses mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space)) mod_addrs = sorted(mods.keys()) ssdts = set() if addr_space.profile.metadata.get("memory_model", "32bit") == "32bit": # Gather up all SSDTs referenced by threads print "[x86] Gathering all referenced SSDTs from KTHREADs..." for proc in tasks.pslist(addr_space): for thread in proc.ThreadListHead.list_of_type("_ETHREAD", "ThreadListEntry"): ssdt_obj = thread.Tcb.ServiceTable.dereference_as("_SERVICE_DESCRIPTOR_TABLE") ssdts.add(ssdt_obj) else: print "[x64] Gathering all referenced SSDTs from KeAddSystemServiceTable..." # The NT module always loads first ntos = list(modules.lsmod(addr_space))[0] func_rva = ntos.getprocaddress("KeAddSystemServiceTable") if func_rva == None: raise StopIteration("Cannot locate KeAddSystemServiceTable") KeAddSystemServiceTable = ntos.DllBase + func_rva for table_rva in find_tables(KeAddSystemServiceTable, addr_space): ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE", ntos.DllBase + table_rva, addr_space) ssdts.add(ssdt_obj) # Get a list of *unique* SSDT entries. Typically we see only two. tables = set() for ssdt_obj in ssdts: for i, desc in enumerate(ssdt_obj.Descriptors): # Apply some extra checks - KiServiceTable should reside in kernel memory and ServiceLimit # should be greater than 0 but not unbelievably high if ( desc.is_valid() and desc.ServiceLimit > 0 and desc.ServiceLimit < 0xFFFF and desc.KiServiceTable > 0x80000000 ): tables.add((i, desc.KiServiceTable.v(), desc.ServiceLimit.v())) print "Finding appropriate address space for tables..." tables_with_vm = [] procs = list(tasks.pslist(addr_space)) for idx, table, n in tables: vm = tasks.find_space(addr_space, procs, table) if vm: tables_with_vm.append((idx, table, n, vm)) else: debug.debug("[SSDT not resident at 0x{0:08X}]\n".format(table)) for idx, table, n, vm in sorted(tables_with_vm, key=itemgetter(0)): yield idx, table, n, vm, mods, mod_addrs
def calculate(self): if self._config.TAP_FILE is None or not os.path.exists( self._config.TAP_FILE): debug.error("Tap file not found") taplist = open(self._config.TAP_FILE, "r") taps = [] for line in taplist: line = line.split() (stack, cr3) = line[:-1], line[-1] try: stack = [int(s, 16) for s in stack] cr3 = int(cr3, 16) except ValueError: debug.error("Tap file format invalid.") taps.append((stack, cr3)) cr3s = set(t[1] for t in taps) cr3s.discard(0) # First do the userland ones addr_space = utils.load_as(self._config) procs = list(tasks.pslist(addr_space)) # CR3 => proc mapping proc_map = {} for proc in procs: dtb = proc.Pcb.DirectoryTableBase.v() if dtb in cr3s: proc_map[dtb] = proc for cr3, proc in proc_map.items(): print ">>> Working on {0}[{1}]".format(proc.ImageFileName, proc.UniqueProcessId) ps_ad = proc.get_process_address_space() proc_taps = [t for t in taps if t[1] == cr3] mods = list(proc.get_load_modules()) sorted_mods = sorted([(m.DllBase.v(), m.SizeOfImage.v(), str(m.BaseDllName)) for m in mods]) for v in self.resolve_taps(proc_taps, sorted_mods, lambda m: ps_ad): yield v + (proc.ImageFileName, ) # Now kernel mode taps print ">>> Working on kernel taps" kern_taps = [t for t in taps if t[1] == 0] sorted_mods = sorted([(mod.DllBase.v(), mod.SizeOfImage.v(), str(mod.BaseDllName)) for mod in modules.lsmod(addr_space)]) bases = [m[0] for m in sorted_mods] for v in self.resolve_taps( kern_taps, sorted_mods, lambda m: tasks.find_space(addr_space, procs, m)): yield v + ("Kernel", )
def __createModules(self): self.stateinfo = "Step {:<2d} / {:<2d}: Modules -- ModScan".format( self.__step, self.__steps) self.__scanned_modules = Set([ ldr_entry.obj_offset for ldr_entry in modscan.ModScan(self._config).calculate() ]) self.stateinfo = "Step {:<2d} / {:<2d}: Modules -- Modules calculate".format( self.__step, self.__steps) self.__loaded_modules = Set([ module.obj_vm.vtop(module.obj_offset) for module in modules.Modules(self._config).calculate() ]) self.__unlinked_or_hidden = self.__scanned_modules.difference( self.__loaded_modules) self.__modulesNode = Node("Modules", 0, None, self) self.__modulesNode.setDir() self.__modulesNode.__disown__() unknown = 0 address_space = utils.load_as(self._config, astype='physical') kernel_as = utils.load_as(self._config) procs = list(tasks.pslist(kernel_as)) modcount = 1 lmodcount = len(self.__scanned_modules) for offset in self.__scanned_modules: self.stateinfo = "Step {:<2d} / {:<2d}: Modules -- creating nodes ({:>6d} / {:<6d})".format( self.__step, self.__steps, modcount, lmodcount) modcount += 1 ldr_entry = obj.Object('_LDR_DATA_TABLE_ENTRY', vm=address_space, offset=offset, native_vm=kernel_as) if not ldr_entry.BaseDllName: unknown += 1 name = "Unknown" + str(unknown) else: name = str(ldr_entry.BaseDllName) unlinked_or_hidden = False if offset in self.__unlinked_or_hidden: unlinked_or_hidden = True aspace = tasks.find_space(kernel_as, procs, ldr_entry.DllBase.v()) n = ModuleNode(name, ldr_entry, self.__modulesNode, self, aspace, unlinked_or_hidden) n.__disown__() self.registerTree(self.root, self.__modulesNode) self.__step += 1
def render_text(self, outfd, data): if self._config.DUMP_DIR == None: debug.error("Please specify a dump directory (--dump-dir)") if not os.path.isdir(self._config.DUMP_DIR): debug.error(self._config.DUMP_DIR + " is not a directory") self.table_header(outfd, [("Module Base", "[addrpad]"), ("Module Name", "20"), ("Result", "")]) for addr_space, procs, mod_base, mod_name in data: space = tasks.find_space(addr_space, procs, mod_base) if space == None: result = "Error: Cannot acquire AS" else: dump_file = "driver.{0:x}.sys".format(mod_base) result = self.dump_pe(space, mod_base, dump_file) self.table_row(outfd, mod_base, mod_name, result)
def calculate(self): if not has_distorm: debug.error("You must install distorm3") addr_space = utils.load_as(self._config) all_tasks = list(tasks.pslist(addr_space)) all_mods = list(modules.lsmod(addr_space)) # Operate in kernel mode if pid is not supplied if not self._config.PID: if not self._config.BASE: debug.error("You must specify --BASE") base_address = self._config.BASE size_to_read = self._config.SIZE # Get the size from the module list if its not supplied if not size_to_read: for module in all_mods: if module.DllBase == base_address: size_to_read = module.SizeOfImage break # Alternately, try the size from the PE header if not size_to_read: pefile = obj.Object("_IMAGE_DOS_HEADER", offset=base_address, vm=addr_space) try: nt_header = pefile.get_nt_header() size_to_read = nt_header.OptionalHeader.SizeOfImage except ValueError: pass if not size_to_read: debug.error("You must specify --SIZE") kernel_space = tasks.find_space(addr_space, all_tasks, base_address) if not kernel_space: debug.error("Cannot read supplied address") data = kernel_space.zread(base_address, size_to_read) apis = self.enum_apis(all_mods) addr_space = kernel_space else: # In process mode, we find the process by PID task = None for atask in all_tasks: if atask.UniqueProcessId == self._config.PID: task = atask break if not task: debug.error("You must supply an active PID") task_space = task.get_process_address_space() if not task_space: debug.error("Cannot acquire process AS") all_mods = list(task.get_load_modules()) # PEB is paged or no DLLs loaded if not all_mods: debug.error("Cannot load DLLs in process AS") # If an address is supplied with a size, try to get # the size from the vad node. If neither are supplied, # assume we should carve the main process executable. if self._config.BASE: base_address = self._config.BASE size_to_read = self._config.SIZE if not size_to_read: for vad in task.VadRoot.traverse(): if base_address >= vad.Start and base_address <= vad.End: size_to_read = vad.Length if not size_to_read: debug.error("You must specify --SIZE") else: # Its OK to blindly take the 0th element because the # executable is always the first module to load. base_address = all_mods[0].DllBase size_to_read = all_mods[0].SizeOfImage data = task_space.zread(base_address, size_to_read) apis = self.enum_apis(all_mods) addr_space = task_space # This is a dictionary of confirmed API calls. calls_imported = dict( (iat, call) for (_, iat, call) in self.call_scan(addr_space, base_address, data) if call in apis) # Scan forward self._vicinity_scan(addr_space, calls_imported, apis, base_address, len(data), forward=True) # Scan reverse self._vicinity_scan(addr_space, calls_imported, apis, base_address, len(data), forward=False) for iat, call in sorted(calls_imported.items()): yield iat, call, apis[call][0], apis[call][1]
if "Symlink" in self._config.TYPE: data = filescan.SymLinkScan(self._config).calculate() for link in data: objct = link.get_object_header() line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format( "" if body else "|", str(objct.NameInfo.Name or ''), str(link.LinkTarget or ''), link.obj_offset, objct.PointerCount, objct.HandleCount, self._config.MACHINE) yield self.getoutput(line, link.CreationTime, body=body) data = [] if "TimeDateStamp" in self._config.TYPE: data = moddump.ModDump(self._config).calculate() for aspace, procs, mod_base, mod_name in data: mod_name = str(mod_name or '') space = tasks.find_space(aspace, procs, mod_base) if space != None: try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset=mod_base, vm=space) header = pe_file.get_nt_header() except ValueError, ve: continue line = "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format( "" if body else "|", mod_name, mod_base, self._config.MACHINE) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body)
def calculate(self): addr_space = utils.load_as(self._config) if not has_distorm3: debug.error("Install distorm3 code.google.com/p/distorm/") if not self.is_valid_profile(addr_space.profile): debug.error("This command does not support the selected profile.") if not self._config.SKIP_PROCESS: for proc in self.filter_tasks(tasks.pslist(addr_space)): process_name = str(proc.ImageFileName).lower() if (self._config.QUICK and process_name not in self.critical_process): #debug.debug("Skipping non-critical process {0} ({1})".format( # process_name, proc.UniqueProcessId)) continue process_space = proc.get_process_address_space() if not process_space: #debug.debug("Cannot acquire process AS for {0} ({1})".format( # process_name, proc.UniqueProcessId)) continue module_group = ModuleGroup(proc.get_load_modules()) for dll in module_group.mods: if not process_space.is_valid_address(dll.DllBase): continue dll_name = str(dll.BaseDllName or '').lower() if (self._config.QUICK and dll_name not in self.critical_dlls and dll.DllBase != proc.Peb.ImageBaseAddress): #debug.debug("Skipping non-critical dll {0} at {1:#x}".format( # dll_name, dll.DllBase)) continue #debug.debug("Analyzing {0}!{1}".format(process_name, dll_name)) for hook in self.get_hooks(HOOK_MODE_USER, process_space, dll, module_group): yield proc, dll, hook if not self._config.SKIP_KERNEL: process_list = list(tasks.pslist(addr_space)) module_group = ModuleGroup(modules.lsmod(addr_space)) for mod in module_group.mods: #module_name = str(mod.BaseDllName or '') #debug.debug("Analyzing {0}".format(module_name)) kernel_space = tasks.find_space(addr_space, process_list, mod.DllBase) if not kernel_space: #debug.debug("No kernel AS for {0} at {1:#x}".format( # module_name, mod.DllBase)) continue for hook in self.get_hooks(HOOK_MODE_KERNEL, kernel_space, mod, module_group): yield None, mod, hook
def calculate(self): addr_space = utils.load_as(self._config) self._config.update('TIMELINE', -1) pids = {} #dictionary of process IDs/ImageFileName offsets = [] #process offsets im = self.get_image_time(addr_space) event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime']) yield event # Get EPROCESS psscan = filescan.PSScan.calculate(self) for eprocess in psscan: if eprocess.obj_offset not in offsets: offsets.append(eprocess.obj_offset) ts = eprocess.CreateTime or '-1' line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format( eprocess.CreateTime or '-1', "[PROCESS]", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime or '', eprocess.obj_offset) pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName yield line # Get Sockets and Evtlogs XP/2k3 only if addr_space.profile.metadata.get('major', 0) == 5: #socks = sockets.Sockets.calculate(self) socks = sockscan.SockScan.calculate(self) for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format( sock.CreateTime, sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) yield line stuff = evtlogs.EvtLogs.calculate(self) for name, buf in stuff: lines = self.parse_evt_info(name, buf) for l in lines: l = l.replace("\n", "") t = l.split("|") line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format( t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]) yield line else: # Vista+ nets = netscan.Netscan.calculate(self) for offset, proto, laddr, lport, raddr, rport, state, p, ctime in nets: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format( ctime, p.UniqueProcessId, conn, proto, state, offset) yield line # Get threads threads = modscan.ThrdScan.calculate(self) for thread in threads: try: image = pids[thread.Cid.UniqueProcess.v()] except: image = "" line = "{0}|{1}|{2}|{3}|{4}|{5}|||\n".format( thread.CreateTime or '-1', "[THREAD]", image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, thread.ExitTime or '', ) yield line # now we get to the PE part. All PE's are dumped in case you want to inspect them later # Get module offsets by scanning mod_offsets = [] data = modscan.ModScan.calculate(self) for module in data: base = "{0:#010x}".format(module.DllBase) mod_offsets.append(base) # and get PE timestamps for those modules for base in mod_offsets: self._config.update('OFFSET', int(base, 16)) data = moddump.ModDump.calculate(self) for addr_space, procs, mod_base, mod_name in data: space = tasks.find_space(addr_space, procs, mod_base) if space != None: try: header = self.get_nt_header(space, mod_base) except ValueError, ve: continue try: line = "{0}|{1}|{2}|{3}|{4:#010x}|||||\n".format( self.time_stamp(header.FileHeader.TimeDateStamp) or '-1', "[PE Timestamp (module)]", mod_name, "", mod_base) except: line = "{0}|{1}|{2}|{3}|{4}|||||\n".format( '-1', "[PE Timestamp (module)]", mod_name, "", mod_base) yield line
def calculate(self): addr_space = utils.load_as(self._config) self._config.update('TIMELINE', -1) pids = {} #dictionary of process IDs/ImageFileName offsets = [] #process offsets im = self.get_image_time(addr_space) event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime']) yield event # Get EPROCESS psscan = filescan.PSScan.calculate(self) for eprocess in psscan: if eprocess.obj_offset not in offsets: offsets.append(eprocess.obj_offset) ts = eprocess.CreateTime or '-1' line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format( eprocess.CreateTime or '-1', "[PROCESS]", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime or '', eprocess.obj_offset) pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName yield line # Get Sockets and Evtlogs XP/2k3 only if addr_space.profile.metadata.get('major', 0) == 5: #socks = sockets.Sockets.calculate(self) socks = sockscan.SockScan.calculate(self) for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format( sock.CreateTime, sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) yield line stuff = evtlogs.EvtLogs.calculate(self) for name, buf in stuff: lines = self.parse_evt_info(name, buf) for l in lines: l = l.replace("\n","") t = l.split("|") line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format( t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]) yield line else: # Vista+ nets = netscan.Netscan.calculate(self) for offset, proto, laddr, lport, raddr, rport, state, p, ctime in nets: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format( ctime, p.UniqueProcessId, conn, proto, state, offset) yield line # Get threads threads = modscan.ThrdScan.calculate(self) for thread in threads: try: image = pids[thread.Cid.UniqueProcess.v()] except: image = "" line = "{0}|{1}|{2}|{3}|{4}|{5}|||\n".format( thread.CreateTime or '-1', "[THREAD]", image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, thread.ExitTime or '', ) yield line # now we get to the PE part. All PE's are dumped in case you want to inspect them later # Get module offsets by scanning mod_offsets = [] data = modscan.ModScan.calculate(self) for module in data: base = "{0:#010x}".format(module.DllBase) mod_offsets.append(base) # and get PE timestamps for those modules for base in mod_offsets: self._config.update('OFFSET', int(base, 16)) data = moddump.ModDump.calculate(self) for addr_space, procs, mod_base, mod_name in data: space = tasks.find_space(addr_space, procs, mod_base) if space != None: try: header = self.get_nt_header(space, mod_base) except ValueError, ve: continue try: line = "{0}|{1}|{2}|{3}|{4:#010x}|||||\n".format( self.time_stamp(header.FileHeader.TimeDateStamp) or '-1', "[PE Timestamp (module)]", mod_name, "", mod_base) except: line = "{0}|{1}|{2}|{3}|{4}|||||\n".format( '-1', "[PE Timestamp (module)]", mod_name, "", mod_base) yield line
def calculate(self): if self._config.OUTPUT == "xlsx" and not has_openpyxl: debug.error("You must install OpenPyxl for xlsx format:\n\thttps://bitbucket.org/ericgazoni/openpyxl/wiki/Home") elif self._config.OUTPUT == "xlsx" and not self._config.OUTPUT_FILE: debug.error("You must specify an output *.xlsx file!\n\t(Example: --output-file=OUTPUT.xlsx)") if (self._config.HIVE or self._config.USER) and not (self._config.REGISTRY): debug.error("You must use -R/--registry in conjuction with -H/--hive and/or -U/--user") addr_space = utils.load_as(self._config) version = (addr_space.profile.metadata.get('major', 0), addr_space.profile.metadata.get('minor', 0)) pids = {} #dictionary of process IDs/ImageFileName offsets = [] #process offsets im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) body = False l2tcsv = False plaso = False if self._config.OUTPUT == "body": body = True elif self._config.OUTPUT == "l2tcsv": l2tcsv = True elif self._config.OUTPUT == "plaso": plaso = True if l2tcsv or plaso: if self._config.tz: timezone = self._config.tz else: timezone = 'UTC' if l2tcsv: line = "date,time,timezone,MACB,source,sourcetype,type,user,host,short,desc,version,filename,inode,notes,format,extra\n" elif body: line = "0|[END LIVE RESPONSE]|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(im['ImageDatetime'].v()) else: line = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime']) if line and not plaso: yield line # Get EPROCESS psscan = filescan.PSScan(self._config).calculate() for eprocess in psscan: if eprocess.obj_offset not in offsets: offsets.append(eprocess.obj_offset) if l2tcsv: unixdatetime = eprocess.CreateTime.v() year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y')) time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S')) line = "{0},{1},{6},...B,MEMORY,PROCESS,Created,-,-,,Process: {2}<|>PID: {3}<|>PPID: {4}<|>POffset: 0x{5:08x},,{2},0,-,-,\n".format( year, time, eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.obj_offset, timezone) unixdatetime2 = eprocess.ExitTime.v() year2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%m/%d/%Y')) time2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%H:%M:%S')) yield "{0},{1},{6},.A..,MEMORY,PROCESS,Exit,-,-,,Process:{2}<|>PID: {3}<|>PPID: {4}<|>POffset: 0x{5:08x},,{2},0,-,-,\n".format( year2, time2, eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.obj_offset, timezone) elif plaso: unixdatetime = eprocess.CreateTime.v() line = vol_time.EprocessEvent(unixdatetime, eprocess, timezone) yield vol_time.EprocessEvent(eprocess.ExitTime.v(), eprocess, timezone, True) elif body: line = "0|[PROCESS] {2}/PID: {3}/PPID: {4}/POffset: 0x{5:08x}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( eprocess.CreateTime.v(), eprocess.ExitTime.v(), eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.obj_offset) else: line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format( eprocess.CreateTime or '-1', "[PROCESS]", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime or '', eprocess.obj_offset) pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName yield line # Get Sockets and Evtlogs XP/2k3 only if addr_space.profile.metadata.get('major', 0) == 5: socks = sockets.Sockets(self._config).calculate() #socks = sockscan.SockScan(self._config).calculate() # you can use sockscan instead if you uncomment for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) if l2tcsv: unixdatetime = sock.CreateTime.v() year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y')) time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S')) line = "{0},{1},{7},...B,MEMORY,SOCKET,Created,-,-,,PID: {2}<|>LocalIP: {3}<|>Protocol: {4}({5}),,{2},0,-,-,\n".format( year, time, sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset, timezone) elif plaso: unixdatetime = sock.CreateTime.v() line = vol_time.SockEvent(unixdatetime, sock, protos.protos.get(sock.Protocol.v(), "-")) elif body: line = "0|[SOCKET] PID: {1}/LocalIP: {2}/Protocol: {3}({4})/POffset: 0x{5:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( sock.CreateTime.v(), sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) else: line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format( sock.CreateTime, sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) yield line stuff = evtlogs.EvtLogs.calculate(self) for name, buf in stuff: for fields in self.parse_evt_info(name, buf, rawtime = True): if l2tcsv: unixdatetime = fields[0] year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y')) time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S')) line = "{0},{1},{9},...B,MEMORY,MEM-EVT LOG,Created,-,-,,{2}<|>{3}<|>{4}<|>{5}<|>{6}<|>{7}<|>{8},,-,0,-,-,\n".format( year, time, #Need to replace , for ; so does not throw of delimitor fields[1].replace(",", ";"), fields[2].replace(",", ";"), fields[3].replace(",", ";"), fields[4].replace(",", ";"), fields[5].replace(",", ";"), fields[6].replace(",", ";"), fields[7].replace(",", ";"), timezone) elif plaso: unixdatetime = int(fields[0]) line = vol_time.EvtEvent(unixdatetime, fields) elif body: line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format( fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) else: line = "0|[EVT LOG] {1}/{2}/{3}/{4}/{5}/{6}/{7}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( fields[0].v(),fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) yield line else: # Vista+ nets = netscan.Netscan(self._config).calculate() for net_object, proto, laddr, lport, raddr, rport, state in nets: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) if l2tcsv: unixdatetime = net_object.CreateTime.v() year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y')) time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S')) line = "{0},{1},{7},...B,MEMORY,Network Connection,Created,-,-,,{2}/{3}/{4}/{5}/{6:<#10x},,-,0,-,-,\n".format( year, time, net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset, timezone) elif plaso: unixdatetime = net_object.CreateTime.v() line = vol_time.NetObjectEvent(unixdatetime, net_object, laddr, lport, raddr, rport, proto, state) elif body: line = "0|[NETWORK CONNECTION] {1}/{2}/{3}/{4}/{5:<#10x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( net_object.CreateTime.v(), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) else: line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format( str(net_object.CreateTime or "-1"), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) yield line # Get threads threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") if l2tcsv: unixdatetime = thread.CreateTime.v() year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y')) time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S')) line = "{0},{1},{5},...B,MEMORY,THREAD,Created,-,-,,File: {2}<|>PID: {3}<|>TID: {4},,-,0,-,-,\n".format( year, time, image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, timezone) unixdatetime2 = thread.ExitTime.v() year2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%m/%d/%Y')) time2 = (datetime.datetime.fromtimestamp(int(unixdatetime2)).strftime('%H:%M:%S')) yield "{0},{1},{5},.A..,MEMORY,THREAD,Exit,-,-,,{2}/PID: {3}/TID: {4},,-,0,-,-,\n".format( year2, time2, image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, timezone) elif body: line = "0|[THREAD] {2}/PID: {3}/TID: {4}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( thread.CreateTime.v(), thread.ExitTime.v(), image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, ) elif plaso: unixdatetime = thread.CreateTime.v() yield vol_time.ThreadEvent(unixdatetime, image, thread) unixdatetime = thread.ExitTime.v() line = vol_time.ThreadEvent(unixdatetime, image, thread, True) else: line = "{0}|[THREAD]|{1}|{2}|{3}|{4}|||\n".format( thread.CreateTime or '-1', image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, thread.ExitTime or '', ) yield line # now we get to the PE part. All PE's are dumped in case you want to inspect them later data = moddump.ModDump(self._config).calculate() for addr_space, procs, mod_base, mod_name in data: space = tasks.find_space(addr_space, procs, mod_base) if space != None: try: header = procdump.ProcExeDump(self._config).get_nt_header(space, mod_base) except ValueError, ve: continue try: if l2tcsv: unixdatetime = header.FileHeader.TimeDateStamp.v() year = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%m/%d/%Y')) time = (datetime.datetime.fromtimestamp(int(unixdatetime)).strftime('%H:%M:%S')) line = "{0},{1},{4},...B,MEMORY,MEM-PE Timestamp,Created,-,-,,File: {2}<|>Base: {3:#010x},,-,0,-,-,\n".format( year, time, mod_name, mod_base, timezone) elif plaso: unixdatetime = header.FileHeader.TimeDateStamp.v() line = vol_time.ProcExeDumpEvent(unixdatetime, mod_name, mod_base) elif body: line = "0|[PE Timestamp (module)] {1}/Base: {2:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( header.FileHeader.TimeDateStamp.v(), mod_name, mod_base) else: line = "{0}|[PE Timestamp (module)]|{1}||{2:#010x}|||||\n".format( header.FileHeader.TimeDateStamp or '-1', mod_name, mod_base) except ValueError, ve: if l2tcsv: pass elif plaso: line = vol_time.ProcExeDumpEvent(0, mod_name, mod_base) elif body: line = "0|[PE Timestamp (module)] {0}/Base: {1:#010x}|0|---------------|0|0|0|0|0|0|0\n".format( mod_name, mod_base) else: line = "-1|[PE Timestamp (module)]|{0}||{1}|||||\n".format( mod_name, mod_base) yield line
def calculate(self): if not has_distorm: debug.error("You must install distorm3") addr_space = utils.load_as(self._config) all_tasks = list(tasks.pslist(addr_space)) all_mods = list(modules.lsmod(addr_space)) # Operate in kernel mode if pid is not supplied if not self._config.PID: if not self._config.BASE: debug.error("You must specify --BASE") base_address = self._config.BASE size_to_read = self._config.SIZE # Get the size from the module list if its not supplied if not size_to_read: for module in all_mods: if module.DllBase == base_address: size_to_read = module.SizeOfImage break # Alternately, try the size from the PE header if not size_to_read: pefile = obj.Object("_IMAGE_DOS_HEADER", offset = base_address, vm = addr_space) try: nt_header = pefile.get_nt_header() size_to_read = nt_header.OptionalHeader.SizeOfImage except ValueError: pass if not size_to_read: debug.error("You must specify --SIZE") kernel_space = tasks.find_space(addr_space, all_tasks, base_address) if not kernel_space: debug.error("Cannot read supplied address") data = kernel_space.zread(base_address, size_to_read) apis = self.enum_apis(all_mods) addr_space = kernel_space else: # In process mode, we find the process by PID task = None for atask in all_tasks: if atask.UniqueProcessId == self._config.PID: task = atask break if not task: debug.error("You must supply an active PID") task_space = task.get_process_address_space() if not task_space: debug.error("Cannot acquire process AS") all_mods = list(task.get_load_modules()) # PEB is paged or no DLLs loaded if not all_mods: debug.error("Cannot load DLLs in process AS") # If an address is supplied with a size, try to get # the size from the vad node. If neither are supplied, # assume we should carve the main process executable. if self._config.BASE: base_address = self._config.BASE size_to_read = self._config.SIZE if not size_to_read: for vad in task.VadRoot.traverse(): if base_address >= vad.Start and base_address <= vad.End: size_to_read = vad.Length if not size_to_read: debug.error("You must specify --SIZE") else: # Its OK to blindly take the 0th element because the # executable is always the first module to load. base_address = all_mods[0].DllBase size_to_read = all_mods[0].SizeOfImage if not task_space.is_valid_address(base_address): debug.error("Address is not valid in process AS") data = task_space.zread(base_address, size_to_read) apis = self.enum_apis(all_mods) addr_space = task_space # This is a dictionary of confirmed API calls. calls_imported = dict( (iat, call) for (_, iat, call) in self.call_scan(addr_space, base_address, data) if call in apis ) # Scan forward self._vicinity_scan(addr_space, calls_imported, apis, base_address, len(data), forward = True) # Scan reverse self._vicinity_scan(addr_space, calls_imported, apis, base_address, len(data), forward = False) for iat, call in sorted(calls_imported.items()): yield iat, call, apis[call][0], apis[call][1]
line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format( "" if body else "|", str(objct.NameInfo.Name or ''), str(link.LinkTarget or ''), link.obj_offset, objct.PointerCount, objct.HandleCount, self._config.MACHINE) yield self.getoutput(line, link.CreationTime, body = body) data = [] if "TimeDateStamp" in self._config.TYPE: data = moddump.ModDump(self._config).calculate() for aspace, procs, mod_base, mod_name in data: mod_name = str(mod_name or '') space = tasks.find_space(aspace, procs, mod_base) if space != None: try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset = mod_base, vm = space) header = pe_file.get_nt_header() except ValueError, ve: continue line = "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format( "" if body else "|", mod_name, mod_base, self._config.MACHINE) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body = body) uastuff = [] if "Userassist" in self._config.TYPE:
def calculate(self): if (self._config.HIVE or self._config.USER) and "Registry" not in self._config.TYPE: debug.error( "You must use --registry in conjuction with -H/--hive and/or -U/--user" ) if self._config.TYPE != None: for t in self._config.TYPE.split(","): if t.strip() not in self.types and t.strip() != "Registry": debug.error( "You have entered an incorrect type: {0}".format(t)) addr_space = utils.load_as(self._config) version = ( addr_space.profile.metadata.get('major', 0), addr_space.profile.metadata.get('minor', 0), ) pids = {} # dictionary of process IDs/ImageFileName body = False if self._config.OUTPUT == "body": body = True if self._config.MACHINE != "": self._config.update("MACHINE", "{0} ".format(self._config.MACHINE)) if "ImageDate" in self._config.TYPE: im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) yield self.getoutput( "[{0}LIVE RESPONSE]{1} (System time){1}".format( self._config.MACHINE, "" if body else "|"), im['ImageDatetime'], body=body, ) if version <= (6, 1) and "IEHistory" in self._config.TYPE: self._config.update("LEAK", True) data = iehistory.IEHistory(self._config).calculate() for process, record in data: ## Extended fields are available for these records if record.obj_name == "_URL_RECORD": line = "[{6}IEHISTORY]{0} {1}->{5}{0} PID: {2}/Cache type \"{3}\" at {4:#x}".format( "" if body else "|", process.ImageFileName, process.UniqueProcessId, record.Signature, record.obj_offset, record.Url, self._config.MACHINE, ) yield self.getoutput( line, record.LastModified, end=record.LastAccessed, body=body, ) self._config.remove_option("REDR") self._config.remove_option("LEAK") psx = [] if ("Process" in self._config.Type or "TimeDateStamp" in self._config.Type or "LoadTime" in self._config.Type or "_CM_KEY_BODY" in self._config.Type): psx = psxview.PsXview(self._config).calculate() for offset, eprocess, ps_sources in psx: pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName if "Process" in self._config.TYPE: line = "[{5}PROCESS]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput(line, eprocess.CreateTime, end=eprocess.ExitTime, body=body) if not hasattr(eprocess.obj_vm, "vtop"): eprocess = taskmods.DllList( self._config).virtual_process_from_physical_offset( addr_space, eprocess.obj_offset) if eprocess == None: continue else: ps_ad = eprocess.get_process_address_space() if ps_ad == None: continue if version[0] == 5 and "Process" in self._config.TYPE: line = "[{5}PROCESS LastTrimTime]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput(line, eprocess.Vm.LastTrimTime, body=body) if (eprocess.ObjectTable.HandleTableList and "_CM_KEY_BODY" in self._config.TYPE): for handle in eprocess.ObjectTable.handles(): if not handle.is_valid(): continue name = "" object_type = handle.get_object_type() if object_type == "Key": key_obj = handle.dereference_as("_CM_KEY_BODY") name = key_obj.full_key_name() line = "[{6}Handle (Key)]{0} {1}{0} {2} PID: {3}/PPID: {4}/POffset: 0x{5:08x}".format( "" if body else "|", name, eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput( line, key_obj.KeyControlBlock.KcbLastWriteTime, body=body, ) if eprocess.Peb == None or eprocess.Peb.ImageBaseAddress == None: continue # Get DLL PE timestamps for Wow64 processes (excluding 64-bit ones) if eprocess.IsWow64 and "TimeDateStamp" in self._config.TYPE: for vad, address_space in eprocess.get_vads( vad_filter=eprocess._mapped_file_filter): if vad.FileObject.FileName: name = str(vad.FileObject.FileName).lower() basename = ntpath.basename(name) if not basename.endswith("dll") or basename in [ "wow64cpu.dll", "ntdll.dll", "wow64.dll", "wow64win.dll", ]: continue data = ps_ad.zread(vad.Start, vad.Length) bufferas = addrspace.BufferAddressSpace(self._config, data=data) try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset=0, vm=bufferas) header = pe_file.get_nt_header() except ValueError as ve: continue line = "[{7}PE HEADER 32-bit (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, vad.Start, self._config.MACHINE, ) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body) # get DLL PE timestamps mods = dict() if ("TimeDateStamp" in self._config.TYPE or "LoadTime" in self._config.TYPE): mods = dict((mod.DllBase.v(), mod) for mod in eprocess.get_load_modules()) for mod in list(mods.values()): basename = str(mod.BaseDllName or "") if basename == str(eprocess.ImageFileName): line = "[{7}PE HEADER (exe)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) else: line = "[{7}PE HEADER (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) if "TimeDateStamp" in self._config.TYPE: yield self.getoutput(line, mod.TimeDateStamp, body=body) line2 = "[{7}PE DEBUG]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) yield self.getoutput( line2, mod.get_debug_directory().TimeDateStamp, body=body, ) if (hasattr(mod, "LoadTime") and "LoadTime" in self._config.TYPE): temp = line.replace( "[{0}PE HEADER ".format(self._config.MACHINE), "[{0}DLL LOADTIME ".format(self._config.MACHINE), ) yield self.getoutput(temp, mod.LoadTime, body=body) # Get Sockets and Evtlogs XP/2k3 only if version[0] == 5: # socks = sockets.Sockets(self._config).calculate() socks = [] if "Socket" in self._config.TYPE: socks = sockscan.SockScan(self._config).calculate( ) # you can use sockscan instead if you uncomment for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) line = "[{6}SOCKET]{0} LocalIP: {2}/Protocol: {3}({4}){0} PID: {1}/POffset: 0x{5:#010x}".format( "" if body else "|", sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset, self._config.MACHINE, ) yield self.getoutput(line, sock.CreateTime, body=body) stuff = [] if "EvtLog" in self._config.TYPE: evt = evtlogs.EvtLogs(self._config) stuff = evt.calculate() for name, buf in stuff: for fields in evt.parse_evt_info(name, buf, rawtime=True): line = "[{8}EVT LOG]{0} {1}{0} {2}/{3}/{4}/{5}/{6}/{7}".format( "" if body else "|", fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7], self._config.MACHINE, ) yield self.getoutput(line, fields[0], body=body) elif version <= (6, 1): # Vista+ nets = [] if "Socket" in self._config.TYPE: nets = netscan.Netscan(self._config).calculate() for net_object, proto, laddr, lport, raddr, rport, state in nets: if net_object.CreateTime.v() == 0: continue if raddr == "*" and rport == "*": conn = "{0}:{1}".format(laddr, lport) socket_type = "SOCKET" else: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) socket_TYPE = "CONNECTION" line = ( "[{6}NETWORK {7}]{0} {2}{0} {1}/{3}/{4}/{5:<#10x}".format( "" if body else "|", net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset, self._config.MACHINE, socket_type, )) yield self.getoutput(line, net_object.CreateTime, body=body) # Get threads threads = [] if "Thread" in self._config.TYPE: threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") line = "[{4}THREAD]{0} {1}{0} PID: {2}/TID: {3}".format( "" if body else "|", image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, self._config.MACHINE, ) yield self.getoutput(line, thread.CreateTime, end=thread.ExitTime, body=body) data = [] if "Symlink" in self._config.TYPE: data = filescan.SymLinkScan(self._config).calculate() for link in data: objct = link.get_object_header() line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format( "" if body else "|", str(objct.NameInfo.Name or ''), str(link.LinkTarget or ''), link.obj_offset, objct.PointerCount, objct.HandleCount, self._config.MACHINE, ) yield self.getoutput(line, link.CreationTime, body=body) data = [] if "TimeDateStamp" in self._config.TYPE: data = moddump.ModDump(self._config).calculate() for aspace, procs, mod_base, mod_name in data: mod_name = str(mod_name or '') space = tasks.find_space(aspace, procs, mod_base) if space != None: try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset=mod_base, vm=space) header = pe_file.get_nt_header() except ValueError as ve: continue line = ( "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format( "" if body else "|", mod_name, mod_base, self._config.MACHINE, )) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body) uastuff = [] if "Userassist" in self._config.TYPE: uastuff = userassist.UserAssist(self._config).calculate() for win7, reg, key in uastuff: ts = "{0}".format(key.LastWriteTime) for v in rawreg.values(key): tp, dat = rawreg.value_data(v) subname = v.Name if tp == 'REG_BINARY': dat_raw = dat try: subname = codecs.encode(subname, 'rot_13') except UnicodeDecodeError: pass if win7: guid = subname.split("\\")[0] if guid in userassist.folder_guids: subname = subname.replace( guid, userassist.folder_guids[guid]) bufferas = addrspace.BufferAddressSpace(self._config, data=dat_raw) uadata = obj.Object("_VOLUSER_ASSIST_TYPES", offset=0, vm=bufferas) ID = "N/A" count = "N/A" fc = "N/A" tf = "N/A" lw = "N/A" if (len(dat_raw) < bufferas.profile.get_obj_size( '_VOLUSER_ASSIST_TYPES') or uadata == None): continue else: if hasattr(uadata, "ID"): ID = "{0}".format(uadata.ID) if hasattr(uadata, "Count"): count = "{0}".format(uadata.Count) else: count = "{0}".format( uadata.CountStartingAtFive if uadata.CountStartingAtFive < 5 else uadata.CountStartingAtFive - 5) if hasattr(uadata, "FocusCount"): seconds = (uadata.FocusTime + 500) / 1000.0 time = (datetime.timedelta(seconds=seconds) if seconds > 0 else uadata.FocusTime) fc = "{0}".format(uadata.FocusCount) tf = "{0}".format(time) lw = "{0}".format(uadata.LastUpdated) subname = subname.replace("|", "%7c") line = "[{7}USER ASSIST]{0} {2}{0} Registry: {1}/ID: {3}/Count: {4}/FocusCount: {5}/TimeFocused: {6}".format( "" if body else "|", reg, subname, ID, count, fc, tf, self._config.MACHINE, ) yield self.getoutput(line, uadata.LastUpdated, body=body) shimdata = [] if "Shimcache" in self._config.TYPE: shimdata = shimcache.ShimCache(self._config).calculate() for path, lm, lu in shimdata: line = "[{2}SHIMCACHE]{0} {1}{0} ".format("" if body else "|", path, self._config.MACHINE) if lu: yield self.getoutput(line, lm, end=lu, body=body) else: yield self.getoutput(line, lm, body=body) if ("_HBASE_BLOCK" in self._config.TYPE or "_CMHIVE" in self._config.TYPE or "Registry" in self._config.TYPE): regapi = registryapi.RegistryApi(self._config) for o in regapi.all_offsets: if "_HBASE_BLOCK" in self._config.TYPE: line = "[{2}_HBASE_BLOCK TimeStamp]{0} {1}{0} ".format( "" if body else "|", regapi.all_offsets[o], self._config.MACHINE, ) h = obj.Object("_HHIVE", o, addr_space) yield self.getoutput(line, h.BaseBlock.TimeStamp, body=body) if ("_CMHIVE" in self._config.TYPE and version[0] == 6 and addr_space.profile.metadata.get('build', 0) >= 7601): line = ( line) = "[{2}_CMHIVE LastWriteTime]{0} {1}{0} ".format( "" if body else "|", regapi.all_offsets[o], self._config.MACHINE, ) cmhive = obj.Object("_CMHIVE", o, addr_space) yield self.getoutput(line, cmhive.LastWriteTime, body=body) if "Registry" in self._config.TYPE: regapi.reset_current() regdata = regapi.reg_get_all_keys(self._config.HIVE, self._config.USER, reg=True, rawtime=True) for lwtime, reg, item in regdata: item = item.replace("|", "%7c") line = "[{3}REGISTRY]{0} {2}{0} Registry: {1}".format( "" if body else "|", reg, item, self._config.MACHINE) yield self.getoutput(line, lwtime, body=body) if "Timer" in self._config.TYPE: volmagic = obj.VolMagic(addr_space) KUSER_SHARED_DATA = obj.Object( "_KUSER_SHARED_DATA", offset=volmagic.KUSER_SHARED_DATA.v(), vm=addr_space, ) interrupt = (KUSER_SHARED_DATA.InterruptTime.High1Time << 32) | KUSER_SHARED_DATA.InterruptTime.LowPart now = KUSER_SHARED_DATA.SystemTime.as_windows_timestamp() data = timers.Timers(self._config).calculate() for timer, module in data: signaled = "-" if timer.Header.SignalState.v(): signaled = "Yes" module_name = "UNKNOWN" if module: module_name = str(module.BaseDllName or '') try: # human readable time taken from http://computer.forensikblog.de/en/2011/10/timers-and-times.html bufferas = addrspace.BufferAddressSpace( self._config, data=struct.pack( '<Q', timer.DueTime.QuadPart - interrupt + now), ) due_time = obj.Object("WinTimeStamp", is_utc=True, offset=0, vm=bufferas) except TypeError: due_time = 0 line = "[{6}TIMER]{0} {1}{0} Signaled: {2}/Routine: 0x{3:x}/Period(ms): {4}/Offset: 0x{5:x}".format( "" if body else "|", module_name, signaled, timer.Dpc.DeferredRoutine, timer.Period, timer.obj_offset, self._config.MACHINE, ) yield self.getoutput(line, due_time, body=body)
def calculate(self): addr_space = utils.load_as(self._config) if not has_distorm3: debug.error("Install distorm3 code.google.com/p/distorm/") if not self._config.SKIP_PROCESS: for proc in self.filter_tasks(tasks.pslist(addr_space)): process_name = str(proc.ImageFileName).lower() if (self._config.QUICK and process_name not in self.critical_process): #debug.debug("Skipping non-critical process {0} ({1})".format( # process_name, proc.UniqueProcessId)) continue process_space = proc.get_process_address_space() if not process_space: #debug.debug("Cannot acquire process AS for {0} ({1})".format( # process_name, proc.UniqueProcessId)) continue module_group = ModuleGroup(proc.get_load_modules()) for dll in module_group.mods: if not process_space.is_valid_address(dll.DllBase): continue dll_name = str(dll.BaseDllName or '').lower() if (self._config.QUICK and dll_name not in self.critical_dlls and dll.DllBase != proc.Peb.ImageBaseAddress): #debug.debug("Skipping non-critical dll {0} at {1:#x}".format( # dll_name, dll.DllBase)) continue #debug.debug("Analyzing {0}!{1}".format(process_name, dll_name)) for hook in self.get_hooks(HOOK_MODE_USER, process_space, dll, module_group): if not self._config.NO_WHITELIST: if self.whitelist(hook.hook_mode | hook.hook_type, str(proc.ImageFileName), hook.VictimModule, hook.HookModule, hook.Function): continue yield proc, dll, hook if not self._config.SKIP_KERNEL: process_list = list(tasks.pslist(addr_space)) module_group = ModuleGroup(modules.lsmod(addr_space)) for mod in module_group.mods: #module_name = str(mod.BaseDllName or '') #debug.debug("Analyzing {0}".format(module_name)) kernel_space = tasks.find_space(addr_space, process_list, mod.DllBase) if not kernel_space: #debug.debug("No kernel AS for {0} at {1:#x}".format( # module_name, mod.DllBase)) continue for hook in self.get_hooks(HOOK_MODE_KERNEL, kernel_space, mod, module_group): if not self._config.NO_WHITELIST: if self.whitelist(hook.hook_mode | hook.hook_type, "", hook.VictimModule, hook.HookModule, hook.Function): continue yield None, mod, hook
def calculate(self): if self._config.OUTPUT == "xlsx" and not has_openpyxl: debug.error("You must install OpenPyxl for xlsx format:\n\thttps://bitbucket.org/ericgazoni/openpyxl/wiki/Home") elif self._config.OUTPUT == "xlsx" and not self._config.OUTPUT_FILE: debug.error("You must specify an output *.xlsx file!\n\t(Example: --output-file=OUTPUT.xlsx)") if (self._config.HIVE or self._config.USER) and not (self._config.REGISTRY): debug.error("You must use -R/--registry in conjuction with -H/--hive and/or -U/--user") addr_space = utils.load_as(self._config) version = (addr_space.profile.metadata.get('major', 0), addr_space.profile.metadata.get('minor', 0)) pids = {} #dictionary of process IDs/ImageFileName offsets = [] #process offsets im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) body = False if self._config.OUTPUT == "body": body = True if not body: event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime']) else: event = "0|[END LIVE RESPONSE]|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format(im['ImageDatetime'].v()) yield event # Get EPROCESS psscan = filescan.PSScan(self._config).calculate() for eprocess in psscan: if eprocess.obj_offset not in offsets: offsets.append(eprocess.obj_offset) if not body: line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format( eprocess.CreateTime or '-1', "[PROCESS]", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime or '', eprocess.obj_offset) else: line = "0|[PROCESS] {2}/PID: {3}/PPID: {4}/POffset: 0x{5:08x}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( eprocess.CreateTime.v(), eprocess.ExitTime.v(), eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.obj_offset) pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName yield line # Get Sockets and Evtlogs XP/2k3 only if addr_space.profile.metadata.get('major', 0) == 5: socks = sockets.Sockets(self._config).calculate() #socks = sockscan.SockScan(self._config).calculate() # you can use sockscan instead if you uncomment for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) if not body: line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format( sock.CreateTime, sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) else: line = "0|[SOCKET] PID: {1}/LocalIP: {2}/Protocol: {3}({4})/POffset: 0x{5:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( sock.CreateTime.v(), sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) yield line stuff = evtlogs.EvtLogs.calculate(self) for name, buf in stuff: for fields in self.parse_evt_info(name, buf, rawtime = True): if not body: line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format( fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) else: line = "0|[EVT LOG] {1}/{2}/{3}/{4}/{5}/{6}/{7}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( fields[0].v(),fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) yield line else: # Vista+ nets = netscan.Netscan(self._config).calculate() for net_object, proto, laddr, lport, raddr, rport, state in nets: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) if not body: line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format( str(net_object.CreateTime or "-1"), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) else: line = "0|[NETWORK CONNECTION] {1}/{2}/{3}/{4}/{5:<#10x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( net_object.CreateTime.v(), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) yield line # Get threads threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") if not body: line = "{0}|[THREAD]|{1}|{2}|{3}|{4}|||\n".format( thread.CreateTime or '-1', image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, thread.ExitTime or '', ) else: line = "0|[THREAD] {2}/PID: {3}/TID: {4}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( thread.CreateTime.v(), thread.ExitTime.v(), image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, ) yield line # now we get to the PE part. All PE's are dumped in case you want to inspect them later data = moddump.ModDump(self._config).calculate() for addr_space, procs, mod_base, mod_name in data: space = tasks.find_space(addr_space, procs, mod_base) if space != None: try: header = procdump.ProcExeDump(self._config).get_nt_header(space, mod_base) except ValueError, ve: continue try: if not body: line = "{0}|[PE Timestamp (module)]|{1}||{2:#010x}|||||\n".format( header.FileHeader.TimeDateStamp or '-1', mod_name, mod_base) else: line = "0|[PE Timestamp (module)] {1}/Base: {2:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( header.FileHeader.TimeDateStamp.v(), mod_name, mod_base) except ValueError, ve: if not body: line = "-1|[PE Timestamp (module)]|{0}||{1}|||||\n".format( mod_name, mod_base) else: line = "0|[PE Timestamp (module)] {0}/Base: {1:#010x}|0|---------------|0|0|0|0|0|0|0\n".format( mod_name, mod_base) yield line
def calculate(self): if self._config.OUTPUT == "xlsx" and not has_openpyxl: debug.error( "You must install OpenPyxl for xlsx format:\n\thttps://bitbucket.org/ericgazoni/openpyxl/wiki/Home" ) elif self._config.OUTPUT == "xlsx" and not self._config.OUTPUT_FILE: debug.error( "You must specify an output *.xlsx file!\n\t(Example: --output-file=OUTPUT.xlsx)" ) if (self._config.HIVE or self._config.USER) and not (self._config.REGISTRY): debug.error( "You must use -R/--registry in conjuction with -H/--hive and/or -U/--user" ) addr_space = utils.load_as(self._config) version = (addr_space.profile.metadata.get('major', 0), addr_space.profile.metadata.get('minor', 0)) pids = {} #dictionary of process IDs/ImageFileName offsets = [] #process offsets im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) body = False if self._config.OUTPUT == "body": body = True if not body: event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime']) else: event = "0|[END LIVE RESPONSE]|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( im['ImageDatetime'].v()) yield event # Get EPROCESS psscan = filescan.PSScan(self._config).calculate() for eprocess in psscan: if eprocess.obj_offset not in offsets: offsets.append(eprocess.obj_offset) if not body: line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format( eprocess.CreateTime or '-1', "[PROCESS]", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime or '', eprocess.obj_offset) else: line = "0|[PROCESS] {2}/PID: {3}/PPID: {4}/POffset: 0x{5:08x}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( eprocess.CreateTime.v(), eprocess.ExitTime.v(), eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.obj_offset) pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName yield line # Get Sockets and Evtlogs XP/2k3 only if addr_space.profile.metadata.get('major', 0) == 5: socks = sockets.Sockets(self._config).calculate() #socks = sockscan.SockScan(self._config).calculate() # you can use sockscan instead if you uncomment for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) if not body: line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format( sock.CreateTime, sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) else: line = "0|[SOCKET] PID: {1}/LocalIP: {2}/Protocol: {3}({4})/POffset: 0x{5:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( sock.CreateTime.v(), sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) yield line evt = evtlogs.EvtLogs(self._config) stuff = evt.calculate() for name, buf in stuff: for fields in evt.parse_evt_info(name, buf, rawtime=True): if not body: line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format( fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) else: line = "0|[EVT LOG] {1}/{2}/{3}/{4}/{5}/{6}/{7}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( fields[0].v(), fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) yield line else: # Vista+ nets = netscan.Netscan(self._config).calculate() for net_object, proto, laddr, lport, raddr, rport, state in nets: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) if not body: line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format( str(net_object.CreateTime or "-1"), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) else: line = "0|[NETWORK CONNECTION] {1}/{2}/{3}/{4}/{5:<#10x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( net_object.CreateTime.v(), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) yield line # Get threads threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") if not body: line = "{0}|[THREAD]|{1}|{2}|{3}|{4}|||\n".format( thread.CreateTime or '-1', image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, thread.ExitTime or '', ) else: line = "0|[THREAD] {2}/PID: {3}/TID: {4}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( thread.CreateTime.v(), thread.ExitTime.v(), image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, ) yield line # now we get to the PE part. All PE's are dumped in case you want to inspect them later data = moddump.ModDump(self._config).calculate() for addr_space, procs, mod_base, mod_name in data: mod_name = str(mod_name or '') space = tasks.find_space(addr_space, procs, mod_base) if space != None: try: header = procdump.ProcExeDump(self._config).get_nt_header( space, mod_base) except ValueError, ve: continue try: if not body: line = "{0}|[PE Timestamp (module)]|{1}||{2:#010x}|||||\n".format( header.FileHeader.TimeDateStamp or '-1', mod_name, mod_base) else: line = "0|[PE Timestamp (module)] {1}/Base: {2:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( header.FileHeader.TimeDateStamp.v(), mod_name, mod_base) except ValueError, ve: if not body: line = "-1|[PE Timestamp (module)]|{0}||{1}|||||\n".format( mod_name, mod_base) else: line = "0|[PE Timestamp (module)] {0}/Base: {1:#010x}|0|---------------|0|0|0|0|0|0|0\n".format( mod_name, mod_base) yield line
def calculate(self): """ TODO """ self.addr_space = utils.load_as(self._config) if self._config.PID: pids = self._config.PID.split(',') log_file = None if self._config.LOGFILE: log_file = open(self._config.LOGFILE, "w+") # Modules on user space for task in tasks.pslist(self.addr_space): if (not self._config.PID) or (str(task.UniqueProcessId) in pids): task_space = task.get_process_address_space() for mod in task.get_load_modules(): count_valid_pages = 0 _list = [] for i in range(0, mod.SizeOfImage, PAGE_SIZE): if task_space.is_valid_address(mod.DllBase + i): count_valid_pages += 1 _list.append([ mod.DllBase + i, task_space.vtop(mod.DllBase + i) ]) dump_file = None if self._config.DUMP_DIR: if not os.path.exists(self._config.DUMP_DIR): os.makedirs(self._config.DUMP_DIR) # Create dump_file dump_file = os.path.join( self._config.DUMP_DIR, '{0}-{1}-{2}.csv'.format(task.ImageFileName, task.UniqueProcessId, mod.BaseDllName.v())) self.write_to_file(dump_file, _list) total_pages = mod.SizeOfImage / PAGE_SIZE if log_file: baseDllName = (mod.BaseDllName.v()) if type(baseDllName) == obj.NoneObject: baseDllName = '-----' fullDllName = mod.FullDllName.v() if type(fullDllName) == obj.NoneObject: fullDllName = '-----' log_file.write('\t'.join( (str(task.UniqueProcessId), str(task.ImageFileName), baseDllName, str(mod.DllBase.v()), str(count_valid_pages), str(total_pages), fullDllName)) + '\n') version = obj.Object("_IMAGE_DOS_HEADER", mod.DllBase, task_space).get_version_info() yield (task.UniqueProcessId, task.ImageFileName, mod.BaseDllName.v(), mod.DllBase.v(), count_valid_pages, total_pages, mod.FullDllName.v(), dump_file, version.FileInfo.file_version() if version else '') # Drivers -- part of this code is inspired in moddump plugin mods = dict( (mod.DllBase.v(), mod) for mod in modules.lsmod(self.addr_space)) procs = list(tasks.pslist(self.addr_space)) for mod in mods.values(): mod_base = mod.DllBase.v() space = tasks.find_space(self.addr_space, procs, mod_base) count_valid_pages = 0 _list = [] if space != None: # check if we have retrieved the correct AS # when no retrieved, paged memory pages will be equal to the total pages for i in range(0, mod.SizeOfImage, PAGE_SIZE): if space.is_valid_address(mod.DllBase + i): count_valid_pages += 1 _list.append( [mod.DllBase + i, space.vtop(mod.DllBase + i)]) dump_file = None if self._config.DUMP_DIR: if not os.path.exists(self._config.DUMP_DIR): os.makedirs(self._config.DUMP_DIR) # Create dump_file dump_file = os.path.join( self._config.DUMP_DIR, 'drv_{}.csv'.format(mod.BaseDllName.v())) self.write_to_file(dump_file, _list) total_pages = mod.SizeOfImage / PAGE_SIZE if log_file: log_file.write('\t'.join( ('--', '--', str(mod.BaseDllName.v()), str(mod.DllBase.v()), str(count_valid_pages), str(total_pages), str(mod.FullDllName.v()))) + '\n') version = obj.Object("_IMAGE_DOS_HEADER", mod.DllBase, task_space).get_version_info() yield ('--', '--', mod.BaseDllName.v(), mod.DllBase.v(), count_valid_pages, total_pages, mod.FullDllName.v(), dump_file, version.FileInfo.file_version() if version else '') if self._config.LOGFILE: log_file.close()