Ejemplo n.º 1
0
    def calculate(self):
        ## Select the tags to scan for. Always find visited URLs,
        ## but make freed and redirected records optional.
        tags = ["URL "]
        if self._config.LEAK:
            tags.append("LEAK")
        if self._config.REDR:
            tags.append("REDR")

        ## Define the record type based on the tag
        tag_records = {
            "URL ": "_URL_RECORD",
            "LEAK": "_URL_RECORD",
            "REDR": "_REDR_RECORD"
        }

        ## Enumerate processes based on the --pid and --offset
        for proc in taskmods.DllList(self._config).calculate():

            ## Acquire a process specific AS
            ps_as = proc.get_process_address_space()

            for hit in proc.search_process_memory(tags):
                ## Get a preview of the data to see what tag was detected
                tag = ps_as.read(hit, 4)

                ## Create the appropriate object type based on the tag
                record = obj.Object(tag_records[tag], offset=hit, vm=ps_as)
                if record.is_valid():
                    yield proc, record
Ejemplo n.º 2
0
    def calculate(self):
        ## Select the tags to scan for. Always find visited URLs,
        ## but make freed and redirected records optional.
        tags = ["URL ", "DEST"]
        if self._config.LEAK:
            tags.append("LEAK")
        if self._config.REDR:
            tags.append("REDR")

        ## Define the record type based on the tag
        tag_records = {
            "URL ": "_URL_RECORD",
            "LEAK": "_URL_RECORD",
            "REDR": "_REDR_RECORD",
            "DEST": "_DEST_RECORD"
        }

        vad_filter = lambda x: (hasattr(x, 'ControlArea') and str(
            x.FileObject.FileName or '').endswith("index.dat")) or (
                x.VadFlags.Protection.v() == 4)

        ## Enumerate processes based on the --pid and --offset
        for proc in taskmods.DllList(self._config).calculate():

            ## Acquire a process specific AS
            ps_as = proc.get_process_address_space()

            for hit in proc.search_process_memory(tags, vad_filter=vad_filter):
                ## Get a preview of the data to see what tag was detected
                tag = ps_as.read(hit, 4)

                ## Create the appropriate object type based on the tag
                record = obj.Object(tag_records[tag], offset=hit, vm=ps_as)
                if record.is_valid():
                    yield proc, record
Ejemplo n.º 3
0
    def calculate(self):
        thread_start_module = None
        thread_start_function = None
        # Checks that subclass AbstractThreadCheck
        checks = registry.get_plugin_classes(threads.AbstractThreadCheck)

        addr_space = utils.load_as(self._config)

        # Are we on x86 or x64. Save this for render_text
        self.bits32 = addr_space.profile.metadata.\
            get("memory_model", "32bit") == "32bit"

        seen_threads = dict()

        # Gather threads by list traversal of active/linked processes
        for task in taskmods.DllList(self._config).calculate():
            for thread in task.ThreadListHead.\
                    list_of_type("_ETHREAD", "ThreadListEntry"):
                seen_threads[thread.obj_vm.vtop(thread.obj_offset)] = (False,
                                                                       thread)

        # Now scan for threads and save any that haven't been seen
        for thread in modscan.ThrdScan(self._config).calculate():
            if not seen_threads.has_key(thread.obj_offset):
                seen_threads[thread.obj_offset] = (True, thread)

        # Keep a record of processes whose DLLs we've already enumerated
        process_dll_info = {}

        for _offset, (found_by_scanner, thread) in seen_threads.items():
            if self.pidlist:
                if not thread.attached_process(
                ).UniqueProcessId in self.pidlist:
                    continue
            thread_callstack = parse_callstack(thread, self.bits32,
                                               self._config)

            yield thread, addr_space, \
                        thread_start_function, thread_callstack
