コード例 #1
0
    def render_text(self, outfd, data):
        addr_space = utils.load_as(self._config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model', '32bit') == '32bit'

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            outfd.write("SSDT[{0}] at {1:x} with {2} entries\n".format(idx, table, n))
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory. 
                    syscall_addr = obj.Object('address', table + (i * 4), vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative. 
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number. 
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                outfd.write("  Entry {0:#06x}: {1:#x} ({2}) owned by {3}\n".format(idx * 0x1000 + i,
                                                                   syscall_addr,
                                                                   syscall_name,
                                                                   syscall_modname))

                ## check for inline hooks if in --verbose mode, we're analyzing
                ## an x86 model system and the sycall_mod is available 
                if (self._config.VERBOSE and 
                            addr_space.profile.metadata.get('memory_model', '32bit') == '32bit' and 
                            syscall_mod is not None):

                        ## leverage this static method from apihooks
                        ret = apihooks.ApiHooks.check_inline(va = syscall_addr, addr_space = vm, 
                                                mem_start = syscall_mod.DllBase, 
                                                mem_end = syscall_mod.DllBase + syscall_mod.SizeOfImage)
                        ## could not analyze the memory
                        if ret == None:
                            continue 
                        (hooked, data, dest_addr) = ret
                        ## the function isn't hooked
                        if not hooked:
                            continue 
                        ## we found a hook, try to resolve the hooker. no mask required because
                        ## we currently only work on x86 anyway
                        hook_mod = tasks.find_module(mods, mod_addrs, dest_addr)
                        if hook_mod: 
                            hook_name = hook_mod.BaseDllName
                        else:
                            hook_name = "UNKNOWN"
                        ## report it now 
                        outfd.write("  ** INLINE HOOK? => {0:#x} ({1})\n".format(dest_addr, hook_name))
コード例 #2
0
ファイル: ssdt.py プロジェクト: BryanSingh/volatility
    def render_text(self, outfd, data):
        addr_space = utils.load_as(self._config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model', '32bit') == '32bit'

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            outfd.write("SSDT[{0}] at {1:x} with {2} entries\n".format(idx, table, n))
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory. 
                    syscall_addr = obj.Object('address', table + (i * 4), vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative. 
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number. 
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                outfd.write("  Entry {0:#06x}: {1:#x} ({2}) owned by {3}\n".format(idx * 0x1000 + i,
                                                                   syscall_addr,
                                                                   syscall_name,
                                                                   syscall_modname))

                ## check for inline hooks if in --verbose mode, we're analyzing
                ## an x86 model system and the sycall_mod is available 
                if (self._config.VERBOSE and 
                            addr_space.profile.metadata.get('memory_model', '32bit') == '32bit' and 
                            syscall_mod is not None):

                        ## leverage this static method from apihooks
                        ret = apihooks.ApiHooks.check_inline(va = syscall_addr, addr_space = vm, 
                                                mem_start = syscall_mod.DllBase, 
                                                mem_end = syscall_mod.DllBase + syscall_mod.SizeOfImage)
                        ## could not analyze the memory
                        if ret == None:
                            continue 
                        (hooked, data, dest_addr) = ret
                        ## the function isn't hooked
                        if not hooked:
                            continue 
                        ## we found a hook, try to resolve the hooker. no mask required because
                        ## we currently only work on x86 anyway
                        hook_mod = tasks.find_module(mods, mod_addrs, dest_addr)
                        if hook_mod: 
                            hook_name = hook_mod.BaseDllName
                        else:
                            hook_name = "UNKNOWN"
                        ## report it now 
                        outfd.write("  ** INLINE HOOK? => {0:#x} ({1})\n".format(dest_addr, hook_name))
コード例 #3
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        modlist = list(modules.lsmod(addr_space))
        mods = dict(
            (addr_space.address_mask(mod.DllBase), mod) for mod in modlist)
        mod_addrs = sorted(mods.keys())

        drivers = dtree.DriverIrp(self._config).calculate()
        driver_name = "UNKNOWN"
        service_key = "UNKNOWN"
        driver_name3 = "UNKNOWN"
        module_name = "UNKNOWN"

        if self._config.ADDR:
            find_address = self._config.ADDR

            module_name = tasks.find_module(
                mods,
                mod_addrs,
                list(mods.values())[0].obj_vm.address_mask(find_address),
            )
            if module_name:
                module_name = (module_name.BaseDllName
                               or module_name.FullDllName)

            for driver in drivers:
                if (driver.DriverStart <= find_address <
                        driver.DriverStart + driver.DriverSize):
                    header = driver.get_object_header()
                    driver_name = header.NameInfo.Name
                    driver_name = str(driver.get_object_header().NameInfo.Name
                                      or '')
                    service_key = str(driver.DriverExtension.ServiceKeyName
                                      or '')
                    driver_name3 = str(driver.DriverName or '')
                    break

            yield (module_name, driver_name, service_key, driver_name3)

        else:
            for driver in drivers:
                driver_name = str(driver.get_object_header().NameInfo.Name
                                  or '')
                service_key = str(driver.DriverExtension.ServiceKeyName or '')
                driver_name3 = str(driver.DriverName or '')

                owning_module = tasks.find_module(
                    mods,
                    mod_addrs,
                    list(mods.values())[0].obj_vm.address_mask(
                        driver.DriverStart),
                )
                module_name = "UNKNOWN"
                if owning_module:
                    module_name = (owning_module.BaseDllName
                                   or owning_module.FullDllName)

                yield (module_name, driver_name, service_key, driver_name3)
コード例 #4
0
ファイル: ssdt.py プロジェクト: carmaa/volatility-2.2-python3
    def render_text(self, outfd, data):

        addr_space = utils.load_as(self._config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model', '32bit') == '32bit'

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            outfd.write("SSDT[{0}] at {1:x} with {2} entries\n".format(idx, table, n))
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory. 
                    syscall_addr = obj.Object('address', table + (i * 4), vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative. 
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number. 
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, syscall_addr)
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                outfd.write("  Entry {0:#06x}: {1:#x} ({2}) owned by {3}\n".format(idx * 0x1000 + i,
                                                                   syscall_addr,
                                                                   syscall_name,
                                                                   syscall_modname))
コード例 #5
0
ファイル: exportstack.py プロジェクト: binsrc/volatility-1
 def __init__(self, start, stack_base, stack_limit, eproc, modules=None, module_addrs=None, *args, **kwargs):
   EBP.__init__(self, start, stack_base, stack_limit, eproc, *args, **kwargs)
   if modules == None:
     self.modules = dict( (m.DllBase, m) for m in list(sysmods.lsmod(eproc.get_process_address_space())) + list(eproc.get_load_modules()) )
     self.module_addrs = sorted(self.modules.keys())
   else:
     self.modules = modules
     self.module_addrs = module_addrs
   mod = tasks.find_module(self.modules, self.module_addrs, self.eip)
   self.security_cookie = None
   self.cookie = None
   security_cookie_addr = None
   if mod != None:
     load_config = mod.get_load_config_directory()
     if load_config == None:
       # Attempt to use PDB symbols to locate this module's ___security_cookie
       addrs = eproc.lookup("{0}/.data!___security_cookie".format(str(mod.BaseDllName)))
       if len(addrs) > 0:
         security_cookie_addr = addrs[0]
     else:
       # Use _IMAGE_LOAD_CONFIG_DIRECTORY to locate this module's ___security_cookie
       security_cookie_addr = load_config.SecurityCookie
     if security_cookie_addr != None and self.addrspace.is_valid_address(security_cookie_addr):
       self.security_cookie = self.addrspace.read_long_phys(self.addrspace.vtop(security_cookie_addr))
     if self.addrspace.is_valid_address(self.ebp - self.alignment):
       self.cookie = self.addrspace.read_long_phys(self.addrspace.vtop(self.ebp - self.alignment))
コード例 #6
0
ファイル: memory.py プロジェクト: samanalysis/cuckoo
    def callbacks(self):
        """Volatility callbacks plugin.
        @see volatility/plugins/malware/callbacks.py
        """
        log.debug("Executing Volatility callbacks plugin on "
                  "{0}".format(self.memdump))

        self.__config()
        results = []

        command = self.plugins["callbacks"](self.config)
        for (sym, cb, detail), mods, mod_addrs in command.calculate():
            module = tasks.find_module(mods, mod_addrs,
                                       self.addr_space.address_mask(cb))

            if module:
                module_name = module.BaseDllName or module.FullDllName
            else:
                module_name = "UNKNOWN"

            new = {
                "type": str(sym),
                "callback": hex(int(cb)),
                "module": str(module_name),
                "details": str(detail or "-"),
            }

            results.append(new)

        return dict(config={}, data=results)
コード例 #7
0
ファイル: memory.py プロジェクト: NickyCM/cuckoo
    def callbacks(self):
        """Volatility callbacks plugin.
        @see volatility/plugins/malware/callbacks.py
        """
        results = []

        command = self.plugins["callbacks"](self.config)
        for (sym, cb, detail), mods, mod_addrs in command.calculate():
            module = tasks.find_module(mods, mod_addrs, self.addr_space.address_mask(cb))

            if module:
                module_name = module.BaseDllName or module.FullDllName
            else:
                module_name = "UNKNOWN"

            new = {
                "type": str(sym),
                "callback": hex(int(cb)),
                "module": str(module_name),
                "details": str(detail or "-"),
            }

            results.append(new)

        return dict(config={}, data=results)
コード例 #8
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        # Currently we only support x86. The x64 does still have a IDT
        # but hooking is prohibited and results in bugcheck.
        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")

        mods = dict((addr_space.address_mask(mod.DllBase), mod)
                    for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        for kpcr in tasks.get_kdbg(addr_space).kpcrs():
            # Get the GDT for access to selector bases
            gdt = dict((i * 8, sd) for i, sd in kpcr.gdt_entries())
            for i, entry in kpcr.idt_entries():
                # Where the IDT entry points.
                addr = entry.Address
                # Per MITRE, add the GDT selector  base if available.
                # This allows us to detect sneaky attempts to hook IDT
                # entries by changing the entry's GDT selector.
                gdt_entry = gdt.get(entry.Selector.v())
                if gdt_entry != None and "Code" in gdt_entry.Type:
                    addr += gdt_entry.Base

                # Lookup the function's owner
                module = tasks.find_module(mods, mod_addrs,
                                           addr_space.address_mask(addr))

                yield i, entry, addr, module
コード例 #9
0
    def render_text(self, outfd, data):

        self.table_header(
            outfd,
            [
                ("Type", "36"),
                ("Callback", "[addrpad]"),
                ("Module", "20"),
                ("Details", ""),
            ],
        )

        for (sym, cb, detail), mods, mod_addrs in data:

            module = tasks.find_module(
                mods, mod_addrs,
                list(mods.values())[0].obj_vm.address_mask(cb))

            ## The original callbacks plugin searched driver objects
            ## if the owning module isn't found (Rustock.B). We leave that
            ## task up to the user this time, and will be incoporating
            ## some different module association methods later.
            if module:
                module_name = module.BaseDllName or module.FullDllName
            else:
                module_name = "UNKNOWN"

            self.table_row(outfd, sym, cb, module_name, detail or "-")
コード例 #10
0
ファイル: sessions.py プロジェクト: 504ensicsLabs/DAMM
    def render_text(self, outfd, data):

        # Kernel AS for looking up modules 
        kernel_space = utils.load_as(self._config)

        # Modules sorted for address lookups 
        mods = dict((kernel_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(kernel_space))
        mod_addrs = sorted(mods.keys())

        for session in data:
            outfd.write("*" * 50 + "\n")
            outfd.write("Session(V): {0:x} ID: {1} Processes: {2}\n".format(
                session.obj_offset,
                session.SessionId,
                len(list(session.processes())),
                ))
            outfd.write("PagedPoolStart: {0:x} PagedPoolEnd {1:x}\n".format(
                session.PagedPoolStart,
                session.PagedPoolEnd,
                ))
            for process in session.processes():
                outfd.write(" Process: {0} {1} {2}\n".format(
                    process.UniqueProcessId,
                    process.ImageFileName,
                    process.CreateTime,
                    ))
            for image in session.images():
                module = tasks.find_module(mods, mod_addrs, kernel_space.address_mask(image.Address))
                outfd.write(" Image: {0:#x}, Address {1:x}, Name: {2}\n".format(
                    image.obj_offset,
                    image.Address,
                    str(module and module.BaseDllName or '')
                    ))
コード例 #11
0
ファイル: idt.py プロジェクト: RaptorFactor/volatility
    def calculate(self):
        addr_space = utils.load_as(self._config)

        # Currently we only support x86. The x64 does still have a IDT
        # but hooking is prohibited and results in bugcheck.
        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")

        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        for kpcr in tasks.get_kdbg(addr_space).kpcrs():
            # Get the GDT for access to selector bases
            gdt = dict((i * 8, sd) for i, sd in kpcr.gdt_entries())
            for i, entry in kpcr.idt_entries():
                # Where the IDT entry points.
                addr = entry.Address
                # Per MITRE, add the GDT selector  base if available.
                # This allows us to detect sneaky attempts to hook IDT
                # entries by changing the entry's GDT selector.
                gdt_entry = gdt.get(entry.Selector.v())
                if gdt_entry != None and "Code" in gdt_entry.Type:
                    addr += gdt_entry.Base

                # Lookup the function's owner
                module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(addr))

                yield i, entry, addr, module
コード例 #12
0
    def calculate(self):

        if not has_yara:
            debug.error(
                "Please install Yara from https://plusvic.github.io/yara/")

        addr_space = utils.load_as(self._config)

        rules = self._compile_rules()

        if self._config.KERNEL:

            # Find KDBG so we know where kernel memory begins. Do not assume
            # the starting range is 0x80000000 because we may be dealing with
            # an image with the /3GB boot switch.
            kdbg = tasks.get_kdbg(addr_space)

            start = kdbg.MmSystemRangeStart.dereference_as("Pointer")

            # Modules so we can map addresses to owners
            mods = dict((addr_space.address_mask(mod.DllBase), mod)
                        for mod in modules.lsmod(addr_space))
            mod_addrs = sorted(mods.keys())

            # There are multiple views (GUI sessions) of kernel memory.
            # Since we're scanning virtual memory and not physical,
            # all sessions must be scanned for full coverage. This
            # really only has a positive effect if the data you're
            # searching for is in GUI memory.
            sessions = []

            for proc in tasks.pslist(addr_space):
                sid = proc.SessionId
                # Skip sessions we've already seen
                if sid == None or sid in sessions:
                    continue

                session_space = proc.get_process_address_space()
                if session_space == None:
                    continue

                sessions.append(sid)
                scanner = DiscontigYaraScanner(address_space=session_space,
                                               rules=rules)

                for hit, address in scanner.scan(start_offset=start):
                    module = tasks.find_module(
                        mods, mod_addrs, addr_space.address_mask(address))
                    yield (module, address, hit,
                           session_space.zread(address - self._config.REVERSE,
                                               self._config.SIZE))

        else:
            for task in self.filter_tasks(tasks.pslist(addr_space)):
                scanner = VadYaraScanner(task=task, rules=rules)
                for hit, address in scanner.scan():
                    yield (task, address, hit,
                           scanner.address_space.zread(
                               address - self._config.REVERSE,
                               self._config.SIZE))
コード例 #13
0
ファイル: sessions.py プロジェクト: yangstars/spider
    def render_text(self, outfd, data):

        # Kernel AS for looking up modules
        kernel_space = utils.load_as(self._config)

        # Modules sorted for address lookups
        mods = dict((kernel_space.address_mask(mod.DllBase), mod)
                    for mod in modules.lsmod(kernel_space))
        mod_addrs = sorted(mods.keys())

        for session in data:
            outfd.write("*" * 50 + "\n")
            outfd.write("Session(V): {0:x} ID: {1} Processes: {2}\n".format(
                session.obj_offset,
                session.SessionId,
                len(list(session.processes())),
            ))
            outfd.write("PagedPoolStart: {0:x} PagedPoolEnd {1:x}\n".format(
                session.PagedPoolStart,
                session.PagedPoolEnd,
            ))
            for process in session.processes():
                outfd.write(" Process: {0} {1} {2}\n".format(
                    process.UniqueProcessId,
                    process.ImageFileName,
                    process.CreateTime,
                ))
            for image in session.images():
                module = tasks.find_module(
                    mods, mod_addrs, kernel_space.address_mask(image.Address))
                outfd.write(
                    " Image: {0:#x}, Address {1:x}, Name: {2}\n".format(
                        image.obj_offset, image.Address,
                        str(module and module.BaseDllName or '')))
コード例 #14
0
ファイル: devicetree.py プロジェクト: yangstars/spider
    def render_text(self, outfd, data):

        addr_space = utils.load_as(self._config)

        # Compile the regular expression for filtering by driver name
        if self._config.regex != None:
            mod_re = re.compile(self._config.regex, re.I)
        else:
            mod_re = None

        mods = dict((addr_space.address_mask(mod.DllBase), mod)
                    for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        bits = addr_space.profile.metadata.get('memory_model', '32bit')

        self.table_header(None, [('i', ">4"), ('Funcs', "36"),
                                 ('addr', '[addrpad]'), ('name', '')])

        for object_obj, driver_obj, _ in data:
            driver_name = str(object_obj.NameInfo.Name or '')
            # Continue if a regex was supplied and it doesn't match
            if mod_re != None:
                if not (mod_re.search(driver_name)
                        or mod_re.search(driver_name)):
                    continue

            # Write the standard header for each driver object
            outfd.write("{0}\n".format("-" * 50))
            outfd.write("DriverName: {0}\n".format(driver_name))
            outfd.write("DriverStart: {0:#x}\n".format(driver_obj.DriverStart))
            outfd.write("DriverSize: {0:#x}\n".format(driver_obj.DriverSize))
            outfd.write("DriverStartIo: {0:#x}\n".format(
                driver_obj.DriverStartIo))

            # Write the address and owner of each IRP function
            for i, function in enumerate(driver_obj.MajorFunction):
                function = driver_obj.MajorFunction[i]
                module = tasks.find_module(mods, mod_addrs,
                                           addr_space.address_mask(function))
                if module:
                    module_name = str(module.BaseDllName or '')
                else:
                    module_name = "Unknown"
                # This is where we check for inline hooks once the
                # ApiHooks plugin is ported to 2.1.
                self.table_row(outfd, i, MAJOR_FUNCTIONS[i], function,
                               module_name)

                if self._config.verbose:
                    data = addr_space.zread(function, 64)
                    outfd.write("\n".join([
                        "{0:#x} {1:<16} {2}".format(o, h, i)
                        for o, i, h in malfind.Disassemble(data=data,
                                                           start=function,
                                                           bits=bits,
                                                           stoponret=True)
                    ]))
                    outfd.write("\n")
コード例 #15
0
    def get_hooked_tables(self, addr_space):
        """This function finds SSDTs in an address space, checks
        if there are any hooked functions in the SSDTs, and returns
        a dictionary where SSDT base addresses are the keys and the
        values are lists of hooked function names.

        @param addr_space: a kernel address space. 
        """

        # Names of the legit executive modules for SSDT tables
        executive_modules = [
            # SSDT 0
            ["ntoskrnl.exe", "ntkrnlpa.exe", "ntkrnlmp.exe", "ntkrpamp.exe"],
            # SSDT 1
            ["win32k.sys"],
            # SSDT 2
            ["spud.sys"],
            # SSDT 3
            []
        ]

        syscalls = addr_space.profile.syscalls

        hooked_tables = {}

        for info in ssdt.SSDT(self._config).calculate():
            idx, table, n, vm, mods, mod_addrs = info
            # This is straight out of ssdt.py. Too bad there's no better way
            # to not duplicate code?
            for i in range(n):
                if self.bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object('address', table + (i * 4),
                                              vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs
                    # relative to the base of the table and can be negative.
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, syscall_addr)
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                if str(syscall_modname).lower() not in executive_modules[idx]:
                    fields = (i, syscall_name, syscall_addr, syscall_modname)
                    if table in hooked_tables:
                        hooked_tables[table].append(fields)
                    else:
                        hooked_tables[table] = [(fields)]

        return hooked_tables
コード例 #16
0
ファイル: devicetree.py プロジェクト: vortessence/vortessence
    def render_text(self, outfd, data):

        addr_space = utils.load_as(self._config)

        # Compile the regular expression for filtering by driver name 
        if self._config.regex != None:
            mod_re = re.compile(self._config.regex, re.I)
        else:
            mod_re = None

        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        bits = addr_space.profile.metadata.get('memory_model', '32bit')

        self.table_header(None, [('i', ">4"),
                                 ('Funcs', "36"),
                                 ('addr', '[addrpad]'),
                                 ('name', '')
                                 ])

        for driver in data:

            header = driver.get_object_header()

            driver_name = str(header.NameInfo.Name or '')
            # Continue if a regex was supplied and it doesn't match 
            if mod_re != None:
                if not (mod_re.search(driver_name) or
                        mod_re.search(driver_name)): continue

            # Write the standard header for each driver object 
            outfd.write("{0}\n".format("-" * 50))
            outfd.write("DriverName: {0}\n".format(driver_name))
            outfd.write("DriverStart: {0:#x}\n".format(driver.DriverStart))
            outfd.write("DriverSize: {0:#x}\n".format(driver.DriverSize))
            outfd.write("DriverStartIo: {0:#x}\n".format(driver.DriverStartIo))

            # Write the address and owner of each IRP function 
            for i, function in enumerate(driver.MajorFunction):
                function = driver.MajorFunction[i]
                module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(function))
                if module:
                    module_name = str(module.BaseDllName or '')
                else:
                    module_name = "Unknown"
                # This is where we check for inline hooks once the 
                # ApiHooks plugin is ported to 2.1. 
                self.table_row(outfd, i, MAJOR_FUNCTIONS[i], function, module_name)

                if self._config.verbose:
                    data = addr_space.zread(function, 64)
                    outfd.write("\n".join(
                        ["{0:#x} {1:<16} {2}".format(o, h, i)
                        for o, i, h in malfind.Disassemble(data = data, 
                            start = function, bits = bits, stoponret = True)
                    ]))
                    outfd.write("\n")
コード例 #17
0
ファイル: threads.py プロジェクト: BryanSingh/volatility
    def get_hooked_tables(self, addr_space):
        """This function finds SSDTs in an address space, checks
        if there are any hooked functions in the SSDTs, and returns
        a dictionary where SSDT base addresses are the keys and the
        values are lists of hooked function names.

        @param addr_space: a kernel address space. 
        """

        # Names of the legit executive modules for SSDT tables 
        executive_modules = [
            # SSDT 0
            ["ntoskrnl.exe", "ntkrnlpa.exe", "ntkrnlmp.exe", "ntkrpamp.exe"],
            # SSDT 1 
            ["win32k.sys"],
            # SSDT 2
            ["spud.sys"],
            # SSDT 3
            []]

        syscalls = addr_space.profile.syscalls

        hooked_tables = {}

        for info in ssdt.SSDT(self._config).calculate():
            idx, table, n, vm, mods, mod_addrs = info
            # This is straight out of ssdt.py. Too bad there's no better way 
            # to not duplicate code?
            for i in range(n):
                if self.bits32:
                    # These are absolute function addresses in kernel memory. 
                    syscall_addr = obj.Object('address', table + (i * 4), vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs 
                    # relative to the base of the table and can be negative. 
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number. 
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, syscall_addr)
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                if str(syscall_modname).lower() not in executive_modules[idx]:
                    fields = (i, syscall_name, syscall_addr, syscall_modname)
                    if hooked_tables.has_key(table):
                        hooked_tables[table].append(fields)
                    else:
                        hooked_tables[table] = [(fields)]

        return hooked_tables
コード例 #18
0
ファイル: threads.py プロジェクト: Jack47/volatility
    def check(self):
        """This check is True for system threads whose start address
        do not map back to known/loaded kernel drivers."""

        module = tasks.find_module(self.mods,
            self.mod_addrs, self.thread.StartAddress)

        return ('PS_CROSS_THREAD_FLAGS_SYSTEM' in self.flags and
                    module == None)
コード例 #19
0
    def check(self):
        """This check is True for system threads whose start address
        do not map back to known/loaded kernel drivers."""

        module = tasks.find_module(self.mods, self.mod_addrs,
                                   self.thread.StartAddress)

        return ('PS_CROSS_THREAD_FLAGS_SYSTEM' in self.flags
                and module == None)
コード例 #20
0
ファイル: ssdeepscan.py プロジェクト: xueyi28/volgui
    def calculate(self):

        if not has_pydeep:
            debug.error(
                "Please install ssdeep and pydeep from http://ssdeep.sourceforge.net/ and https://github.com/kbandla/pydeep"
            )

        addr_space = utils.load_as(self._config)
        self._addr_space = addr_space

        page_sig = self._pydeep_page()
        if page_sig == None:
            debug.error("Pydeep was not able to hash the input")

        if self._config.KERNEL:

            # Find KDBG so we know where kernel memory begins. Do not assume
            # the starting range is 0x80000000 because we may be dealing with
            # an image with the /3GB boot switch.
            kdbg = tasks.get_kdbg(addr_space)

            start = kdbg.MmSystemRangeStart.dereference_as("Pointer")

            # Modules so we can map addresses to owners
            mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space))
            mod_addrs = sorted(mods.keys())

            # There are multiple views (GUI sessions) of kernel memory.
            # Since we're scanning virtual memory and not physical,
            # all sessions must be scanned for full coverage. This
            # really only has a positive effect if the data you're
            # searching for is in GUI memory.
            sessions = []

            for proc in tasks.pslist(addr_space):
                sid = proc.SessionId
                # Skip sessions we've already seen
                if sid == None or sid in sessions:
                    continue

                session_space = proc.get_process_address_space()
                if session_space == None:
                    continue

                sessions.append(sid)
                scanner = DiscontigSSDeepScanner(address_space=session_space, rules=rules)

                for hit, address in scanner.scan(start_offset=start):
                    module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(address))
                    yield (module, address, hit, session_space.zread(address - self._config.REVERSE, self._config.SIZE))

        else:
            for task in self.filter_tasks(tasks.pslist(addr_space)):
                scanner = VadSSDeepScanner(task=task, pydeep_hash=page_sig)
                for sig, vStart, vLength, offset, alike in scanner.scan():
                    yield (task, sig, vStart, vLength, offset, alike, scanner.address_space.zread(offset, 0x1000))
コード例 #21
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        modlist = list(modules.lsmod(addr_space))
        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modlist)
        mod_addrs = sorted(mods.keys())
            
        drivers = dtree.DriverIrp(self._config).calculate()    
        driver_name = "UNKNOWN"
        service_key = "UNKNOWN"
        driver_name3 = "UNKNOWN"
        module_name = "UNKNOWN"

        if self._config.ADDR:
            find_address = self._config.ADDR
            
            module_name = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(find_address))
            if module_name:
                module_name = module_name.BaseDllName or module_name.FullDllName

            for driver in drivers:
                if driver.DriverStart <= find_address < driver.DriverStart + driver.DriverSize:
                    header = driver.get_object_header()
                    driver_name = header.NameInfo.Name
                    driver_name  = str(driver.get_object_header().NameInfo.Name or '') 
                    service_key = str(driver.DriverExtension.ServiceKeyName or '') 
                    driver_name3 = str(driver.DriverName or '') 
                    break
            
            yield (module_name, driver_name, service_key, driver_name3)

        else:                
            for driver in drivers:
                driver_name  = str(driver.get_object_header().NameInfo.Name or '')
                service_key = str(driver.DriverExtension.ServiceKeyName or '')
                driver_name3 = str(driver.DriverName or '')
                
                owning_module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(driver.DriverStart))
                module_name = "UNKNOWN"
                if owning_module:
                    module_name = owning_module.BaseDllName or owning_module.FullDllName

                yield (module_name, driver_name, service_key, driver_name3)
