def update_proc_vad_info(self, proc_peb_info): """Builds a dictionary of process executable information from VAD""" self.proc_vad_info = {} for pid in proc_peb_info: self.proc_vad_info[pid] = [] proc = proc_peb_info[pid][0] if proc.Peb: # gets process information for the process executable from VAD and updates the dictionary for vad, addr_space in proc.get_vads( vad_filter=proc._mapped_file_filter): ext = "" vad_found = False if obj.Object("_IMAGE_DOS_HEADER", offset=vad.Start, vm=addr_space).e_magic != 0x5A4D: continue if str(vad.FileObject.FileName or ''): ext = os.path.splitext(str( vad.FileObject.FileName))[1].lower() if (ext == ".exe") or (vad.Start == proc.Peb.ImageBaseAddress): vad_filename = vad.FileObject.FileName vad_baseaddr = vad.Start vad_size = vad.End - vad.Start vad_protection = vadinfo.PROTECT_FLAGS.get( vad.VadFlags.Protection.v()) vad_tag = vad.Tag self.proc_vad_info[pid].extend([ str(vad_filename or ''), Address(vad_baseaddr), Hex(vad_size), str(vad_protection or ''), str(vad_tag or '') ]) vad_found = True break if vad_found == False: self.proc_vad_info[pid].extend( ["NA", Address(0), Hex(0), "NA", "NA"]) else: self.proc_vad_info[pid].extend( ["NoVAD", Address(0), Hex(0), "NoVAD", "NoVAD"])
def generator(self, data): for task in data: task_space = task.get_process_address_space() pagedata = task_space.get_available_pages() if pagedata: for p in pagedata: pa = task_space.vtop(p[0]) # pa can be 0, according to the old memmap, but can't == None(NoneObject) if pa != None: yield (0, [str(task.comm), int(task.pid), Address(p[0]), Address(pa), Address(p[1])]) #else: # outfd.write("0x{0:10x} 0x000000 0x{1:12x}\n".format(p[0], p[1])) else: yield(0, [str(task.comm), int(task.pid), Address(-1), Address(-1), Address(-1)])
def generator(self, data): for task in data: if task.mm.pgd == None: dtb = task.mm.pgd else: dtb = self.addr_space.vtop(task.mm.pgd) or task.mm.pgd yield (0, [ Address(task.obj_offset), str(task.comm), int(task.pid), str(task.uid) if task.uid else "-", str(task.gid) if task.gid else "-", Address(dtb), str(task.get_task_start_time()) ])
def generator(self, data): for task, vma in data: (fname, major, minor, ino, pgoff) = vma.info(task) yield (0, [ int(task.pid), Address(vma.vm_start), Address(vma.vm_end), str(vma.vm_flags), Address(pgoff), int(major), int(minor), int(ino), str(fname) ])
def generator(self, data): for driver in data: header = driver.get_object_header() yield ( 0, [ Address(driver.obj_offset), int(header.PointerCount), int(header.HandleCount), Address(driver.DriverStart), int(driver.DriverSize), str(driver.DriverExtension.ServiceKeyName or ''), str(header.NameInfo.Name or ''), str(driver.DriverName or ''), ], )
def generator(self, data): for dentry in data: yield ( 0, Address(dentry.obj_offset), str(dentry.get_partial_path()), )
def generator(self, data): for proc, ps_ad, mod_base, mod_name in data: if not ps_ad.is_valid_address(mod_base): result = "Error: DllBase is unavailable (possibly due to paging)" else: process_offset = ps_ad.vtop(proc.obj_offset) dump_file = "module.{0}.{1:x}.{2:x}.dll".format( proc.UniqueProcessId, process_offset, mod_base) result = self.dump_pe(ps_ad, mod_base, dump_file) yield (0, [ Address(proc.obj_offset), str(proc.ImageFileName), Address(mod_base), str(mod_name or ''), str(result) ])
def generator(self, data): for (shadowtbl_addr, func, op) in data: yield (0, [ str(func), Address(shadowtbl_addr), str(op), ])
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for proc in data: for th in proc.threads(): func_addr = th.continuation (module, handler_sym) = common.get_handler_name(kaddr_info, func_addr) if handler_sym: handler = handler_sym elif module: handler = module else: handler = proc.find_map_path(func_addr) yield ( 0, [ int(proc.p_pid), str(proc.p_comm), str(th.start_time()), int(th.sched_pri), Address(func_addr), str(handler), ], )
def generator(self, data): if self._config.DUMP_DIR and not os.path.isdir(self._config.DUMP_DIR): debug.error(self._config.DUMP_DIR + " is not a directory") for task in data: for vad, address_space in task.get_vads( vad_filter=task._injection_filter): if self._is_vad_empty(vad, address_space): continue content = address_space.zread(vad.Start, 64) yield (0, [ str(task.ImageFileName), int(task.UniqueProcessId), Address(vad.Start), str(vad.Tag), str( vadinfo.PROTECT_FLAGS.get(vad.VadFlags.Protection.v(), "")), str(vad.VadFlags), Bytes(content) ]) # Dump the data if --dump-dir was supplied if self._config.DUMP_DIR: filename = os.path.join( self._config.DUMP_DIR, "process.{0:#x}.{1:#x}.dmp".format( task.obj_offset, vad.Start)) self.dump_vad(filename, vad, address_space)
def generator(self, data): for mutant in data: header = mutant.get_object_header() if mutant.OwnerThread.is_valid(): thread = mutant.OwnerThread.dereference_as('_ETHREAD') CID = "{0}:{1}".format(thread.Cid.UniqueProcess, thread.Cid.UniqueThread) else: CID = "" yield (0, [Address(mutant.obj_offset), int(header.PointerCount), int(header.HandleCount), str(mutant.Header.SignalState), Address(mutant.OwnerThread), str(CID), str(header.NameInfo.Name or '')])
def generator(self, data): for (num, name, routine) in data: yield (0, [ str(num), str(name), Address(routine), ])
def generator(self, data): for task, vma, vma_file in data: (fname, major, minor, ino, pgoff) = vma.info(task) yield (0, [Address(task.obj_offset), int(task.pid), str(task.comm), Address(vma.vm_start), Address(vma.vm_end), str(vma.vm_flags), Address(pgoff), int(major), int(minor), int(ino), str(fname), str(vma_file["PAllocs"]), str(vma_file["FOffsets"])])
def generator(self, data): for offset, mft_entry, attributes in data: if not len(attributes): continue datnum = 0 for a, i in attributes: if i == None: attrdata = ["Invalid (" + a + ")", "", "", "", "", ""] elif a.startswith("STANDARD_INFORMATION"): attrdata = [a, str(i.CreationTime), str(i.ModifiedTime), str(i.MFTAlteredTime), str(i.FileAccessedTime), i.get_type()] elif a.startswith("FILE_NAME"): attrdata = [a, str(i.CreationTime), str(i.ModifiedTime), str(i.MFTAlteredTime), str(i.FileAccessedTime), i.remove_unprintable(i.get_name())] else: attrdata = [a, "", "", "", "", ""] yield (0, [Address(offset), str(mft_entry.get_mft_type()), int(mft_entry.RecordNumber), int(mft_entry.LinkCount)] + attrdata)
def generator(self, data): for kext in data: path = kext.path if path: path = str(path.dereference()) yield (0, [ Address(kext.kmod_info), Address(kext.kmod_info.address), str(kext.kmod_info.m("size")), str(kext.kmod_info.reference_count), str(kext.version), str(kext.kmod_info.name), str(path) ])
def generator(self, data): if self._config.DUMP_DIR and not os.path.isdir(self._config.DUMP_DIR): debug.error(self._config.DUMP_DIR + " is not a directory") for o, addr, hit, content in data: owner = "Owner: (Unknown Kernel Memory)" if o == None: filename = "kernel.{0:#x}.dmp".format(addr) elif o.obj_name == "_EPROCESS": owner = "{0}: (Pid {1})".format(o.ImageFileName, o.UniqueProcessId) filename = "process.{0:#x}.{1:#x}.dmp".format( o.obj_offset, addr) else: owner = "{0}".format(o.BaseDllName) filename = "kernel.{0:#x}.{1:#x}.dmp".format( o.obj_offset, addr) # Dump the data if --dump-dir was supplied if self._config.DUMP_DIR: path = os.path.join(self._config.DUMP_DIR, filename) fh = open(path, "wb") fh.write(content) fh.close() yield (0, [str(hit.rule), owner, Address(addr), Bytes(content)])
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for scope in data: cb = scope.ks_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) yield (0, [ Address(scope.v()), str(scope.ks_identifier), Address(scope.ks_idata), str(len([l for l in scope.listeners()])), Address(cb), str(module), str(handler_sym), ])
def generator(self, data): seen = [] for window_station in data: for desktop in window_station.desktops(): offset = desktop.PhysicalAddress if offset in seen: continue seen.append(offset) name = "{0}\\{1}".format(desktop.WindowStation.Name, desktop.Name) for thrd in desktop.threads(): yield (0, [ Address(offset), name, Hex(desktop.rpdeskNext.v()), int(desktop.dwSessionId), Hex(desktop.pDeskInfo.v()), int(desktop.DeskInfo.fsHooks), Hex(desktop.DeskInfo.spwnd), int(len(list(desktop.windows( desktop.DeskInfo.spwnd)))), Hex(desktop.pheapDesktop.v()), Hex(desktop.DeskInfo.pvDesktopLimit - desktop.DeskInfo.pvDesktopBase), Hex(desktop.DeskInfo.pvDesktopBase), Hex(desktop.DeskInfo.pvDesktopLimit), int(thrd.pEThread.Cid.UniqueThread), str(thrd.ppi.Process.ImageFileName), int(thrd.ppi.Process.UniqueProcessId), int(thrd.ppi.Process.InheritedFromUniqueProcessId) ])
def generator(self, data): for module in data: if not self._config.PHYSICAL_OFFSET: offset = module.obj_offset else: offset = module.obj_vm.vtop(module.obj_offset) yield ( 0, [ Address(offset), str(module.BaseDllName or ''), Address(module.DllBase), Hex(module.SizeOfImage), str(module.FullDllName or ''), ], )
def generator(self, data): profile = utils.load_as(self._config).profile # Get the OS version being analyzed version = ( profile.metadata.get('major', 0), profile.metadata.get('minor', 0), ) # Choose which USER handle enum to use if version >= (6, 1): handle_types = consts.HANDLE_TYPE_ENUM_SEVEN else: handle_types = consts.HANDLE_TYPE_ENUM for session in data: gahti = session.find_gahti() if gahti: for i, h in list(handle_types.items()): yield ( 0, [ str(session.SessionId), str(h), str(gahti.types[i].dwAllocTag), Address(gahti.types[i].fnDestroy), str(gahti.types[i].bObjectCreateFlags), ], )
def generator(self, data): for process, cert in data: if cert.obj_name == "_X509_PUBLIC_CERT": ext = ".crt" else: ext = ".key" if process: file_name = "{0}-{1:x}{2}".format(process.UniqueProcessId, cert.obj_offset, ext) else: file_name = "phys.{0:x}{1}".format(cert.obj_offset, ext) full_path = os.path.join(self._config.DUMP_DIR, file_name) with open(full_path, "wb") as cert_file: cert_file.write(cert.object_as_string()) parsed_subject = "" if self._config.SSL: openssl_string = cert.as_openssl(full_path) parsed_subject = '/'.join( [v[1] for v in self.get_parsed_fields(openssl_string)]) yield (0, [ int(process.UniqueProcessId if process else -1), str(process.ImageFileName if process else "-"), Address(cert.obj_offset), str(cert.obj_name), int(cert.Size), str(file_name), str(parsed_subject), Bytes(cert.object_as_string()) ])
def generator(self, data): for outer, inner, hook_addr, hooked in data: yield (0, [str(outer), str(inner), Address(hook_addr), str(hooked)])
def generator(self, data): if self._config.OBJECT_TYPE: object_list = [ s.lower() for s in self._config.OBJECT_TYPE.split(',') ] else: object_list = [] for pid, handle, object_type, name in data: if object_list and object_type.lower() not in object_list: continue if self._config.SILENT: if len(name.replace("'", "")) == 0: continue if not self._config.PHYSICAL_OFFSET: offset = handle.Body.obj_offset else: offset = handle.obj_vm.vtop(handle.Body.obj_offset) yield (0, [ Address(offset), int(pid), Hex(handle.HandleValue), Hex(handle.GrantedAccess), str(object_type), str(name) ])
def generator(self, data): for (good, filter, filter_name, filter_socket, member, ptr, module) in data: if good == 0: status = "UNKNOWN" else: status = "OK" yield (0, [ Address(filter.obj_offset), str(filter_name), str(member), Address(filter_socket), Address(ptr), str(module), str(status), ])
def generator(self, data): for task in data: # Walking the VAD tree can be done in kernel AS, but to # carve the actual data, we need a valid process AS. task_space = task.get_process_address_space() if not task_space: outfd.write("Unable to get process AS for {0}\n".format( task.UniqueProcessId)) continue # as a first step, we try to get the physical offset of the # _EPROCESS object using the process address space offset = task_space.vtop(task.obj_offset) # if this fails, we'll get its physical offset using kernel space if offset == None: offset = task.obj_vm.vtop(task.obj_offset) # if this fails we'll manually set the offset to 0 if offset == None: offset = 0 filter = lambda x: x.Length < self._config.MAX_SIZE for vad, _addrspace in task.get_vads(vad_filter=filter, skip_max_commit=True): if self._config.BASE and vad.Start != self._config.BASE: continue # Open the file and initialize the data vad_start = self.format_value(vad.Start, "[addrpad]") vad_end = self.format_value(vad.End, "[addrpad]") dump_file = "{0}.{1:x}.{2}-{3}.dmp".format( task.ImageFileName, offset, vad_start, vad_end) #PK path = os.path.join( self._config.DUMP_DIR, dump_file) path = self._config.DUMP_DIR result = self.dump_vad(path, dump_file, vad, task_space) yield (0, [ int(task.UniqueProcessId), str(task.ImageFileName), Address(vad.Start), Address(vad.End), str(result) ])
def generator(self, data): for (proc, map) in data: path = map.get_path() if path == "": path = map.get_special_path() yield ( 0, [ int(proc.p_pid), str(proc.p_comm), Address(map.links.start), Address(map.links.end), str(map.get_perms()), str(path), ], )
def generator(self, data): for task, mapping in data: yield (0, [ str(task.comm), int(task.pid), Address(mapping.l_addr), str(mapping.l_name) ])
def generator(self, data): for (sym_name, member, hook_type, sym_addr) in data: yield (0, [ str(sym_name), str(member), str(hook_type), Address(sym_addr) ])
def generator(self, data): for (task, fd, socket) in data: yield (0, [ str(task.p_comm), int(task.p_pid), int(fd), Address(socket), ])
def generator(self, data): for (_, table_name, i, call_addr, sym_name, _) in data: yield(0, [ str(table_name), int(i), Address(call_addr), str(sym_name), ])