Ejemplo n.º 4
0
    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 "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))

        detections = False
        if self._config.OUTPUT == "xlsx" and self._config.HIGHLIGHT != None:
            detections = True

        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)".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 detections and "Process" in self._config.TYPE:
                injected = False
                for vad, address_space in eprocess.get_vads(
                        vad_filter=eprocess._injection_filter):

                    if malfind.Malfind(self._config)._is_vad_empty(
                            vad, address_space):
                        continue

                    line = "PID: {0}/PPID: {1}/POffset: 0x{2:08x}".format(
                        eprocess.UniqueProcessId,
                        eprocess.InheritedFromUniqueProcessId, offset)
                    self.suspicious[line.strip()] = {
                        "reason": "MALFIND",
                        "color": "RED"
                    }
                    self.suspiciouspids[eprocess.UniqueProcessId.v()] = {
                        "reason": "MALFIND",
                        "color": "RED"
                    }
                    injected = True

                proc_okay = False
                if not injected and (eprocess.ExitTime.v() > 0
                                     or str(eprocess.ImageFileName).lower()
                                     in ["system", "smss.exe", "csrss.exe"]):
                    proc_okay = True
                elif not injected and ps_sources['psscan'].has_key(offset) and (not ps_sources['pslist'].has_key(offset) or not \
                    ps_sources['thrdproc'].has_key(offset) or not ps_sources['pspcid'].has_key(offset) or not \
                    ps_sources['csrss'].has_key(offset) or not ps_sources['session'].has_key(offset) or not \
                    ps_sources['deskthrd'].has_key(offset)):
                    proc_okay = True
                if not proc_okay and (not ps_sources['pslist'].has_key(offset) or not ps_sources['psscan'].has_key(offset) or not ps_sources['thrdproc'].has_key(offset) \
                    or not ps_sources['pspcid'].has_key(offset) or not ps_sources['csrss'].has_key(offset) or not ps_sources['session'].has_key(offset) \
                    or not ps_sources['deskthrd'].has_key(offset)):
                    if self.suspicious.get(line.strip(),
                                           {}).get("reason", None) == None:
                        self.suspicious[line.strip()] = {
                            "reason": "PSXVIEW",
                            "color": "RED"
                        }
                        self.suspiciouspids[eprocess.UniqueProcessId.v()] = {
                            "reason": "PSXVIEW",
                            "color": "RED"
                        }
                    else:
                        self.suspicious[line.strip()] = {
                            "reason": "MALFIND and PSXVIEW",
                            "color": "RED"
                        }
                        self.suspiciouspids[eprocess.UniqueProcessId.v()] = {
                            "reason": "MALFIND and PSXVIEW",
                            "color": "RED"
                        }

            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, 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 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.TimeDateStamp,
                                         end=mod.LoadTime,
                                         body=body)
                if detections and eprocess.UniqueProcessId.v(
                ) in self.suspiciouspids.keys():
                    suspiciousline = "Process: {0}/PID: {1}/PPID: {2}/Process POffset: 0x{3:08x}/DLL Base: 0x{4:08x}".format(
                        eprocess.ImageFileName, eprocess.UniqueProcessId,
                        eprocess.InheritedFromUniqueProcessId, offset,
                        mod.DllBase.v())
                    self.suspicious[suspiciousline] = {
                        "reason":
                        "Process flagged: " + self.suspiciouspids[
                            eprocess.UniqueProcessId.v()]["reason"],
                        "color":
                        "BLUE"
                    }