コード例 #22
0
ファイル: drivermodule.py プロジェクト: shiham101/volatility
    def calculate(self):
        addr_space = utils.load_as(self._config)

        modlist = list(modules.lsmod(addr_space))
        mods = dict(
            (addr_space.address_mask(mod.DllBase), mod) for mod in modlist)
        mod_addrs = sorted(mods.keys())

        drivers = dtree.DriverIrp(self._config).calculate()
        found_driver = "UNKNOWN"

        if self._config.ADDR:
            find_address = self._config.ADDR

            found_module = tasks.find_module(
                mods, mod_addrs,
                mods.values()[0].obj_vm.address_mask(find_address))
            if found_module:
                found_module = found_module.BaseDllName or found_module.FullDllName
            else:
                found_module = "UNKNOWN"

            for driver in drivers:
                if driver.DriverStart <= find_address < driver.DriverStart + driver.DriverSize:
                    header = driver.get_object_header()
                    found_driver = header.NameInfo.Name
                    break

            yield (found_module, found_driver)

        else:
            for driver in drivers:
                driver_name = driver.get_object_header().NameInfo.Name
                owning_module = tasks.find_module(
                    mods, mod_addrs,
                    mods.values()[0].obj_vm.address_mask(driver.DriverStart))

                if owning_module:
                    module_name = owning_module.BaseDllName or owning_module.FullDllName
                else:
                    module_name = "UNKNOWN"

                yield (module_name, driver_name)
コード例 #23
0
ファイル: callbacks.py プロジェクト: forensix-cn/DAMM
    def get_alloc(self, addr_space):
        '''
        Mimics volatility's PPP plugin.
        '''
        import volatility.plugins.malware.callbacks as callbacks
        import volatility.win32.tasks as tasks

        # for conn in connections.Connections(self.vol.config).calculate():
        vol_callback = callbacks.Callbacks(self.vol.config)
        for (sym, cb, detail), mods, mod_addrs in vol_callback.calculate():
            module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(cb))
            yield Callback(module, sym, cb, detail, 0)
コード例 #24
0
    def check(self):
        """This check is True for system threads whose start address
        do not map back to known/loaded kernel drivers."""

        # Take the address space from any module object
        addr_space = self.mods.values()[0].obj_vm

        module = tasks.find_module(self.mods,
            self.mod_addrs, addr_space.address_mask(self.thread.StartAddress))

        return ('PS_CROSS_THREAD_FLAGS_SYSTEM' in self.flags and
                    module == None)
コード例 #25
0
ファイル: malfind.py プロジェクト: Austi/volatility
    def calculate(self):

        if not has_yara:
            debug.error("Please install Yara from code.google.com/p/yara-project")

        addr_space = utils.load_as(self._config)

        rules = self._compile_rules()

        if self._config.KERNEL:

            # Find KDBG so we know where kernel memory begins. Do not assume
            # the starting range is 0x80000000 because we may be dealing with
            # an image with the /3GB boot switch. 
            kdbg = tasks.get_kdbg(addr_space)

            start = kdbg.MmSystemRangeStart.dereference_as("Pointer")

            # Modules so we can map addresses to owners
            mods = dict((addr_space.address_mask(mod.DllBase), mod)
                        for mod in modules.lsmod(addr_space))
            mod_addrs = sorted(mods.keys())

            # There are multiple views (GUI sessions) of kernel memory.
            # Since we're scanning virtual memory and not physical, 
            # all sessions must be scanned for full coverage. This 
            # really only has a positive effect if the data you're
            # searching for is in GUI memory. 
            sessions = []

            for proc in tasks.pslist(addr_space):
                sid = proc.SessionId
                # Skip sessions we've already seen 
                if sid == None or sid in sessions:
                    continue

                session_space = proc.get_process_address_space()
                if session_space == None:
                    continue

                sessions.append(sid)
                scanner = DiscontigYaraScanner(address_space = session_space,
                                               rules = rules)

                for hit, address in scanner.scan(start_offset = start):
                    module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(address))
                    yield (module, address, hit, session_space.zread(address, 1024))

        else:
            for task in self.filter_tasks(tasks.pslist(addr_space)):
                scanner = VadYaraScanner(task = task, rules = rules)
                for hit, address in scanner.scan():
                    yield (task, address, hit, scanner.address_space.zread(address, 1024))
コード例 #26
0
ファイル: drivermodule.py プロジェクト: Darriall/volatility
    def calculate(self):
        addr_space = utils.load_as(self._config)

        modlist = list(modules.lsmod(addr_space))
        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modlist)
        mod_addrs = sorted(mods.keys())
            
        drivers = dtree.DriverIrp(self._config).calculate()    
        found_driver = "UNKNOWN"

        if self._config.ADDR:
            find_address = self._config.ADDR
            
            found_module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(find_address))
            if found_module:
                found_module = found_module.BaseDllName or found_module.FullDllName
            else:
                found_module = "UNKNOWN"

            for driver in drivers:
                if driver.DriverStart <= find_address < driver.DriverStart + driver.DriverSize:
                    header = driver.get_object_header()
                    found_driver = header.NameInfo.Name
                    break
            
            yield (found_module, found_driver)

        else:                
            for driver in drivers:
                driver_name = driver.get_object_header().NameInfo.Name
                owning_module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(driver.DriverStart))

                if owning_module:
                    module_name = owning_module.BaseDllName or owning_module.FullDllName
                else:
                    module_name = "UNKNOWN"

                yield (module_name, driver_name)