Ejemplo n.º 5
0
    def render_text(self, outfd, data):
        mal_ids = []
        for mal_process, addr, magic_keyword, encrypted, decrypted, os_version in data:
            outfd.write("Gh0stRat Variant: {0}\n".format(magic_keyword))
            for proc in mal_process:
                outfd.write("Malicious Process: {0}(pid:{1})\n".format(
                    proc, str(mal_process[proc])))
                mal_ids.append((proc, mal_process[proc]))

            outfd.write("Gh0strat Encrypted Communicaton:\n")
            outfd.write("-" * 78 + "\n")
            outfd.write("".join([
                "{0:#010x}  {1:<48}  {2}\n".format(addr + o, h, ''.join(c))
                for o, h, c in utils.Hexdump(encrypted)
            ]))
            outfd.write("\n")

            outfd.write("Decrypted Communication:\n")
            outfd.write("-" * 78 + "\n")
            outfd.write("".join([
                "{0:#010x}  {1:<48}  {2}\n".format(o, h, ''.join(c))
                for o, h, c in utils.Hexdump(decrypted)
            ]))
            outfd.write("\n")

        for proc, pid in list(set(mal_ids)):
            if os_version == 5:
                outfd.write(
                    "connections - Network Connections of Malicious Process:\n"
                )
                outfd.write("-" * 78 + "\n")
                net_con = Connections(self._config)
                net_connections = net_con.calculate()
                for tcp_obj in net_connections:
                    if tcp_obj.Pid == pid:
                        local = "{0}:{1}".format(tcp_obj.LocalIpAddress,
                                                 tcp_obj.LocalPort)
                        remote = "{0}:{1}".format(tcp_obj.RemoteIpAddress,
                                                  tcp_obj.RemotePort)
                        outfd.write("{0}\t{1}\t{2}(pid:{3})\n".format(
                            local, remote, proc, tcp_obj.Pid))
                outfd.write("\n")

                outfd.write(
                    "connscan - Network Connections of Malicious Process:\n")
                outfd.write("-" * 78 + "\n")
                net_scan = ConnScan(self._config)
                net_connscan = net_scan.calculate()
                for tcp_obj in net_connscan:
                    if tcp_obj.Pid == pid:
                        local = "{0}:{1}".format(tcp_obj.LocalIpAddress,
                                                 tcp_obj.LocalPort)
                        remote = "{0}:{1}".format(tcp_obj.RemoteIpAddress,
                                                  tcp_obj.RemotePort)
                        outfd.write("{0}\t{1}\t{2}(pid:{3})\n".format(
                            local, remote, proc, tcp_obj.Pid))
                outfd.write("\n")

            elif os_version == 6:
                outfd.write(
                    "netscan - Network Connections of Malicious Process({0} - pid:{1}):\n"
                    .format(proc, pid))
                outfd.write("-" * 78 + "\n")
                network = Netscan(self._config)
                net_data = network.calculate()
                outfd.write(
                    "{0:<10} {1:<8} {2:<30} {3:<20} {4:<16} {5:<8} {6:<14} {7}\n"
                    .format("Offset(P)", "Proto", "Local Address",
                            "Foreign Address", "State", "Pid", "Owner",
                            "Created"))

                for net_object, proto, laddr, lport, raddr, rport, state in net_data:
                    if net_object.Owner.UniqueProcessId == pid:
                        lendpoint = "{0}:{1}".format(laddr, lport)
                        rendpoint = "{0}:{1}".format(raddr, rport)
                        print(
                            "{0:<#10x} {1:<8} {2:<30} {3:<20} {4:<16} {5:<8} {6:<14} {7}\n"
                            .format(net_object.obj_offset, proto, lendpoint,
                                    rendpoint, state,
                                    net_object.Owner.UniqueProcessId,
                                    net_object.Owner.ImageFileName,
                                    str(net_object.CreateTime or '')))
                outfd.write("\n")

            outfd.write("DLL's Loaded by the Malicious Process:\n")
            outfd.write("-" * 78 + "\n")
            self._config.PID = str(pid)
            dl = taskmods.DllList(self._config)
            dldata = dl.calculate()
            dl.render_text(outfd, dldata)