コード例 #27
0
    def decide(analyzer, signatures):
        breach = False
        ioc_list = []

        rootkit_signatures = signatures.get("rootkits", {})

        entries = rootkit_signatures.get("entries", [])

        aux = analyzer.run_plugin("ssdt", "SSDT")
        config_obj = analyzer.get_config()

        addr_space = utils.load_as(config_obj)
        syscalls = addr_space.profile.syscalls

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in aux:
            for i in range(n):
                # These are absolute function addresses in kernel memory.
                syscall_addr = obj.Object('address', table + (i * 4), vm).v()

                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(
                    mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                # must match all values that are filled (empty values accept any)
                for entry in entries:
                    address = entry.get("address", syscall_addr)
                    name = entry.get("name", syscall_name)
                    module = entry.get("module", syscall_modname)

                    matches_rule = address == str(
                        hex(syscall_addr)) and name == str(
                            syscall_name) and module == str(syscall_modname)

                    if matches_rule:
                        ioc_list.append([
                            "-- Rootkits IoC --",
                            str(hex(syscall_addr)), syscall_name,
                            syscall_modname
                        ])

        return decision_tree.Decision(ioc_list, breach)
コード例 #28
0
ファイル: callbacks.py プロジェクト: idkwim/DAMM
    def get_alloc(self, addr_space):
        '''
        Mimics volatility's PPP plugin.
        '''
        import volatility.plugins.malware.callbacks as callbacks
        import volatility.win32.tasks as tasks

        # for conn in connections.Connections(self.vol.config).calculate():
        vol_callback = callbacks.Callbacks(self.vol.config)
        for (sym, cb, detail), mods, mod_addrs in vol_callback.calculate():
            module = tasks.find_module(
                mods, mod_addrs,
                mods.values()[0].obj_vm.address_mask(cb))
            yield Callback(module, sym, cb, detail, 0)
コード例 #29
0
    def execute(self, config):
        addr_space = utils.load_as(config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model',
                                                 '32bit') == '32bit'
        data = SSDTS.SSDT(config).calculate()
        sdtObjectList = datastructs.rootType()

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            sdtObject = sdtObjectList.SSDTs.SSDT.add()
            sdtObject.VirtAddr = table

            sdtEntries = sdtObject.SSDTEntries
            sdtEntries.count = n

            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object('address', table + (i * 4),
                                              vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative.
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(
                    mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                sdtEntry = sdtEntries.SSDTEntry.add()
                sdtEntry.FunctionName = adutils.SmartUnicode(syscall_name)
                sdtEntry.ModuleName = adutils.SmartUnicode(syscall_modname)
                sdtEntry.VirtAddr = int(syscall_addr)

        sdtsfile = open(config.OUTPUT_PATH + "sdts.xml", "w")
        #sdtsfile.write(sdtObjectList.SerializeToString())
        sdtsfile.write(proto2xml(sdtObjectList, indent=0))

        logging.debug("Completed exporting the sdts on the system")
コード例 #30
0
    def _scan_kernel_memory(self, addr_space, rules):
        # Find KDBG so we know where kernel memory begins. Do not assume
        # the starting range is 0x80000000 because we may be dealing with
        # an image with the /3GB boot switch.
        kdbg = tasks.get_kdbg(addr_space)

        start = kdbg.MmSystemRangeStart.dereference_as("Pointer")

        # Modules so we can map addresses to owners
        mods = dict(
            (addr_space.address_mask(mod.DllBase), mod)
            for mod in modules.lsmod(addr_space)
        )
        mod_addrs = sorted(mods.keys())

        # There are multiple views (GUI sessions) of kernel memory.
        # Since we're scanning virtual memory and not physical,
        # all sessions must be scanned for full coverage. This
        # really only has a positive effect if the data you're
        # searching for is in GUI memory.
        sessions = []

        for proc in tasks.pslist(addr_space):
            sid = proc.SessionId
            # Skip sessions we've already seen
            if sid == None or sid in sessions:
                continue

            session_space = proc.get_process_address_space()
            if session_space == None:
                continue

            sessions.append(sid)
            scanner = DiscontigYaraScanner(
                address_space=session_space, rules=rules
            )

            for hit, address in scanner.scan(start_offset=start):
                module = tasks.find_module(
                    mods, mod_addrs, addr_space.address_mask(address)
                )
                yield (
                    module,
                    address - self._config.REVERSE,
                    hit,
                    session_space.zread(
                        address - self._config.REVERSE, self._config.SIZE
                    ),
                )
コード例 #31
0
ファイル: callbacks.py プロジェクト: vortessence/vortessence
    def generator(self, data):
        for (sym, cb, detail), mods, mod_addrs in data:

            module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(cb))

            ## The original callbacks plugin searched driver objects
            ## if the owning module isn't found (Rustock.B). We leave that 
            ## task up to the user this time, and will be incoporating 
            ## some different module association methods later. 
            if module:
                module_name = module.FullDllName or module.BaseDllName
            else:
                module_name = "UNKNOWN"

            yield (0, [str(sym), Address(cb), str(module_name), str(detail or "-")])
コード例 #32
0
ファイル: adsdts.py プロジェクト: r1nswenson/volatility
    def execute(self,config):
        addr_space = utils.load_as(config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model', '32bit') == '32bit'
        data = SSDTS.SSDT(config).calculate()
        sdtObjectList = datastructs.rootType()

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            sdtObject = sdtObjectList.SSDTs.SSDT.add()
            sdtObject.VirtAddr=table

            sdtEntries = sdtObject.SSDTEntries
            sdtEntries.count=n

            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object('address', table + (i * 4), vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative.
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                sdtEntry = sdtEntries.SSDTEntry.add()
                sdtEntry.FunctionName=adutils.SmartUnicode(syscall_name)
                sdtEntry.ModuleName=adutils.SmartUnicode(syscall_modname)
                sdtEntry.VirtAddr=int(syscall_addr)

        sdtsfile = open(config.OUTPUT_PATH + "sdts.xml", "w")
        #sdtsfile.write(sdtObjectList.SerializeToString())
        sdtsfile.write(proto2xml(sdtObjectList,indent=0))

        logging.debug("Completed exporting the sdts on the system")
コード例 #33
0
    def calculate(self):
        addr_space = utils.load_as(self._config)
        if addr_space.profile.metadata.get("memory_model", "") == "32bit":
            inc = 4
        else:
            inc = 8

        srv_module = self._get_srv(addr_space)
        if not srv_module:
            debug.error("Driver srv.sys not found.")
            return

        if not self._config.PDB_FILE:
            guid, pdb = self._get_debug_symbols(addr_space, srv_module)
            pdb_file = self._download_pdb_file(guid, pdb)
            if not pdb_file:
                debug.error(
                    "The pdb file could not be downloaded. Try it with the PDB_FILE option."
                )
                return
        else:
            pdb_file = self._config.PDB_FILE

        off_sym = self._get_srvtrans_symbol(pdb_file, srv_module.DllBase)

        if not off_sym:
            debug.error(
                "SrvTransaction2DispatchTable symbol address not found")
            return

        rva_sym = off_sym + srv_module.DllBase
        mods = dict((addr_space.address_mask(mod.DllBase), mod)
                    for mod in win32.modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        for i in range(17):
            if inc == 4:
                addr = struct.unpack("<I", addr_space.zread(rva_sym, inc))[0]
            else:
                addr = struct.unpack("<Q", addr_space.zread(rva_sym, inc))[0]

            module = tasks.find_module(mods, mod_addrs,
                                       addr_space.address_mask(addr))
            rva_sym += inc
            yield Address(addr), module
コード例 #34
0
    def render_text(self, outfd, data):

        outfd.write("{0}||{1}||{2}||{3}\n".format('Type', 'Callback', 'Module', 'Details'))

        for (sym, cb, detail), mods, mod_addrs in data:

            module = tasks.find_module(mods, mod_addrs, self.kern_space.address_mask(cb))

            ## The original callbacks plugin searched driver objects
            ## if the owning module isn't found (Rustock.B). We leave that 
            ## task up to the user this time, and will be incoporating 
            ## some different module association methods later. 
            if module:
                module_name = module.BaseDllName or module.FullDllName
            else:
                module_name = "UNKNOWN"

            outfd.write("{0}||{1:#x}||{2}||{3}\n".format(sym, cb, module_name, detail or "-" ))
コード例 #35
0
ファイル: rootkits.py プロジェクト: AlbertoRico/vol-o-matic
    def decide(analyzer, signatures):
        breach = False
        ioc_list = []

        rootkit_signatures = signatures.get("rootkits", {})

        entries = rootkit_signatures.get("entries", [])

        aux = analyzer.run_plugin("ssdt", "SSDT")
        config_obj = analyzer.get_config()

        addr_space = utils.load_as(config_obj)
        syscalls = addr_space.profile.syscalls

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in aux:
            for i in range(n):
                # These are absolute function addresses in kernel memory.
                syscall_addr = obj.Object('address', table + (i * 4), vm).v()

                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                # must match all values that are filled (empty values accept any)
                for entry in entries:
                    address = entry.get("address", syscall_addr)
                    name = entry.get("name", syscall_name)
                    module = entry.get("module", syscall_modname)

                    matches_rule = address == str(hex(syscall_addr)) and name == str(syscall_name) and module == str(syscall_modname)

                    if matches_rule:
                        ioc_list.append(["-- Rootkits IoC --", str(hex(syscall_addr)) , syscall_name, syscall_modname ])


        return decision_tree.Decision(ioc_list, breach)
コード例 #36
0
    def calculate(self):
        if not has_yara:
            debug.error(
                "Please install Yara from code.google.com/p/yara-project")
        addr_space = utils.load_as(self._config)
        rules = yara.compile(sources=ghost_sig)
        decrypted_data = None
        mal_proc = {}

        kdbg = tasks.get_kdbg(addr_space)
        start = kdbg.MmSystemRangeStart.dereference_as("Pointer")
        mods = dict((addr_space.address_mask(mod.DllBase), mod)
                    for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())
        sessions = []
        for proc in tasks.pslist(addr_space):
            sid = proc.SessionId

            if sid == None or sid in sessions:
                continue
            session_space = proc.get_process_address_space()
            if session_space == None:
                continue
            sessions.append(sid)
            scanner = malfind.DiscontigYaraScanner(address_space=session_space,
                                                   rules=rules)
            for hit, address in scanner.scan(start_offset=start):
                module = tasks.find_module(mods, mod_addrs,
                                           addr_space.address_mask(address))
                content = session_space.zread(address, 1024)
                header_size = content.find("\x78\x9c")
                magic_header_size = header_size - 8
                magic_keyword = content[:magic_header_size]
                comp_uncomp_size = content[magic_header_size:header_size]
                s = struct.Struct("I I")
                comp_size, uncomp_size = s.unpack(comp_uncomp_size)
                enc_data = content[0:comp_size]
                to_decrypt = content[header_size:comp_size]
                dec_data = self.decrypt_communication(to_decrypt)
                if not mal_proc:
                    self.get_ghost_process(magic_keyword, mal_proc, addr_space)
                    os_version = self.get_os_version(addr_space)
                yield (mal_proc, address, magic_keyword, enc_data, dec_data,
                       os_version)
コード例 #37
0
 def __init__(self,
              start,
              stack_base,
              stack_limit,
              eproc,
              modules=None,
              module_addrs=None,
              *args,
              **kwargs):
     EBP.__init__(self, start, stack_base, stack_limit, eproc, *args,
                  **kwargs)
     if modules == None:
         self.modules = dict(
             (m.DllBase, m) for m in
             list(sysmods.lsmod(eproc.get_process_address_space())) +
             list(eproc.get_load_modules()))
         self.module_addrs = sorted(self.modules.keys())
     else:
         self.modules = modules
         self.module_addrs = module_addrs
     mod = tasks.find_module(self.modules, self.module_addrs, self.eip)
     self.security_cookie = None
     self.cookie = None
     security_cookie_addr = None
     if mod != None:
         load_config = mod.get_load_config_directory()
         if load_config == None:
             # Attempt to use PDB symbols to locate this module's ___security_cookie
             addrs = eproc.lookup("{0}/.data!___security_cookie".format(
                 str(mod.BaseDllName)))
             if len(addrs) > 0:
                 security_cookie_addr = addrs[0]
         else:
             # Use _IMAGE_LOAD_CONFIG_DIRECTORY to locate this module's ___security_cookie
             security_cookie_addr = load_config.SecurityCookie
         if security_cookie_addr != None and self.addrspace.is_valid_address(
                 security_cookie_addr):
             self.security_cookie = self.addrspace.read_long_phys(
                 self.addrspace.vtop(security_cookie_addr))
         if self.addrspace.is_valid_address(self.ebp - self.alignment):
             self.cookie = self.addrspace.read_long_phys(
                 self.addrspace.vtop(self.ebp - self.alignment))
コード例 #38
0
ファイル: ghostrat.py プロジェクト: Alpha-10000/Volatility
    def calculate(self):
        if not has_yara:
            debug.error("Please install Yara from code.google.com/p/yara-project")
        addr_space = utils.load_as(self._config)
        rules = yara.compile(sources=ghost_sig)
        decrypted_data = None
        mal_proc = {}

        kdbg = tasks.get_kdbg(addr_space)
        start = kdbg.MmSystemRangeStart.dereference_as("Pointer")
        mods = dict((addr_space.address_mask(mod.DllBase), mod)
                        for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())
        sessions = []
        for proc in tasks.pslist(addr_space):
                sid = proc.SessionId

                if sid == None or sid in sessions:
                    continue
                session_space = proc.get_process_address_space()
                if session_space == None:
                    continue
                sessions.append(sid)
                scanner = malfind.DiscontigYaraScanner(address_space = session_space,
                                               rules = rules)
                for hit, address in scanner.scan(start_offset = start):
                    module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(address))
                    content = session_space.zread(address,1024)
                    header_size = content.find("\x78\x9c")
                    magic_header_size = header_size - 8
                    magic_keyword = content[:magic_header_size]
                    comp_uncomp_size = content[magic_header_size:header_size]
                    s = struct.Struct("I I")
                    comp_size, uncomp_size = s.unpack(comp_uncomp_size)
                    enc_data = content[0:comp_size]
                    to_decrypt = content[header_size:comp_size]
                    dec_data = self.decrypt_communication(to_decrypt)
                    if not mal_proc:
                        self.get_ghost_process(magic_keyword, mal_proc, addr_space)
                        os_version = self.get_os_version(addr_space)
                    yield (mal_proc, address, magic_keyword, enc_data, dec_data, os_version)
コード例 #39
0
ファイル: callbacks.py プロジェクト: tingyuwzq/volatility
    def generator(self, data):
        for (sym, cb, detail), mods, mod_addrs in data:

            module = tasks.find_module(
                mods, mod_addrs,
                mods.values()[0].obj_vm.address_mask(cb))

            ## The original callbacks plugin searched driver objects
            ## if the owning module isn't found (Rustock.B). We leave that
            ## task up to the user this time, and will be incoporating
            ## some different module association methods later.
            if module:
                module_name = module.BaseDllName or module.FullDllName
            else:
                module_name = "UNKNOWN"

            yield (0, [
                str(sym),
                Address(cb),
                str(module_name),
                str(detail or "-")
            ])
コード例 #40
0
ファイル: callbacks.py プロジェクト: BryanSingh/volatility
    def render_text(self, outfd, data):

        self.table_header(outfd,
                        [("Type", "36"),
                         ("Callback", "[addrpad]"),
                         ("Module", "20"),
                         ("Details", ""),
                        ])

        for (sym, cb, detail), mods, mod_addrs in data:

            module = tasks.find_module(mods, mod_addrs, mods.values()[0].obj_vm.address_mask(cb))

            ## The original callbacks plugin searched driver objects
            ## if the owning module isn't found (Rustock.B). We leave that 
            ## task up to the user this time, and will be incoporating 
            ## some different module association methods later. 
            if module:
                module_name = module.BaseDllName or module.FullDllName
            else:
                module_name = "UNKNOWN"

            self.table_row(outfd, sym, cb, module_name, detail or "-")
コード例 #41
0
ファイル: ssdt.py プロジェクト: olivierh59500/volatility
    def render_text(self, outfd, data):

        addr_space = utils.load_as(self._config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model',
                                                 '32bit') == '32bit'

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            outfd.write("SSDT[{0}] at {1:x} with {2} entries\n".format(
                idx, table, n))
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object('address', table + (i * 4),
                                              vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative.
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, syscall_addr)
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                outfd.write(
                    "  Entry {0:#06x}: {1:#x} ({2}) owned by {3}\n".format(
                        idx * 0x1000 + i, syscall_addr, syscall_name,
                        syscall_modname))
コード例 #42
0
    def _scan_kernel_memory(self, addr_space, rules):
        # Find KDBG so we know where kernel memory begins. Do not assume
        # the starting range is 0x80000000 because we may be dealing with
        # an image with the /3GB boot switch. 
        kdbg = tasks.get_kdbg(addr_space)

        start = kdbg.MmSystemRangeStart.dereference_as("Pointer")

        # Modules so we can map addresses to owners
        mods = dict((addr_space.address_mask(mod.DllBase), mod)
                    for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        # There are multiple views (GUI sessions) of kernel memory.
        # Since we're scanning virtual memory and not physical, 
        # all sessions must be scanned for full coverage. This 
        # really only has a positive effect if the data you're
        # searching for is in GUI memory. 
        sessions = []

        for proc in tasks.pslist(addr_space):
            sid = proc.SessionId
            # Skip sessions we've already seen 
            if sid == None or sid in sessions:
                continue

            session_space = proc.get_process_address_space()
            if session_space == None:
                continue

            sessions.append(sid)
            scanner = DiscontigYaraScanner(address_space = session_space,
                                           rules = rules)

            for hit, address in scanner.scan(start_offset = start):
                module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(address))
                yield (module, address - self._config.REVERSE, hit, session_space.zread(address - self._config.REVERSE, self._config.SIZE))
コード例 #43
0
ファイル: memory.py プロジェクト: samanalysis/cuckoo
    def ssdt(self):
        """Volatility ssdt plugin.
        @see volatility/plugins/malware/ssdt.py
        """
        log.debug("Executing Volatility ssdt plugin on "
                  "{0}".format(self.memdump))

        self.__config()
        results = []

        command = self.plugins["ssdt"](self.config)

        # Comment: this code is pretty much ripped from render_text in volatility.
        addr_space = utils.load_as(self.config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get("memory_model",
                                                 "32bit") == "32bit"

        for idx, table, n, vm, mods, mod_addrs in command.calculate():
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object("address", table + (i * 4),
                                              vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative.
                    offset = obj.Object("long", table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)

                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(
                    mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = "{0}".format(syscall_mod.BaseDllName)
                else:
                    syscall_modname = "UNKNOWN"

                new = {
                    "index": int(idx),
                    "table": hex(int(table)),
                    "entry": "{0:#06x}".format(idx * 0x1000 + i),
                    "syscall_name": syscall_name,
                    "syscall_addr": syscall_addr,
                    "syscall_modname": syscall_modname,
                }

                if bits32 and syscall_mod is not None:
                    ret = apihooks.ApiHooks.check_inline(
                        va=syscall_addr,
                        addr_space=vm,
                        mem_start=syscall_mod.DllBase,
                        mem_end=syscall_mod.DllBase + syscall_mod.SizeOfImage)

                    # Could not analyze the memory.
                    if ret is not None:
                        hooked, data, dest_addr = ret
                        if hooked:
                            # We found a hook, try to resolve the hooker.
                            # No mask required because we currently only work
                            # on x86 anyway.
                            hook_mod = tasks.find_module(
                                mods, mod_addrs, dest_addr)
                            if hook_mod:
                                hook_name = "{0}".format(hook_mod.BaseDllName)
                            else:
                                hook_name = "UNKNOWN"

                            # Report it now.
                            new.update({
                                "hook_dest_addr":
                                "{0:#x}".format(dest_addr),
                                "hook_name":
                                hook_name,
                            })

                results.append(new)

        return dict(config={}, data=results)
コード例 #44
0
ファイル: devicetree.py プロジェクト: vortessence/vortessence
    def get_json(self, data):
        results = {}

        addr_space = utils.load_as(self._config)

        # Compile the regular expression for filtering by driver name
        if self._config.regex != None:
            mod_re = re.compile(self._config.regex, re.I)
        else:
            mod_re = None

        mods = dict((mod.DllBase, mod) for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        bits = addr_space.profile.metadata.get('memory_model', '32bit')

        for driver in data:
            header = driver.get_object_header()

            driver_name = str(header.NameInfo.Name or '')

            # Continue if a regex was supplied and it doesn't match
            if mod_re != None:
                if not (mod_re.search(driver_name) or
                        mod_re.search(driver_name)): continue

            row = {'DriverName':driver_name,
                   'DriverStart':int(driver.DriverStart),
                   'DriverSize':int(driver.DriverSize),
                   'DriverStartIo':int(driver.DriverStartIo),
                   'IrpFunctions':[],
                   'Devices':[],
                   }

            # Write the address and owner of each IRP function
            for i, function in enumerate(driver.MajorFunction):
                function = driver.MajorFunction[i]
                module = tasks.find_module(mods, mod_addrs, function)
                irp = {'index':int(i),
                        'FunctionName':str(MAJOR_FUNCTIONS[i]),
                        'FunctionAddress':int(function),
                        'Disassembly':[]
                        }
                if module:
                    irp['BaseDllName'] = str(module.BaseDllName or '')
                else:
                    irp['BaseDllName'] = ''


                if self._config.verbose:
                    data = addr_space.zread(function, 64)
                    irp["Disassembly"] = [{'Address':int(o), "Bytes":str(h), "Instruction":str(i)}
                        for o, i, h in malfind.Disassemble(data = data,
                            start = function, bits = bits, stoponret = True)
                    ]
                row['IrpFunctions'].append(irp)

            for device in driver.devices():

                device_header = obj.Object("_OBJECT_HEADER", offset = device.obj_offset -
                        device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"),
                        vm = device.obj_vm,
                        native_vm = device.obj_native_vm
                        )

                device_name = str(device_header.NameInfo.Name or '')

                dev = {'Offset': int(device.obj_offset),
                          'DeviceName': device_name,
                          'DeviceCodes': DEVICE_CODES.get(device.DeviceType.v(), "UNKNOWN"),
                          'AttachedDevices': []}

                level = 0

                for att_device in device.attached_devices():

                    device_header = obj.Object("_OBJECT_HEADER", offset = att_device.obj_offset -
                        att_device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"),
                        vm = att_device.obj_vm,
                        native_vm = att_device.obj_native_vm
                        )

                    device_name = str(device_header.NameInfo.Name or '')
                    name = (device_name + " - " +
                           str(att_device.DriverObject.DriverName or ''))

                    attached_device = {'Offset': att_device.obj_offset,
                                       'DeviceName': name,
                                       'DeviceCodes': DEVICE_CODES.get(att_device.DeviceType.v(), "UNKNOWN"),
                                       'Level': level}

                    level += 1
                    dev['AttachedDevices'].append(attached_device)
                row['Devices'].append(dev)

            _addr = str(row['DriverStart'])
            results [_addr ] = row

        return results
コード例 #45
0
ファイル: timers.py プロジェクト: 5l1v3r1/volatility-1
    def calculate(self):
        addr_space = utils.load_as(self._config)

        if not self.is_valid_profile(addr_space.profile):
            debug.error("This command does not support the selected profile.")

        # Get the OS version we're analyzing 
        version = (addr_space.profile.metadata.get('major', 0),
                   addr_space.profile.metadata.get('minor', 0))

        modlist = list(modules.lsmod(addr_space))
        mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modlist)
        mod_addrs = sorted(mods.keys())

        # KTIMERs collected 
        timers = []

        # Valid KTIMER.Header.Type values 
        TimerNotificationObject = 8
        TimerSynchronizationObject = 9
        valid_types = (TimerNotificationObject, TimerSynchronizationObject)

        if version == (5, 1) or (version == (5, 2) and
                                addr_space.profile.metadata.get('build', 0) == 3789):

            # On XP SP0-SP3 x86 and Windows 2003 SP0, KiTimerTableListHead
            # is an array of 256 _LIST_ENTRY for _KTIMERs.

            KiTimerTableListHead = self.find_list_head(modlist[0],
                                        "KeUpdateSystemTime",
                                        "\x25\xFF\x00\x00\x00\x8D\x0C\xC5")

            lists = obj.Object("Array", offset = KiTimerTableListHead,
                                        vm = addr_space,
                                        targetType = '_LIST_ENTRY',
                                        count = 256)

            for l in lists:
                for t in l.list_of_type("_KTIMER", "TimerListEntry"):
                    timers.append(t)

        elif version == (5, 2) or version == (6, 0):

            # On XP x64, Windows 2003 SP1-SP2, and Vista SP0-SP2, KiTimerTableListHead
            # is an array of 512 _KTIMER_TABLE_ENTRY structs.

            KiTimerTableListHead = self.find_list_head(modlist[0],
                                        "KeCancelTimer",
                                        "\xC1\xE7\x04\x81\xC7")

            lists = obj.Object("Array", offset = KiTimerTableListHead,
                                        vm = addr_space,
                                        targetType = '_KTIMER_TABLE_ENTRY',
                                        count = 512)

            for l in lists:
                for t in l.Entry.list_of_type("_KTIMER", "TimerListEntry"):
                    timers.append(t)

        elif version == (6, 1):

            # On Windows 7, there is no more KiTimerTableListHead. The list is
            # at _KPCR.PrcbData.TimerTable.TimerEntries (credits to Matt Suiche
            # for this one. See http://pastebin.com/FiRsGW3f).
            for kpcr in tasks.get_kdbg(addr_space).kpcrs():
                for table in kpcr.ProcessorBlock.TimerTable.TimerEntries:
                    for t in table.Entry.list_of_type("_KTIMER", "TimerListEntry"):
                        timers.append(t)

        for timer in timers:

            # Sanity check on the timer type 
            if timer.Header.Type not in valid_types:
                continue

            # Ignore timers without DPCs
            if not timer.Dpc.is_valid() or not timer.Dpc.DeferredRoutine.is_valid():
                continue

            # Lookup the module containing the DPC
            module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(timer.Dpc.DeferredRoutine))

            yield timer, module
コード例 #46
0
ファイル: threads.py プロジェクト: Jack47/volatility
    def render_text(self, outfd, data):

        # Determine which filters the user wants to see
        if self._config.FILTER:
            filters = set(self._config.FILTER.split(','))
        else:
            filters = set()

        for thread, addr_space, mods, mod_addrs, instances, hooked_tables in data:
            # If the user didn't set filters, display all results. If 
            # the user set one or more filters, only show threads 
            # with matching results. 
            tags = set([t for t, v in instances.items() if v.check()])

            if filters and not filters & tags:
                continue

            s = "------\n"

            s += "ETHREAD: {0:#010x} Pid: {1} Tid: {2}\n".format(
                thread.obj_offset,
                thread.Cid.UniqueProcess, thread.Cid.UniqueThread)

            s += "Tags: {0}\n".format(','.join(tags))
            s += "Created: {0}\n".format(thread.CreateTime)
            s += "Exited: {0}\n".format(thread.ExitTime)

            s += "Owning Process: {0}\n".format(
                thread.owning_process().ImageFileName)

            s += "Attached Process: {0}\n".format(
                thread.attached_process().ImageFileName)

            # Lookup the thread's state
            state = str(thread.Tcb.State)

            # Append the wait reason 
            if state == 'Waiting':
                state = state + ':' + str(thread.Tcb.WaitReason)

            s += "State: {0}\n".format(state)
            s += "BasePriority: {0:#x}\n".format(thread.Tcb.BasePriority)
            s += "Priority: {0:#x}\n".format(thread.Tcb.Priority)
            s += "TEB: {0:#010x}\n".format(thread.Tcb.Teb)

            # If its a system thread, get the owning module
            if "SystemThread" in tags:
                owner = tasks.find_module(mods, mod_addrs, thread.StartAddress)
            else:
                owner = None

            if owner:
                owner_name = str(owner.BaseDllName or '')
            else:
                owner_name = "UNKNOWN"

            s += "StartAddress: {0:#010x} {1}\n".format(
                thread.StartAddress, owner_name)

            # Check the flag which indicates whether Win32StartAddress is valid
            if thread.SameThreadApcFlags & 1:
                s += "Win32StartAddress: {0:#010x}\n".format(
                    thread.Win32StartAddress)

            if self.bits32:
                s += "ServiceTable: {0:#010x}\n".format(thread.Tcb.ServiceTable)

                ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE",
                    offset = thread.Tcb.ServiceTable,
                    vm = addr_space
                    )

                if ssdt_obj != None:
                    for i, desc in enumerate(ssdt_obj.Descriptors):
                        if desc.is_valid():
                            s += "  [{0}] {1:#010x}\n".format(i, desc.KiServiceTable.v())
                        else:
                            s += "  [{0}] -\n".format(i)
                        # Show exactly which functions are hooked 
                        table = desc.KiServiceTable.v()
                        if table not in hooked_tables.keys():
                            continue
                        for (i, func_name, func_addr, mod_name) in hooked_tables[table]:
                            s += "      [{0:#x}] {1} {2:#x} {3}\n".format(
                                i, func_name, func_addr, mod_name)

            s += "Win32Thread: {0:#010x}\n".format(thread.Tcb.Win32Thread)
            s += "CrossThreadFlags: {0}\n".format(thread.CrossThreadFlags)

            # Print the registers if possible 
            trapframe = thread.Tcb.TrapFrame.dereference_as("_KTRAP_FRAME")

            if trapframe and self.bits32:
                s += "Eip: {0:#10x}\n".format(trapframe.Eip)
                s += "  eax={0:#010x} ebx={1:#010x} ecx={2:#010x}".format(
                    trapframe.Eax, trapframe.Ebx, trapframe.Ecx)
                s += " edx={0:#010x} esi={1:#010x} edi={2:#010x}\n".format(
                    trapframe.Edx, trapframe.Esi, trapframe.Edi)
                s += "  eip={0:#010x} esp={1:#010x} ebp={2:#010x} err={3:#010x}\n".format(
                    trapframe.Eip, trapframe.HardwareEsp, trapframe.Ebp, trapframe.ErrCode)
                s += "  cs={0:#04x} ss={1:#04x} ds={2:#04x}".format(
                    trapframe.SegCs, trapframe.HardwareSegSs, trapframe.SegDs)
                s += " es={0:#04x} gs={1:#04x} efl={2:#010x}\n".format(
                    trapframe.SegEs, trapframe.SegGs, trapframe.EFlags)
                s += "  dr0={0:#010x} dr1={1:#010x} dr2={2:#010x}".format(
                    trapframe.Dr0, trapframe.Dr1, trapframe.Dr2)
                s += " dr3={0:#010x} dr6={1:#010x} dr7={2:#010x}\n".format(
                    trapframe.Dr3, trapframe.Dr6, trapframe.Dr7)

            # Disasemble the start address if possible 
            if addr_space.is_valid_address(thread.StartAddress):
                buf = addr_space.zread(thread.StartAddress, 24)

                s += "\n".join(["{0:#x} {1:<16} {2}".format(o, h, i)
                    for o, i, h in malfind.Disassemble(buf, thread.StartAddress.v())])

            outfd.write("{0}\n".format(s))
コード例 #47
0
    def render_text(self, outfd, data):

        # Determine which filters the user wants to see
        if self._config.FILTER:
            filters = set(self._config.FILTER.split(','))
        else:
            filters = set()

        for thread, addr_space, mods, mod_addrs, instances, hooked_tables in data:
            # If the user didn't set filters, display all results. If
            # the user set one or more filters, only show threads
            # with matching results.
            tags = set([t for t, v in list(instances.items()) if v.check()])

            if filters and not filters & tags:
                continue

            s = "------\n"

            s += "ETHREAD: {0:#010x} Pid: {1} Tid: {2}\n".format(
                thread.obj_offset, thread.Cid.UniqueProcess,
                thread.Cid.UniqueThread)

            s += "Tags: {0}\n".format(','.join(tags))
            s += "Created: {0}\n".format(thread.CreateTime)
            s += "Exited: {0}\n".format(thread.ExitTime)

            s += "Owning Process: {0}\n".format(
                thread.owning_process().ImageFileName)

            s += "Attached Process: {0}\n".format(
                thread.attached_process().ImageFileName)

            # Lookup the thread's state
            state = str(thread.Tcb.State)

            # Append the wait reason
            if state == 'Waiting':
                state = state + ':' + str(thread.Tcb.WaitReason)

            s += "State: {0}\n".format(state)
            s += "BasePriority: {0:#x}\n".format(thread.Tcb.BasePriority)
            s += "Priority: {0:#x}\n".format(thread.Tcb.Priority)
            s += "TEB: {0:#010x}\n".format(thread.Tcb.Teb)

            # If its a system thread, get the owning module
            if "SystemThread" in tags:
                owner = tasks.find_module(mods, mod_addrs, thread.StartAddress)
            else:
                owner = None

            if owner:
                owner_name = str(owner.BaseDllName or '')
            else:
                owner_name = "UNKNOWN"

            s += "StartAddress: {0:#010x} {1}\n".format(
                thread.StartAddress, owner_name)

            # Check the flag which indicates whether Win32StartAddress is valid
            if thread.SameThreadApcFlags & 1:
                s += "Win32StartAddress: {0:#010x}\n".format(
                    thread.Win32StartAddress)

            if self.bits32:
                s += "ServiceTable: {0:#010x}\n".format(
                    thread.Tcb.ServiceTable)

                ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE",
                                      offset=thread.Tcb.ServiceTable,
                                      vm=addr_space)

                if ssdt_obj != None:
                    for i, desc in enumerate(ssdt_obj.Descriptors):
                        if desc.is_valid():
                            s += "  [{0}] {1:#010x}\n".format(
                                i, desc.KiServiceTable.v())
                        else:
                            s += "  [{0}] -\n".format(i)
                        # Show exactly which functions are hooked
                        table = desc.KiServiceTable.v()
                        if table not in list(hooked_tables.keys()):
                            continue
                        for (i, func_name, func_addr,
                             mod_name) in hooked_tables[table]:
                            s += "      [{0:#x}] {1} {2:#x} {3}\n".format(
                                i, func_name, func_addr, mod_name)

            s += "Win32Thread: {0:#010x}\n".format(thread.Tcb.Win32Thread)
            s += "CrossThreadFlags: {0}\n".format(thread.CrossThreadFlags)

            # Print the registers if possible
            trapframe = thread.Tcb.TrapFrame.dereference_as("_KTRAP_FRAME")

            if trapframe and self.bits32:
                s += "Eip: {0:#10x}\n".format(trapframe.Eip)
                s += "  eax={0:#010x} ebx={1:#010x} ecx={2:#010x}".format(
                    trapframe.Eax, trapframe.Ebx, trapframe.Ecx)
                s += " edx={0:#010x} esi={1:#010x} edi={2:#010x}\n".format(
                    trapframe.Edx, trapframe.Esi, trapframe.Edi)
                s += "  eip={0:#010x} esp={1:#010x} ebp={2:#010x} err={3:#010x}\n".format(
                    trapframe.Eip, trapframe.HardwareEsp, trapframe.Ebp,
                    trapframe.ErrCode)
                s += "  cs={0:#04x} ss={1:#04x} ds={2:#04x}".format(
                    trapframe.SegCs, trapframe.HardwareSegSs, trapframe.SegDs)
                s += " es={0:#04x} gs={1:#04x} efl={2:#010x}\n".format(
                    trapframe.SegEs, trapframe.SegGs, trapframe.EFlags)
                s += "  dr0={0:#010x} dr1={1:#010x} dr2={2:#010x}".format(
                    trapframe.Dr0, trapframe.Dr1, trapframe.Dr2)
                s += " dr3={0:#010x} dr6={1:#010x} dr7={2:#010x}\n".format(
                    trapframe.Dr3, trapframe.Dr6, trapframe.Dr7)

            # Disasemble the start address if possible
            if addr_space.is_valid_address(thread.StartAddress):
                buf = addr_space.zread(thread.StartAddress, 24)

                s += "\n".join([
                    "{0:#x} {1:<16} {2}".format(o, h, i)
                    for o, i, h in malfind.Disassemble(buf,
                                                       thread.StartAddress.v())
                ])

            outfd.write("{0}\n".format(s))
コード例 #48
0
ファイル: baseline.py プロジェクト: hartl3y94/community-1
    def calculate(self):
        if self._config.BASELINEIMG == None:
            print "Baseline image required!"
            sys.exit()

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

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

        # Instantiating DriverScan plugin
        addr_space = utils.load_as(self._config)
        drv_scan = DriverScan(self._config)

        if volatility.constants.VERSION == "2.6" or volatility.constants.VERSION == "2.4":
            for driver in drv_scan.calculate():
                header = driver.get_object_header()
                if driver.DriverExtension.ServiceKeyName != None:
                    service_key_name = str(
                        driver.DriverExtension.ServiceKeyName).lower()
                else:
                    service_key_name = None

                if header.NameInfo.Name != None:
                    name = str(header.NameInfo.Name).lower()
                else:
                    name = None

                if driver.DriverName != None:
                    driver_name = str(driver.DriverName).lower()
                else:
                    driver_name = None

                if driver.DriverSize != None:
                    driver_size = driver.DriverSize
                else:
                    driver_size = None

                if driver.DriverStart != None:
                    driver_start = driver.DriverStart
                else:
                    driver_start = None

                mods = dict((addr_space.address_mask(mod.DllBase), mod)
                            for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())

                IRPs = {}
                for i, function in enumerate(driver.MajorFunction):
                    function = driver.MajorFunction[i]
                    module = tasks.find_module(
                        mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name

                self.baseline_drv_list.append({
                    'service_key_name': service_key_name,
                    'name': name,
                    'driver_name': driver_name,
                    'driver_size': driver_size,
                    'driver_start': driver_start,
                    'irps': IRPs
                })

        else:
            for obj, drv, ext in drv_scan.calculate():
                if ext.ServiceKeyName != None:
                    service_key_name = str(ext.ServiceKeyName).lower()
                else:
                    service_key_name = None

                if obj.NameInfo.Name != None:
                    name = str(obj.NameInfo.Name).lower()
                else:
                    name = None

                if drv.DriverName != None:
                    driver_name = str(drv.DriverName).lower()
                else:
                    driver_name = None

                if drv.DriverSize != None:
                    driver_size = drv.DriverSize
                else:
                    driver_size = None

                if drv.DriverStart != None:
                    driver_start = drv.DriverStart
                else:
                    driver_start = None

                mods = dict((addr_space.address_mask(mod.DllBase), mod)
                            for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())

                IRPs = {}
                for i, function in enumerate(drv.MajorFunction):
                    function = drv.MajorFunction[i]
                    module = tasks.find_module(
                        mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name

                self.baseline_drv_list.append({
                    'service_key_name': service_key_name,
                    'name': name,
                    'driver_name': driver_name,
                    'driver_size': driver_size,
                    'driver_start': driver_start,
                    'irps': IRPs
                })

        # Instantiating Modules plugin
        for m in lsmod(addr_space):
            self.baseline_mod_list.append({
                'full_dll_name':
                str(m.FullDllName).lower(),
                'base_dll_name':
                str(m.BaseDllName).lower(),
                'dll_base':
                m.DllBase
            })

            for drv in self.baseline_drv_list:
                if drv['driver_start'] == m.DllBase:
                    if m.FullDllName != None:
                        drv['full_dll_name'] = str(m.FullDllName).lower()
                    else:
                        drv['full_dll_name'] = None
                    if m.BaseDllName != None:
                        drv['base_dll_name'] = str(m.BaseDllName).lower()
                    else:
                        drv['base_dll_name'] = None

        # Fixing entries that are not in the list of loaded modules list
        for drv in self.baseline_drv_list:
            f = False
            for m in self.baseline_mod_list:
                if m['dll_base'] == drv['driver_start']:
                    f = True
            if not f:
                drv['full_dll_name'] = None
                drv['base_dll_name'] = None

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

        # Instantiating DriverScan plugin
        addr_space = utils.load_as(self._config)
        drv_scan = DriverScan(self._config)

        if volatility.constants.VERSION == "2.6" or volatility.constants.VERSION == "2.4":
            for driver in drv_scan.calculate():
                header = driver.get_object_header()
                if driver.DriverExtension.ServiceKeyName != None:
                    service_key_name = str(
                        driver.DriverExtension.ServiceKeyName).lower()
                else:
                    service_key_name = None

                if header.NameInfo.Name != None:
                    name = str(header.NameInfo.Name).lower()
                else:
                    name = None

                if driver.DriverName != None:
                    driver_name = str(driver.DriverName).lower()
                else:
                    driver_name = None

                if driver.DriverSize != None:
                    driver_size = driver.DriverSize
                else:
                    driver_size = None

                if driver.DriverStart != None:
                    driver_start = driver.DriverStart
                else:
                    driver_start = None

                mods = dict((addr_space.address_mask(mod.DllBase), mod)
                            for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())

                IRPs = {}
                for i, function in enumerate(driver.MajorFunction):
                    function = driver.MajorFunction[i]
                    module = tasks.find_module(
                        mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name

                self.image_drv_list.append({
                    'service_key_name': service_key_name,
                    'name': name,
                    'driver_name': driver_name,
                    'driver_size': driver_size,
                    'driver_start': driver_start,
                    'irps': IRPs,
                    'obj': header,
                    'drv': driver,
                    'ext': driver.DriverExtension
                })

        else:
            for obj, drv, ext in drv_scan.calculate():
                if ext.ServiceKeyName != None:
                    service_key_name = str(ext.ServiceKeyName).lower()
                else:
                    service_key_name = None

                if obj.NameInfo.Name != None:
                    name = str(obj.NameInfo.Name).lower()
                else:
                    name = None

                if drv.DriverName != None:
                    driver_name = str(drv.DriverName).lower()
                else:
                    driver_name = None

                if drv.DriverSize != None:
                    driver_size = drv.DriverSize
                else:
                    driver_size = None

                if drv.DriverStart != None:
                    driver_start = drv.DriverStart
                else:
                    driver_start = None

                mods = dict((addr_space.address_mask(mod.DllBase), mod)
                            for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())

                IRPs = {}
                for i, function in enumerate(drv.MajorFunction):
                    function = drv.MajorFunction[i]
                    module = tasks.find_module(
                        mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name

                self.image_drv_list.append({
                    'service_key_name': service_key_name,
                    'name': name,
                    'driver_name': driver_name,
                    'driver_size': driver_size,
                    'driver_start': driver_start,
                    'irps': IRPs,
                    'obj': obj,
                    'drv': drv,
                    'ext': ext
                })

        for m in lsmod(addr_space):
            self.image_mod_list.append({
                'full_dll_name':
                str(m.FullDllName).lower(),
                'base_dll_name':
                str(m.BaseDllName).lower(),
                'dll_base':
                m.DllBase
            })
            for drv in self.image_drv_list:
                if drv['driver_start'] == m.DllBase:
                    if m.FullDllName != None:
                        drv['full_dll_name'] = str(m.FullDllName).lower()
                    else:
                        drv['full_dll_name'] = None
                    if m.BaseDllName != None:
                        drv['base_dll_name'] = str(m.BaseDllName).lower()
                    else:
                        drv['base_dll_name'] = None

        # Fixing up entries that are not in the list of loaded modules list
        for drv in self.image_drv_list:
            f = False
            for m in self.image_mod_list:
                if m['dll_base'] == drv['driver_start']:
                    f = True
            if not f:
                drv['full_dll_name'] = None
                drv['base_dll_name'] = None

        # Compare the lists
        for drv in self.image_drv_list:
            known = False
            d_name = False
            drv_name = False
            drv_size = False
            drv_mod = False
            drv_irp = False
            drv_bl = None
            for bl_drv in self.baseline_drv_list:

                if drv['service_key_name'] == bl_drv['service_key_name']:
                    known = True

                    if drv['name'] == bl_drv['name']:
                        d_name = True
                    elif self._config.VERBOSE:
                        print "Name:"
                        print "Baseline: " + bl_drv['name']
                        print "Image:    " + drv['name']

                    if drv['driver_name'] == bl_drv['driver_name']:
                        drv_name = True
                    elif self._config.VERBOSE:
                        print "Driver Name:"
                        print "Baseline: " + str(bl_drv['driver_name'])
                        print "Image:    " + str(drv['driver_name'])

                    if drv['driver_size'] == bl_drv['driver_size']:
                        drv_size = True
                    elif self._config.VERBOSE:
                        print "Driver Size:"
                        print "Baseline: " + str(bl_drv['driver_size'])
                        print "Image:    " + str(drv['driver_size'])

                    if drv['full_dll_name'] == bl_drv['full_dll_name']:
                        drv_mod = True
                    elif self._config.VERBOSE:
                        print "Module:"
                        print "Baseline: " + str(bl_drv['full_dll_name'])
                        print "Image:    " + str(drv['full_dll_name'])

                    drv_irp = True
                    for m in drv['irps']:
                        if drv['irps'][m] != bl_drv['irps'][m]:
                            drv_irp = False

                if known:
                    drv_bl = bl_drv
                    break

            if self._config.ONLYKNOWN:
                if known:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name,
                           drv_name, drv_mod, drv_size, drv['full_dll_name'],
                           drv_irp, drv['irps'], drv_bl['irps'])
            if self._config.ONLYUNKNOWN:
                if not known:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name,
                           drv_name, drv_mod, drv_size, drv['full_dll_name'],
                           drv_irp, drv['irps'], None)
            if not self._config.ONLYKNOWN and not self._config.ONLYUNKNOWN:
                if drv_bl:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name,
                           drv_name, drv_mod, drv_size, drv['full_dll_name'],
                           drv_irp, drv['irps'], drv_bl['irps'])
                else:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name,
                           drv_name, drv_mod, drv_size, drv['full_dll_name'],
                           drv_irp, drv['irps'], None)
コード例 #49
0
ファイル: devicetree.py プロジェクト: vortessence/vortessence
    def get_json(self, data):
        results = {}

        addr_space = utils.load_as(self._config)

        # Compile the regular expression for filtering by driver name
        if self._config.regex != None:
            mod_re = re.compile(self._config.regex, re.I)
        else:
            mod_re = None

        mods = dict((mod.DllBase, mod) for mod in modules.lsmod(addr_space))
        mod_addrs = sorted(mods.keys())

        bits = addr_space.profile.metadata.get('memory_model', '32bit')

        for driver in data:
            header = driver.get_object_header()

            driver_name = str(header.NameInfo.Name or '')

            # Continue if a regex was supplied and it doesn't match
            if mod_re != None:
                if not (mod_re.search(driver_name)
                        or mod_re.search(driver_name)):
                    continue

            row = {
                'DriverName': driver_name,
                'DriverStart': int(driver.DriverStart),
                'DriverSize': int(driver.DriverSize),
                'DriverStartIo': int(driver.DriverStartIo),
                'IrpFunctions': [],
                'Devices': [],
            }

            # Write the address and owner of each IRP function
            for i, function in enumerate(driver.MajorFunction):
                function = driver.MajorFunction[i]
                module = tasks.find_module(mods, mod_addrs, function)
                irp = {
                    'index': int(i),
                    'FunctionName': str(MAJOR_FUNCTIONS[i]),
                    'FunctionAddress': int(function),
                    'Disassembly': []
                }
                if module:
                    irp['BaseDllName'] = str(module.BaseDllName or '')
                else:
                    irp['BaseDllName'] = ''

                if self._config.verbose:
                    data = addr_space.zread(function, 64)
                    irp["Disassembly"] = [{
                        'Address': int(o),
                        "Bytes": str(h),
                        "Instruction": str(i)
                    } for o, i, h in malfind.Disassemble(
                        data=data, start=function, bits=bits, stoponret=True)]
                row['IrpFunctions'].append(irp)

            for device in driver.devices():

                device_header = obj.Object(
                    "_OBJECT_HEADER",
                    offset=device.obj_offset -
                    device.obj_vm.profile.get_obj_offset(
                        "_OBJECT_HEADER", "Body"),
                    vm=device.obj_vm,
                    native_vm=device.obj_native_vm)

                device_name = str(device_header.NameInfo.Name or '')

                dev = {
                    'Offset':
                    int(device.obj_offset),
                    'DeviceName':
                    device_name,
                    'DeviceCodes':
                    DEVICE_CODES.get(device.DeviceType.v(), "UNKNOWN"),
                    'AttachedDevices': []
                }

                level = 0

                for att_device in device.attached_devices():

                    device_header = obj.Object(
                        "_OBJECT_HEADER",
                        offset=att_device.obj_offset -
                        att_device.obj_vm.profile.get_obj_offset(
                            "_OBJECT_HEADER", "Body"),
                        vm=att_device.obj_vm,
                        native_vm=att_device.obj_native_vm)

                    device_name = str(device_header.NameInfo.Name or '')
                    name = (device_name + " - " +
                            str(att_device.DriverObject.DriverName or ''))

                    attached_device = {
                        'Offset':
                        att_device.obj_offset,
                        'DeviceName':
                        name,
                        'DeviceCodes':
                        DEVICE_CODES.get(att_device.DeviceType.v(), "UNKNOWN"),
                        'Level':
                        level
                    }

                    level += 1
                    dev['AttachedDevices'].append(attached_device)
                row['Devices'].append(dev)

            _addr = str(row['DriverStart'])
            results[_addr] = row

        return results
コード例 #50
0
    def calculate(self):
        if self._config.BASELINEIMG == None:
            print "Baseline image required!"
            sys.exit()
        
        if self._config.ONLYKNOWN and self._config.ONLYUNKNOWN:
            print "Select only one of the options (-K, -U)!"
            sys.exit(-1)
        
        #######################################
        #Searching for drivers in baseline image
        ######################################
        # Saving original image
        orig_img = self._config.LOCATION
        # Setting up baseline image
        self._config.LOCATION = "file://" + self._config.BASELINEIMG

        # Instantiating DriverScan plugin
        addr_space = utils.load_as(self._config)
        drv_scan = DriverScan(self._config)
        
        if volatility.constants.VERSION != "2.4":
            for obj, drv, ext  in drv_scan.calculate():
                if ext.ServiceKeyName != None:
                    service_key_name = str(ext.ServiceKeyName).lower()
                else:
                    service_key_name = None
                
                if obj.NameInfo.Name != None:
                    name = str(obj.NameInfo.Name).lower()
                else:
                    name = None
                
                if drv.DriverName != None:
                    driver_name = str(drv.DriverName).lower()
                else:
                    driver_name = None
                
                if drv.DriverSize != None:
                    driver_size = drv.DriverSize
                else:
                    driver_size = None
                
                if drv.DriverStart != None:
                    driver_start = drv.DriverStart
                else:
                    driver_start = None
                
                mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())
                
                IRPs = {}
                for i, function in enumerate(drv.MajorFunction):
                    function = drv.MajorFunction[i]
                    module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name               
                
                self.baseline_drv_list.append({
                                                'service_key_name': service_key_name,
                                                'name': name,
                                                'driver_name': driver_name,
                                                'driver_size': driver_size,
                                                'driver_start': driver_start,
                                                'irps': IRPs
                                            })
        else:
            for driver in drv_scan.calculate():
                header = driver.get_object_header()
                if driver.DriverExtension.ServiceKeyName != None:
                    service_key_name = str(driver.DriverExtension.ServiceKeyName).lower()
                else:
                    service_key_name = None
                
                if header.NameInfo.Name != None:
                    name = str(header.NameInfo.Name).lower()
                else:
                    name = None
                
                if driver.DriverName != None:
                    driver_name = str(driver.DriverName).lower()
                else:
                    driver_name = None
                
                if driver.DriverSize != None:
                    driver_size = driver.DriverSize
                else:
                    driver_size = None
                
                if driver.DriverStart != None:
                    driver_start = driver.DriverStart
                else:
                    driver_start = None
                
                mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())
                
                IRPs = {}
                for i, function in enumerate(driver.MajorFunction):
                    function = driver.MajorFunction[i]
                    module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name               
                
                self.baseline_drv_list.append({
                                                'service_key_name': service_key_name,
                                                'name': name,
                                                'driver_name': driver_name,
                                                'driver_size': driver_size,
                                                'driver_start': driver_start,
                                                'irps': IRPs
                                            })
        
        # Instantiating Modules plugin
        for m in lsmod(addr_space):
            self.baseline_mod_list.append({
                                            'full_dll_name': str(m.FullDllName).lower(),
                                            'base_dll_name': str(m.BaseDllName).lower(),
                                            'dll_base': m.DllBase
                                        })
            
            for drv in self.baseline_drv_list:
                if drv['driver_start'] == m.DllBase:
                    if m.FullDllName != None:
                        drv['full_dll_name'] = str(m.FullDllName).lower()
                    else:
                        drv['full_dll_name'] = None
                    if m.BaseDllName != None:
                        drv['base_dll_name'] = str(m.BaseDllName).lower()
                    else:
                        drv['base_dll_name'] = None
        
        # Fixing entries that are not in the list of loaded modules list
        for drv in self.baseline_drv_list:
            f = False
            for m in self.baseline_mod_list:
                if m['dll_base'] == drv['driver_start']:
                    f = True
            if not f:
                drv['full_dll_name'] = None
                drv['base_dll_name'] = None
        
        ####################################
        #Searching for drivers in the image to be analyzed
        ##################################
        # Restoring original image
        self._config.LOCATION = orig_img
        
        # Instantiating DriverScan plugin
        addr_space = utils.load_as(self._config)
        drv_scan = DriverScan(self._config)
        if volatility.constants.VERSION != "2.4":
            for obj, drv, ext  in drv_scan.calculate():
                if ext.ServiceKeyName != None:
                    service_key_name = str(ext.ServiceKeyName).lower()
                else:
                    service_key_name = None
                
                if obj.NameInfo.Name != None:
                    name = str(obj.NameInfo.Name).lower()
                else:
                    name = None
                
                if drv.DriverName != None:
                    driver_name = str(drv.DriverName).lower()
                else:
                    driver_name = None
                
                if drv.DriverSize != None:
                    driver_size = drv.DriverSize
                else:
                    driver_size = None
                
                if drv.DriverStart != None:
                    driver_start = drv.DriverStart
                else:
                    driver_start = None
                
                mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())
                
                IRPs = {}
                for i, function in enumerate(drv.MajorFunction):
                    function = drv.MajorFunction[i]
                    module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name
                
                self.image_drv_list.append({
                                                'service_key_name': service_key_name,
                                                'name': name,
                                                'driver_name': driver_name,
                                                'driver_size': driver_size,
                                                'driver_start': driver_start,
                                                'irps': IRPs,
                                                'obj': obj,
                                                'drv': drv,
                                                'ext': ext
                                            })
        else:
            for driver in drv_scan.calculate():
                header = driver.get_object_header()
                if driver.DriverExtension.ServiceKeyName != None:
                    service_key_name = str(driver.DriverExtension.ServiceKeyName).lower()
                else:
                    service_key_name = None
                
                if header.NameInfo.Name != None:
                    name = str(header.NameInfo.Name).lower()
                else:
                    name = None
                
                if driver.DriverName != None:
                    driver_name = str(driver.DriverName).lower()
                else:
                    driver_name = None
                
                if driver.DriverSize != None:
                    driver_size = driver.DriverSize
                else:
                    driver_size = None
                
                if driver.DriverStart != None:
                    driver_start = driver.DriverStart
                else:
                    driver_start = None
                
                mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in lsmod(addr_space))
                mod_addrs = sorted(mods.keys())
                
                IRPs = {}
                for i, function in enumerate(driver.MajorFunction):
                    function = driver.MajorFunction[i]
                    module = tasks.find_module(mods, mod_addrs, addr_space.address_mask(function))
                    if module:
                        module_name = str(module.BaseDllName or '').lower()
                    else:
                        module_name = "unknown"
                    IRPs[MAJOR_FUNCTIONS[i]] = module_name
                
                self.image_drv_list.append({
                                                'service_key_name': service_key_name,
                                                'name': name,
                                                'driver_name': driver_name,
                                                'driver_size': driver_size,
                                                'driver_start': driver_start,
                                                'irps': IRPs,
                                                'obj': header,
                                                'drv': driver,
                                                'ext': driver.DriverExtension
                                            })
        
        for m in lsmod(addr_space):
            self.image_mod_list.append({
                                            'full_dll_name': str(m.FullDllName).lower(),
                                            'base_dll_name': str(m.BaseDllName).lower(),
                                            'dll_base': m.DllBase
                                        })
            for drv in self.image_drv_list:
                if drv['driver_start'] == m.DllBase:
                    if m.FullDllName != None:
                        drv['full_dll_name'] = str(m.FullDllName).lower()
                    else:
                        drv['full_dll_name'] = None
                    if m.BaseDllName != None:
                        drv['base_dll_name'] = str(m.BaseDllName).lower()
                    else:
                        drv['base_dll_name'] = None
        
        # Fixing up entries that are not in the list of loaded modules list
        for drv in self.image_drv_list:
            f = False
            for m in self.image_mod_list:
                if m['dll_base'] == drv['driver_start']:
                    f = True
            if not f:
                drv['full_dll_name'] = None
                drv['base_dll_name'] = None
        
        # Compare the lists
        for drv in self.image_drv_list:
            known = False
            d_name = False
            drv_name = False
            drv_size = False
            drv_mod = False
            drv_irp = False
            drv_bl = None
            for bl_drv in self.baseline_drv_list:
                
                if drv['service_key_name'] == bl_drv['service_key_name']:
                    known = True
                    
                    if drv['name'] == bl_drv['name']:
                        d_name = True
                    elif self._config.VERBOSE:
                        print "Name:"
                        print "Baseline: " + bl_drv['name']
                        print "Image:    " + drv['name']
                    
                    if drv['driver_name'] == bl_drv['driver_name']:
                        drv_name = True
                    elif self._config.VERBOSE:
                        print "Driver Name:"
                        print "Baseline: " + str(bl_drv['driver_name'])
                        print "Image:    " + str(drv['driver_name'])
                    
                    if drv['driver_size'] == bl_drv['driver_size']:
                        drv_size = True
                    elif self._config.VERBOSE:
                        print "Driver Size:"
                        print "Baseline: " + str(bl_drv['driver_size'])
                        print "Image:    " + str(drv['driver_size'])
                    
                    if drv['full_dll_name'] == bl_drv['full_dll_name']:
                        drv_mod = True
                    elif self._config.VERBOSE:
                        print "Module:"
                        print "Baseline: " + str(bl_drv['full_dll_name'])
                        print "Image:    " + str(drv['full_dll_name'])
                        
                    drv_irp = True
                    for m in drv['irps']:
                        if drv['irps'][m] != bl_drv['irps'][m]:
                            drv_irp = False
                    
                if known:
                    drv_bl = bl_drv
                    break
            
            if self._config.ONLYKNOWN:
                if known:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name, drv_name, drv_mod, drv_size, drv['full_dll_name'], drv_irp, drv['irps'], drv_bl['irps'])
            if self._config.ONLYUNKNOWN:
                if not known:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name, drv_name, drv_mod, drv_size, drv['full_dll_name'], drv_irp, drv['irps'], None)
            if not self._config.ONLYKNOWN and not self._config.ONLYUNKNOWN:
                if drv_bl:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name, drv_name, drv_mod, drv_size, drv['full_dll_name'], drv_irp, drv['irps'], drv_bl['irps'])
                else:
                    yield (drv['obj'], drv['drv'], drv['ext'], known, d_name, drv_name, drv_mod, drv_size, drv['full_dll_name'], drv_irp, drv['irps'], None)
コード例 #51
0
ファイル: threads.py プロジェクト: vortessence/vortessence
    def get_json(self, data):
        results = {}

        # Determine which filters the user wants to see
        if self._config.FILTER:
            filters = set(self._config.FILTER.split(','))
        else:
            filters = set()

        for thread, addr_space, mods, mod_addrs, \
            instances, hooked_tables, system_range, owner_name in data:
            # If the user didn't set filters, display all results. If
            # the user set one or more filters, only show threads
            # with matching results.
            tags = set([t for t, v in instances.items() if v.check()])

            if filters and not filters & tags:
                continue

            row = {'offset': int(thread.obj_offset),
                   'UniqueProcess': int(thread.Cid.UniqueProcess),
                   'UniqueThread': int(thread.Cid.UniqueThread),
                   'Tags': [str(i) for i in tags],
                   'CreateTime': str(thread.CreateTime),
                   'ExitTime': str(thread.ExitTime),
                   'ImageFileName': str(thread.owning_process().ImageFileName),
                   'Attached': str(thread.attached_process().ImageFileName),
                   'BasePriority': int(thread.Tcb.BasePriority),
                   'Priority': int(thread.Tcb.Priority),
                   'Teb': int(thread.Tcb.Teb),
                   'State': str(thread.Tcb.State),
                   'WaitReason': str(thread.Tcb.WaitReason),
                   'StartAddress': int(thread.StartAddress),
                   "SystemThread": bool("SystemThread" in tags),
                   "OwnerName": "",
                   "Win32StartAddressValid": thread.SameThreadApcFlags & 1,
                   "Win32StartAddress": int(thread.Win32StartAddress),
                   'ServiceTable': int(thread.Tcb.ServiceTable) if self.bits32 else "",
                   "Win32Thread": int(thread.Tcb.Win32Thread),
                   "CrossThreadFlags": int(thread.CrossThreadFlags),
                   "TrapFrame": {},
                   'SSDT': {},
                   "Disassembly": []
            }

            # Print the registers if possible
            trapframe = thread.Tcb.TrapFrame.dereference_as("_KTRAP_FRAME")

            if trapframe and self.bits32:
                row["TrapFrame"] = {key: int(eval('trapframe.%s' % key, {'trapframe': trapframe})) for key in
                                    trapframe.members.keys()}

            # Disasemble the start address if possible
            if addr_space.is_valid_address(thread.StartAddress):
                buf = addr_space.zread(thread.StartAddress, 24)
                row["Disassembly"] = [{'Address': int(o), "Bytes": str(h), "Instruction": str(i)}
                                      for o, i, h in
                                      malfind.Disassemble(buf, thread.StartAddress.v())
                ]

            # If its a system thread, get the owning module
            if row["SystemThread"]:
                owner = tasks.find_module(mods, mod_addrs, thread.StartAddress)
                if not owner is None:
                    row["OwnerName"] = str(owner.BaseDllName or owner_name)

            if self.bits32:
                ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE",
                                      offset=thread.Tcb.ServiceTable,
                                      vm=addr_space
                )

                if ssdt_obj is not None:
                    for i, desc in enumerate(ssdt_obj.Descriptors):
                        row['SSDT'][str(i)] = {'index': i,
                                               'KiServiceTable': '',
                                               'HookedSSDT': []}
                        if desc.is_valid():
                            row['SSDT'][str(i)]['KiServiceTable'] = desc.KiServiceTable.v()

                        table = desc.KiServiceTable.v()
                        if table not in hooked_tables.keys():
                            continue

                        # no use for this data so far
                        #
                        # for (j, func_name, func_addr, mod_name) in hooked_tables[table]:
                        #     row['SSDT'][str(i)]['HookedSSDT'].append({'index': j,
                        #                                               'FunctionName': func_name,
                        #                                               'FunctionAddress': func_addr,
                        #                                               'ModuleName': str(mod_name)})

            results[str(row['offset'])] = row

        return results