Ejemplo n.º 6
0
    def calculate(self):
        if self._config.BASELINEIMG == None:
            print "Baseline image required!"
            sys.exit(-1)

        if self._config.ONLYKNOWN and self._config.ONLYUNKNOWN:
            print "Select only one of the options (-K, -U)!"
            sys.exit(-1)

        #######################################
        #Searching for processes in the baseline image
        ######################################
        # Saving original image
        orig_img = self._config.LOCATION
        # Setting up baseline image
        self._config.LOCATION = "file://" + self._config.BASELINEIMG

        addr_space = utils.load_as(self._config)
        dlllist = taskmods.DllList(self._config)

        for task in dlllist.calculate():
            if task.ProcessExiting != 0:  # We don't care about the exited processes
                continue

            proc = None

            if task.Peb == None:
                continue

            #if str(task.ImageFileName).lower() not in self.baseline_proc_list:
            if str(task.Peb.ProcessParameters.ImagePathName).lower(
            ) not in self.baseline_proc_list:
                # We haven't seen the process yet
                # Let's create a new object and add it
                proc = {
                    'pid': [],
                    'ppid': [],
                    'image':
                    str(task.ImageFileName).lower() or '',
                    'path':
                    str(task.Peb.ProcessParameters.ImagePathName).lower()
                    if task.Peb.ProcessParameters != None else '',
                    'cmd':
                    str(task.Peb.ProcessParameters.CommandLine).lower()
                    if task.Peb.ProcessParameters != None else '',
                    'offset': [],
                    'exited': [],
                    'dlls': {
                        'load': {},  # load list
                        'mem': {},  # mem list
                        'init': {},  # init list
                        'comb': {},  # combined list, contains all dlls
                        'vad': {}  # vad list
                    }
                }
                #self.baseline_proc_list[proc['image']] = proc
                self.baseline_proc_list[proc['path']] = proc

            # Get process from our list
            #proc = self.baseline_proc_list[str(task.ImageFileName).lower()]
            proc = self.baseline_proc_list[str(
                task.Peb.ProcessParameters.ImagePathName).lower()]

            proc['pid'].append(task.UniqueProcessId)
            proc['ppid'].append(task.InheritedFromUniqueProcessId)
            proc['offset'].append(task.obj_offset)

            for m in task.get_load_modules():
                mod = {
                    'dll': str(m.FullDllName).lower(),
                    'base': m.DllBase.v(),
                    'size': m.SizeOfImage or -1
                }

                if mod['dll'] not in proc['dlls']['load']:
                    proc['dlls']['load'][mod['dll']] = mod

                if mod['dll'] not in proc['dlls']['comb']:
                    proc['dlls']['comb'][mod['dll']] = mod

            for m in task.get_mem_modules():
                mod = {
                    'dll': str(m.FullDllName).lower(),
                    'base': m.DllBase.v(),
                    'size': m.SizeOfImage or -1
                }

                if mod['dll'] not in proc['dlls']['mem']:
                    proc['dlls']['mem'][mod['dll']] = mod

                if mod['dll'] not in proc['dlls']['comb']:
                    proc['dlls']['comb'][mod['dll']] = mod

            for m in task.get_init_modules():
                mod = {
                    'dll': str(m.FullDllName).lower(),
                    'base': m.DllBase.v(),
                    'size': m.SizeOfImage or -1
                }

                if mod['dll'] not in proc['dlls']['init']:
                    proc['dlls']['init'][mod['dll']] = mod

                if mod['dll'] not in proc['dlls']['comb']:
                    proc['dlls']['comb'][mod['dll']] = mod

            # Check VADs
            # Add only the missing modules
            for vad, address_space in task.get_vads(
                    vad_filter=task._mapped_file_filter):
                if obj.Object("_IMAGE_DOS_HEADER",
                              offset=vad.Start,
                              vm=address_space).e_magic != 0x5A4D:
                    continue
                mod = {
                    'dll': str(vad.FileObject.FileName or '').lower(),
                    'base': int(vad.Start),
                    'size': int(vad.Length)
                }

                if mod['dll'] not in proc['dlls']['vad']:
                    proc['dlls']['vad'][mod['dll']] = mod

                f = False
                for m in proc['dlls']['comb']:
                    if proc['dlls']['comb'][m]['base'] == mod['base']:
                        f = True
                if not f:
                    proc['dlls']['comb'][mod['dll']] = mod

        ####################################
        #Searching for processes in the image to be analyzed
        ##################################
        # Restoring original image
        self._config.LOCATION = orig_img

        addr_space = utils.load_as(self._config)
        dlllist = taskmods.DllList(self._config)

        for task in dlllist.calculate():
            if task.Peb == None:
                continue

            proc = {
                'pid':
                task.UniqueProcessId,
                'ppid':
                task.InheritedFromUniqueProcessId,
                'image':
                str(task.ImageFileName).lower(),
                'path':
                str(task.Peb.ProcessParameters.ImagePathName).lower()
                if task.Peb.ProcessParameters != None else '',
                'cmd':
                str(task.Peb.ProcessParameters.CommandLine).lower()
                if task.Peb.ProcessParameters != None else '',
                'offset':
                task.obj_offset,
                'dlls': {
                    'load': {},
                    'mem': {},
                    'init': {},
                    'comb': {},
                    'vad': {}
                }
            }

            for m in task.get_load_modules():
                mod = {
                    'dll': str(m.FullDllName).lower(),
                    'base': m.DllBase.v(),
                    'size': m.SizeOfImage or -1
                }
                proc['dlls']['load'][mod['dll']] = mod
                proc['dlls']['comb'][mod['dll']] = mod

            for m in task.get_mem_modules():
                mod = {
                    'dll': str(m.FullDllName).lower(),
                    'base': m.DllBase.v(),
                    'size': m.SizeOfImage or -1
                }
                proc['dlls']['mem'][mod['dll']] = mod
                if mod['dll'] not in proc['dlls']['comb']:
                    proc['dlls']['comb'][mod['dll']] = mod

            for m in task.get_init_modules():
                mod = {
                    'dll': str(m.FullDllName).lower(),
                    'base': m.DllBase.v(),
                    'size': m.SizeOfImage or -1
                }
                proc['dlls']['init'][mod['dll']] = mod
                if mod['dll'] not in proc['dlls']['comb']:
                    proc['dlls']['comb'][mod['dll']] = mod

            # Check the VADs
            # Add only the missing modules
            for vad, address_space in task.get_vads(
                    vad_filter=task._mapped_file_filter):
                if obj.Object("_IMAGE_DOS_HEADER",
                              offset=vad.Start,
                              vm=address_space).e_magic != 0x5A4D:
                    continue
                mod = {
                    'dll': str(vad.FileObject.FileName or '').lower(),
                    'base': int(vad.Start),
                    'size': int(vad.Length)
                }
                proc['dlls']['vad'][mod['dll']] = mod
                f = False
                for m in proc['dlls']['comb']:
                    if proc['dlls']['comb'][m]['base'] == mod['base']:
                        f = True
                if not f:
                    proc['dlls']['comb'][mod['dll']] = mod

            self.image_proc_list.append(proc)

        # Compare the lists
        for task in self.image_proc_list:  # Check all the processes in the image
            #if task['path'] != '':
            image = task['path']
            #else:
            #    image = task['image']
            p_found = False
            if image in self.baseline_proc_list:  # If the process is found
                task_bl = self.baseline_proc_list[image]
                p_found = True
                if self._config.VERBOSE:
                    for m in task['dlls']['comb']:
                        # Check if we have the dll in our combined list of the baseline
                        m_found = False
                        for m_bl in self.baseline_proc_list[image]['dlls'][
                                'comb']:
                            if task['dlls']['comb'][m]['dll'] == task_bl[
                                    'dlls']['comb'][m_bl]['dll']:
                                m_found = True

                        # Check in which lists we can find it in the baseline
                        m_l = False
                        for m_bl in self.baseline_proc_list[image]['dlls'][
                                'load']:
                            if task['dlls']['comb'][m]['dll'] == task_bl[
                                    'dlls']['load'][m_bl]['dll']:
                                m_l = True

                        m_i = False
                        for m_bl in self.baseline_proc_list[image]['dlls'][
                                'init']:
                            if task['dlls']['comb'][m]['dll'] == task_bl[
                                    'dlls']['init'][m_bl]['dll']:
                                m_i = True

                        m_m = False
                        for m_bl in self.baseline_proc_list[image]['dlls'][
                                'mem']:
                            if task['dlls']['comb'][m]['dll'] == task_bl[
                                    'dlls']['mem'][m_bl]['dll']:
                                m_m = True

                        # Check in which lists we can find it in our image
                        m_l_i = False
                        if task['dlls']['comb'][m]['dll'] in task['dlls'][
                                'load']:
                            m_l_i = True

                        m_i_i = False
                        if task['dlls']['comb'][m]['dll'] in task['dlls'][
                                'init']:
                            m_i_i = True

                        m_m_i = False
                        if task['dlls']['comb'][m]['dll'] in task['dlls'][
                                'mem']:
                            m_m_i = True

                        if not self._config.ONLYKNOWN and not self._config.ONLYUNKNOWN:
                            yield (task, m, p_found, m_found, m_l, m_i, m_m,
                                   m_l_i, m_i_i, m_m_i)

                        if self._config.ONLYKNOWN and m_found:
                            yield (task, m, p_found, m_found, m_l, m_i, m_m,
                                   m_l_i, m_i_i, m_m_i)

                        if self._config.ONLYUNKNOWN and not m_found:
                            yield (task, m, p_found, m_found, m_l, m_i, m_m,
                                   m_l_i, m_i_i, m_m_i)
                else:
                    if not self._config.ONLYKNOWN and not self._config.ONLYUNKNOWN:
                        yield (task, p_found)

                    if self._config.ONLYKNOWN and p_found:
                        yield (task, p_found)

                    if self._config.ONLYUNKNOWN and not p_found:
                        yield (task, p_found)

            else:  # The process is not in our baseline
                m_found = False
                if self._config.VERBOSE:
                    for m in task['dlls']['comb']:
                        m_l_i = False
                        if task['dlls']['comb'][m]['dll'] in task['dlls'][
                                'load']:
                            m_l_i = True

                        m_i_i = False
                        if task['dlls']['comb'][m]['dll'] in task['dlls'][
                                'init']:
                            m_i_i = True

                        m_m_i = False
                        if task['dlls']['comb'][m]['dll'] in task['dlls'][
                                'mem']:
                            m_m_i = True

                        if not self._config.ONLYKNOWN:
                            yield (task, m, p_found, m_found, False, False,
                                   False, m_l_i, m_i_i, m_m_i)
                else:
                    if not self._config.ONLYKNOWN:
                        yield (task, p_found)