コード例 #52
0
ファイル: ssdt.py プロジェクト: DSLeung/volatility
    def generator(self, data):

        addr_space = utils.load_as(self._config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model', '32bit') == '32bit'

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            table_name = "SSDT[{0}]".format(idx)
            table_offset = Address(table)
            num_entries = int(n)
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory. 
                    syscall_addr = obj.Object('address', table + (i * 4), vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative. 
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number. 
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                if not self._config.VERBOSE:
                    yield (0, [table_name, table_offset, num_entries, Address(idx * 0x1000 + i), 
                            Address(syscall_addr), str(syscall_name), str(syscall_modname)])

                ## check for inline hooks if in --verbose mode, we're analyzing
                ## an x86 model system and the sycall_mod is available 
                if (self._config.VERBOSE and 
                            addr_space.profile.metadata.get('memory_model', '32bit') == '32bit' and 
                            syscall_mod is not None):

                        ## leverage this static method from apihooks
                        ret = apihooks.ApiHooks.check_inline(va = syscall_addr, addr_space = vm, 
                                                mem_start = syscall_mod.DllBase, 
                                                mem_end = syscall_mod.DllBase + syscall_mod.SizeOfImage)
                        ## could not analyze the memory
                        if ret == None:
                            yield (0, [table_name, table_offset, num_entries, Address(idx * 0x1000 + i), 
                                    Address(syscall_addr), str(syscall_name), str(syscall_modname), 
                                    Address(0), "NotInline"])
                            continue 
                        (hooked, data, dest_addr) = ret
                        ## the function isn't hooked
                        if not hooked:
                            yield (0, [table_name, table_offset, num_entries, Address(idx * 0x1000 + i), 
                                    Address(syscall_addr), str(syscall_name), str(syscall_modname), 
                                    Address(0), "NotInline"])
                            continue 
                        ## we found a hook, try to resolve the hooker. no mask required because
                        ## we currently only work on x86 anyway
                        hook_mod = tasks.find_module(mods, mod_addrs, dest_addr)
                        if hook_mod: 
                            hook_name = hook_mod.BaseDllName
                        else:
                            hook_name = "UNKNOWN"
                        ## report it now 
                        yield (0, [table_name, table_offset, num_entries, Address(idx * 0x1000 + i), 
                                Address(syscall_addr), str(syscall_name), str(syscall_modname),
                                Address(dest_addr), str(hook_name)])
コード例 #53
0
ファイル: memory.py プロジェクト: NickyCM/cuckoo
    def ssdt(self):
        """Volatility ssdt plugin.
        @see volatility/plugins/ssdt.py
        """
        results = []

        command = self.plugins["ssdt"](self.config)

        # Comment: this code is pretty much ripped from render_text in volatility.
        addr_space = self.addr_space
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get("memory_model", "32bit") == "32bit"

        for idx, table, n, vm, mods, mod_addrs in command.calculate():
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object("address", table + (i * 4), vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative.
                    offset = obj.Object("long", table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)

                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = "{0}".format(syscall_mod.BaseDllName)
                else:
                    syscall_modname = "UNKNOWN"

                new = {
                    "index": int(idx),
                    "table": "0x%x" % int(table),
                    "entry": "{0:#06x}".format(idx * 0x1000 + i),
                    "syscall_name": syscall_name,
                    "syscall_addr": "0x%x" % int(syscall_addr),
                    "syscall_modname": syscall_modname,
                }

                if bits32 and syscall_mod is not None:
                    ret = apihooks.ApiHooks.check_inline(
                        va=syscall_addr, addr_space=vm,
                        mem_start=syscall_mod.DllBase,
                        mem_end=syscall_mod.DllBase + syscall_mod.SizeOfImage)

                    # Could not analyze the memory.
                    if ret is not None:
                        hooked, data, dest_addr = ret
                        if hooked:
                            # We found a hook, try to resolve the hooker.
                            # No mask required because we currently only work
                            # on x86 anyway.
                            hook_mod = tasks.find_module(mods, mod_addrs,
                                                         dest_addr)
                            if hook_mod:
                                hook_name = "{0}".format(hook_mod.BaseDllName)
                            else:
                                hook_name = "UNKNOWN"

                            # Report it now.
                            new.update({
                                "hook_dest_addr": "{0:#x}".format(dest_addr),
                                "hook_name": hook_name,
                            })

                results.append(new)

        return dict(config={}, data=results)
コード例 #54
0
    def get_json(self, data):
        results = {}

        # Determine which filters the user wants to see
        if self._config.FILTER:
            filters = set(self._config.FILTER.split(','))
        else:
            filters = set()

        for thread, addr_space, mods, mod_addrs, \
            instances, hooked_tables, system_range, owner_name in data:
            # If the user didn't set filters, display all results. If
            # the user set one or more filters, only show threads
            # with matching results.
            tags = set([t for t, v in instances.items() if v.check()])

            if filters and not filters & tags:
                continue

            row = {
                'offset': int(thread.obj_offset),
                'UniqueProcess': int(thread.Cid.UniqueProcess),
                'UniqueThread': int(thread.Cid.UniqueThread),
                'Tags': [str(i) for i in tags],
                'CreateTime': str(thread.CreateTime),
                'ExitTime': str(thread.ExitTime),
                'ImageFileName': str(thread.owning_process().ImageFileName),
                'Attached': str(thread.attached_process().ImageFileName),
                'BasePriority': int(thread.Tcb.BasePriority),
                'Priority': int(thread.Tcb.Priority),
                'Teb': int(thread.Tcb.Teb),
                'State': str(thread.Tcb.State),
                'WaitReason': str(thread.Tcb.WaitReason),
                'StartAddress': int(thread.StartAddress),
                "SystemThread": bool("SystemThread" in tags),
                "OwnerName": "",
                "Win32StartAddressValid": thread.SameThreadApcFlags & 1,
                "Win32StartAddress": int(thread.Win32StartAddress),
                'ServiceTable':
                int(thread.Tcb.ServiceTable) if self.bits32 else "",
                "Win32Thread": int(thread.Tcb.Win32Thread),
                "CrossThreadFlags": int(thread.CrossThreadFlags),
                "TrapFrame": {},
                'SSDT': {},
                "Disassembly": []
            }

            # Print the registers if possible
            trapframe = thread.Tcb.TrapFrame.dereference_as("_KTRAP_FRAME")

            if trapframe and self.bits32:
                row["TrapFrame"] = {
                    key:
                    int(eval('trapframe.%s' % key, {'trapframe': trapframe}))
                    for key in trapframe.members.keys()
                }

            # Disasemble the start address if possible
            if addr_space.is_valid_address(thread.StartAddress):
                buf = addr_space.zread(thread.StartAddress, 24)
                row["Disassembly"] = [{
                    'Address': int(o),
                    "Bytes": str(h),
                    "Instruction": str(i)
                } for o, i, h in malfind.Disassemble(buf,
                                                     thread.StartAddress.v())]

            # If its a system thread, get the owning module
            if row["SystemThread"]:
                owner = tasks.find_module(mods, mod_addrs, thread.StartAddress)
                if not owner is None:
                    row["OwnerName"] = str(owner.BaseDllName or owner_name)

            if self.bits32:
                ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE",
                                      offset=thread.Tcb.ServiceTable,
                                      vm=addr_space)

                if ssdt_obj is not None:
                    for i, desc in enumerate(ssdt_obj.Descriptors):
                        row['SSDT'][str(i)] = {
                            'index': i,
                            'KiServiceTable': '',
                            'HookedSSDT': []
                        }
                        if desc.is_valid():
                            row['SSDT'][str(i)][
                                'KiServiceTable'] = desc.KiServiceTable.v()

                        table = desc.KiServiceTable.v()
                        if table not in hooked_tables.keys():
                            continue

                        # no use for this data so far
                        #
                        # for (j, func_name, func_addr, mod_name) in hooked_tables[table]:
                        #     row['SSDT'][str(i)]['HookedSSDT'].append({'index': j,
                        #                                               'FunctionName': func_name,
                        #                                               'FunctionAddress': func_addr,
                        #                                               'ModuleName': str(mod_name)})

            results[str(row['offset'])] = row

        return results
コード例 #55
0
ファイル: ssdt.py プロジェクト: jbremer/volatility
    def generator(self, data):

        addr_space = utils.load_as(self._config)
        syscalls = addr_space.profile.syscalls
        bits32 = addr_space.profile.metadata.get('memory_model',
                                                 '32bit') == '32bit'

        # Print out the entries for each table
        for idx, table, n, vm, mods, mod_addrs in data:
            table_name = "SSDT[{0}]".format(idx)
            table_offset = Address(table)
            num_entries = int(n)
            for i in range(n):
                if bits32:
                    # These are absolute function addresses in kernel memory.
                    syscall_addr = obj.Object('address', table + (i * 4),
                                              vm).v()
                else:
                    # These must be signed long for x64 because they are RVAs relative
                    # to the base of the table and can be negative.
                    offset = obj.Object('long', table + (i * 4), vm).v()
                    # The offset is the top 20 bits of the 32 bit number.
                    syscall_addr = table + (offset >> 4)
                try:
                    syscall_name = syscalls[idx][i]
                except IndexError:
                    syscall_name = "UNKNOWN"

                syscall_mod = tasks.find_module(
                    mods, mod_addrs, addr_space.address_mask(syscall_addr))
                if syscall_mod:
                    syscall_modname = syscall_mod.BaseDllName
                else:
                    syscall_modname = "UNKNOWN"

                if not self._config.VERBOSE:
                    yield (0, [
                        table_name, table_offset, num_entries,
                        Address(idx * 0x1000 + i),
                        Address(syscall_addr),
                        str(syscall_name),
                        str(syscall_modname)
                    ])

                ## check for inline hooks if in --verbose mode, we're analyzing
                ## an x86 model system and the sycall_mod is available
                if (self._config.VERBOSE and addr_space.profile.metadata.get(
                        'memory_model', '32bit') == '32bit'
                        and syscall_mod is not None):

                    ## leverage this static method from apihooks
                    ret = apihooks.ApiHooks.check_inline(
                        va=syscall_addr,
                        addr_space=vm,
                        mem_start=syscall_mod.DllBase,
                        mem_end=syscall_mod.DllBase + syscall_mod.SizeOfImage)
                    ## could not analyze the memory
                    if ret == None:
                        yield (0, [
                            table_name, table_offset, num_entries,
                            Address(idx * 0x1000 + i),
                            Address(syscall_addr),
                            str(syscall_name),
                            str(syscall_modname),
                            Address(0), "NotInline"
                        ])
                        continue
                    (hooked, data, dest_addr) = ret
                    ## the function isn't hooked
                    if not hooked:
                        yield (0, [
                            table_name, table_offset, num_entries,
                            Address(idx * 0x1000 + i),
                            Address(syscall_addr),
                            str(syscall_name),
                            str(syscall_modname),
                            Address(0), "NotInline"
                        ])
                        continue
                    ## we found a hook, try to resolve the hooker. no mask required because
                    ## we currently only work on x86 anyway
                    hook_mod = tasks.find_module(mods, mod_addrs, dest_addr)
                    if hook_mod:
                        hook_name = hook_mod.BaseDllName
                    else:
                        hook_name = "UNKNOWN"
                    ## report it now
                    yield (0, [
                        table_name, table_offset, num_entries,
                        Address(idx * 0x1000 + i),
                        Address(syscall_addr),
                        str(syscall_name),
                        str(syscall_modname),
                        Address(dest_addr),
                        str(hook_name)
                    ])
コード例 #56
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