Ejemplo n.º 7
0
    def calculate(self):

        if not has_distorm3:
            debug.warning("For best results please install distorm3")

        # Checks that subclass AbstractThreadCheck
        checks = registry.get_plugin_classes(AbstractThreadCheck)

        # If --listtags is chosen, just print the tags and return 
        if self._config.LISTTAGS:
            for cls_name, cls in checks.items():
                sys.stdout.write("{0:<20} {1}\n".format(cls_name, pydoc.getdoc(cls)))
            return

        addr_space = utils.load_as(self._config)
        system_range = tasks.get_kdbg(addr_space).MmSystemRangeStart.dereference_as("Pointer")

        # Only show threads owned by particular processes
        pidlist = []
        if self._config.PID:
            pidlist = [int(p) for p in self._config.PID.split(',')]
        elif self._config.OFFSET:
            process = self.virtual_process_from_physical_offset(addr_space, self._config.OFFSET)
            if process:
                pidlist = [int(process.UniqueProcessId)]

        # Get sorted list of kernel modules 
        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        # Are we on x86 or x64. Save this for render_text 
        self.bits32 = addr_space.profile.metadata.\
            get("memory_model", "32bit") == "32bit"

        # Get a list of hooked SSDTs but only on x86
        if self.bits32:
            hooked_tables = self.get_hooked_tables(addr_space)
        else:
            hooked_tables = None

        # Dictionary to store threads. Keys are physical offsets of
        # ETHREAD objects. Values are tuples, where the first item is
        # a boolean specifying if the object was found by scanning and
        # the second item is the actual ETHREAD object. 
        seen_threads = dict()

        # Gather threads by list traversal of active/linked processes 
        for task in taskmods.DllList(self._config).calculate():
            for thread in task.ThreadListHead.\
                    list_of_type("_ETHREAD", "ThreadListEntry"):
                seen_threads[thread.obj_vm.vtop(thread.obj_offset)] = (False, thread)

        # Now scan for threads and save any that haven't been seen
        for thread in modscan.ThrdScan(self._config).calculate():
            if not seen_threads.has_key(thread.obj_offset):
                seen_threads[thread.obj_offset] = (True, thread)

        # Keep a record of processes whose DLLs we've already enumerated
        process_dll_info = {}

        for _offset, (found_by_scanner, thread) in seen_threads.items():

            # Skip processes the user doesn't want to see
            if ((self._config.PID or self._config.OFFSET) and not pidlist) or (pidlist and thread.Cid.UniqueProcess not in pidlist):
                continue

            # Do we need to gather DLLs for module resolution 
            if addr_space.address_compare(thread.StartAddress, system_range) != -1:
                owner = tasks.find_module(mods, 
                                          mod_addrs, 
                                          addr_space.address_mask(thread.StartAddress))
            else:
                owning_process = thread.owning_process() 
                if not owning_process.is_valid(): 
                    owner = None
                else:
                    try:
                        user_mod_addrs, user_mods = process_dll_info[owning_process.obj_offset]
                    except KeyError:
                        user_mods = dict((addr_space.address_mask(mod.DllBase), mod) 
                                            for mod in owning_process.get_load_modules())
                        user_mod_addrs = sorted(user_mods.keys())
                        process_dll_info[owning_process.obj_offset] = (user_mod_addrs, user_mods)
                    owner = tasks.find_module(user_mods, 
                                              user_mod_addrs, 
                                              addr_space.address_mask(thread.StartAddress))
            
            if owner:
                owner_name = str(owner.BaseDllName or '')
            else:
                owner_name = "UNKNOWN"

            # Replace the dummy class with an instance 
            instances = dict(
                        (cls_name, cls(thread, mods, mod_addrs,
                            hooked_tables, found_by_scanner))
                        for cls_name, cls in checks.items()
                        )

            yield thread, addr_space, mods, mod_addrs, \
                        instances, hooked_tables, system_range, owner_name
Ejemplo n.º 8
0
    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, 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 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)
Ejemplo n.º 9
0
    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)