Ejemplo n.º 1
0
def get_kdbg(addr_space):
    """A function designed to return the KDBG structure from 
    an address space. First we try scanning for KDBG and if 
    that fails, we try scanning for KPCR and bouncing back to
    KDBG from there. 

    Also note, both the primary and backup methods rely on the 
    4-byte KDBG.Header.OwnerTag. If someone overwrites this 
    value, then neither method will succeed. The same is true 
    even if a user specifies --kdbg, because we check for the 
    OwnerTag even in that case. 
    """

    kdbgo = obj.VolMagic(addr_space).KDBG.v()

    kdbg = obj.Object("_KDDEBUGGER_DATA64", offset=kdbgo, vm=addr_space)

    if kdbg.is_valid():
        return kdbg

    # Fall back to finding it via the KPCR. We cannot
    # accept the first/best suggestion, because only
    # the KPCR for the first CPU allows us to find KDBG.
    for kpcr_off in obj.VolMagic(addr_space).KPCR.generate_suggestions():

        kpcr = obj.Object("_KPCR", offset=kpcr_off, vm=addr_space)

        kdbg = kpcr.get_kdbg()

        if kdbg.is_valid():
            return kdbg

    return obj.NoneObject(
        "KDDEBUGGER structure not found using either KDBG signature or KPCR pointer"
    )
Ejemplo n.º 2
0
def get_kdbg(addr_space):
    """A function designed to return the KDBG structure from
    an address space. First we try scanning for KDBG and if
    that fails, we try scanning for KPCR and bouncing back to
    KDBG from there.

    Also note, both the primary and backup methods rely on the
    4-byte KDBG.Header.OwnerTag. If someone overwrites this
    value, then neither method will succeed. The same is true
    even if a user specifies --kdbg, because we check for the
    OwnerTag even in that case.
    """
    # we can use the hard coded KPCR value instead of scanning for KDBG
    # like back in the old days of version 1.x
    # this works for XP/2003 x86
    # all other machines that do not have hardcoded KPCR values
    # will fall back on the previous methodology
    if obj.VolMagic(addr_space).KPCR.value:
        kpcr = obj.Object("_KPCR",
                          offset=obj.VolMagic(addr_space).KPCR.value,
                          vm=addr_space)
        kdbg = kpcr.get_kdbg()
        if kdbg.is_valid():
            return kdbg

    kdbg_magic = obj.VolMagic(addr_space).KDBG

    for kdbg in kdbg_magic.get_suggestions():

        if kdbg.is_valid():
            return kdbg

    # skip the KPCR backup method for x64
    memmode = addr_space.profile.metadata.get('memory_model', '32bit')

    version = (
        addr_space.profile.metadata.get('major', 0),
        addr_space.profile.metadata.get('minor', 0),
    )

    if memmode == '32bit' or version <= (6, 1):

        # Fall back to finding it via the KPCR. We cannot
        # accept the first/best suggestion, because only
        # the KPCR for the first CPU allows us to find KDBG.
        for kpcr_off in obj.VolMagic(addr_space).KPCR.get_suggestions():

            kpcr = obj.Object("_KPCR", offset=kpcr_off, vm=addr_space)

            kdbg = kpcr.get_kdbg()

            if kdbg.is_valid():
                return kdbg

    return obj.NoneObject(
        "KDDEBUGGER structure not found using either KDBG signature or KPCR pointer"
    )
Ejemplo n.º 3
0
    def calculate(self):
        """Determines the address space"""
        profilelist = [
            p.__name__
            for p in registry.get_plugin_classes(obj.Profile).values()
        ]

        encrypted_kdbg_profiles = []
        proflens = {}
        maxlen = 0
        origprofile = self._config.PROFILE
        for p in profilelist:
            self._config.update('PROFILE', p)
            buf = addrspace.BufferAddressSpace(self._config)
            if buf.profile.metadata.get('os', 'unknown') == 'windows':
                proflens[p] = str(obj.VolMagic(buf).KDBGHeader)
                maxlen = max(maxlen, len(proflens[p]))
                if (buf.profile.metadata.get('memory_model',
                                             '64bit') == '64bit'
                        and (buf.profile.metadata.get('major', 0),
                             buf.profile.metadata.get('minor', 0)) >= (6, 2)):
                    encrypted_kdbg_profiles.append(p)

        self._config.update('PROFILE', origprofile)
        # keep track of the number of potential KDBGs we find
        count = 0

        if origprofile not in encrypted_kdbg_profiles:
            scanner = KDBGScanner(needles=proflens.values())

            aspace = utils.load_as(self._config, astype='any')

            for offset in scanner.scan(aspace):
                val = aspace.read(offset, maxlen + 0x10)
                for l in proflens:
                    if val.find(proflens[l]) >= 0:
                        kdbg = obj.Object("_KDDEBUGGER_DATA64",
                                          offset=offset,
                                          vm=aspace)
                        yield l, kdbg
                        count += 1

        # only perform the special win8/2012 scan if we didn't find
        # any others and if a virtual x64 address space is available
        if count == 0:
            if origprofile in encrypted_kdbg_profiles:
                encrypted_kdbg_profiles = [origprofile]
            for profile in encrypted_kdbg_profiles:
                self._config.update('PROFILE', profile)
                aspace = utils.load_as(self._config, astype='any')
                if hasattr(aspace, 'vtop'):
                    for kdbg in obj.VolMagic(
                            aspace).KDBG.generate_suggestions():
                        yield profile, kdbg
Ejemplo n.º 4
0
def windows_kdbgscan_fast(dtb):
    global last_kdbg
    from utils import ConfigurationManager as conf_m

    try:
        config = conf_m.vol_conf
        config.DTB = dtb
        try:
            addr_space = utils.load_as(config)
        except BaseException:
            # Return silently
            conf_m.addr_space = None
            return 0L
        conf_m.addr_space = addr_space

        if obj.VolMagic(addr_space).KPCR.value:
            kpcr = obj.Object("_KPCR",
                              offset=obj.VolMagic(addr_space).KPCR.value,
                              vm=addr_space)
            kdbg = kpcr.get_kdbg()
            if kdbg.is_valid():
                last_kdbg = kdbg.obj_offset
                return long(last_kdbg)

        kdbg = obj.VolMagic(addr_space).KDBG.v()

        if kdbg.is_valid():
            last_kdbg = kdbg.obj_offset
            return long(last_kdbg)

        # skip the KPCR backup method for x64
        memmode = addr_space.profile.metadata.get('memory_model', '32bit')

        version = (addr_space.profile.metadata.get('major', 0),
                   addr_space.profile.metadata.get('minor', 0))

        if memmode == '32bit' or version <= (6, 1):

            # Fall back to finding it via the KPCR. We cannot
            # accept the first/best suggestion, because only
            # the KPCR for the first CPU allows us to find KDBG.
            for kpcr_off in obj.VolMagic(addr_space).KPCR.get_suggestions():

                kpcr = obj.Object("_KPCR", offset=kpcr_off, vm=addr_space)

                kdbg = kpcr.get_kdbg()

                if kdbg.is_valid():
                    last_kdbg = kdbg.obj_offset
                    return long(last_kdbg)
        return 0L
    except BaseException:
        traceback.print_exc()
Ejemplo n.º 5
0
    def __init__(self,
                 base,
                 config,
                 dtb=0,
                 skip_as_check=False,
                 *args,
                 **kwargs):
        ## We must be stacked on someone else:
        self.as_assert(base, "No base Address Space")

        addrspace.AbstractVirtualAddressSpace.__init__(self, base, config,
                                                       *args, **kwargs)

        ## We can not stack on someone with a dtb
        self.as_assert(
            not (hasattr(base, 'paging_address_space')
                 and base.paging_address_space),
            "Can not stack over another paging address space")

        self.dtb = dtb or self.load_dtb()
        # No need to set the base or dtb, it's already been by the inherited class

        self.as_assert(self.dtb != None, "No valid DTB found")

        if not skip_as_check:
            volmag = obj.VolMagic(self)
            if hasattr(volmag, self.checkname):
                self.as_assert(
                    getattr(volmag, self.checkname).v(),
                    "Failed valid Address Space check")
            else:
                self.as_assert(
                    False, "Profile does not have valid Address Space check")

        self.name = 'Kernel AS'
Ejemplo n.º 6
0
    def __init__(self, base, config, dtb = 0, *args, **kwargs):
        ## We must be stacked on someone else:
        self.as_assert(base, "No base Address Space")

        ## We allow users to disable us in favour of the old legacy
        ## modules.
        self.as_assert(not config.USE_OLD_AS, "Module disabled")
        standard.AbstractWritablePagedMemory.__init__(self, base, config, *args, **kwargs)
        addrspace.BaseAddressSpace.__init__(self, base, config, *args, **kwargs)

        ## We can not stack on someone with a dtb
        self.as_assert(not (hasattr(base, 'paging_address_space') and base.paging_address_space), "Can not stack over another paging address space")

        self.dtb = dtb or self.load_dtb()
#	print(str(hex(self.dtb)))
        # No need to set the base, it's already been by the inherited class

        self.as_assert(self.dtb != None, "No valid DTB found")

        # The caching code must be in a separate function to allow the
        # PAE code, which inherits us, to have its own code.
        self.cache = config.CACHE_DTB
        if self.cache:
            self._cache_values()

        volmag = obj.VolMagic(self)
        if hasattr(volmag, self.checkname):
            self.as_assert(getattr(volmag, self.checkname).v(), "Failed valid Address Space check")

        # Reserved for future use
        #self.pagefile = config.PAGEFILE
        self.name = 'Kernel AS'
Ejemplo n.º 7
0
    def calculate(self):
        """Determines the address space"""
        profilelist = [
            p.__name__
            for p in registry.get_plugin_classes(obj.Profile).values()
        ]

        proflens = {}
        maxlen = 0
        origprofile = self._config.PROFILE
        for p in profilelist:
            self._config.update('PROFILE', p)
            buf = addrspace.BufferAddressSpace(self._config)
            if buf.profile.metadata.get('os', 'unknown') == 'windows':
                proflens[p] = str(obj.VolMagic(buf).KDBGHeader)
                maxlen = max(maxlen, len(proflens[p]))
        self._config.update('PROFILE', origprofile)

        scanner = KDBGScanner(needles=proflens.values())

        aspace = utils.load_as(self._config, astype='any')

        for offset in scanner.scan(aspace):
            val = aspace.read(offset, maxlen + 0x10)
            for l in proflens:
                if val.find(proflens[l]) >= 0:
                    kdbg = obj.Object("_KDDEBUGGER_DATA64",
                                      offset=offset,
                                      vm=aspace)
                    yield l, kdbg
    def handles(self):
        """ A generator which yields this process's handles

        _HANDLE_TABLE tables are multi-level tables at the first level
        they are pointers to second level table, which might be
        pointers to third level tables etc, until the final table
        contains the real _OBJECT_HEADER table.

        This generator iterates over all the handles recursively
        yielding all handles. We take care of recursing into the
        nested tables automatically.
        """

        magic = obj.VolMagic(self.obj_vm)
        if hasattr(magic, 'ObHeaderCookie'):
            cookie = magic.ObHeaderCookie.v()
            if not cookie:
                raise StopIteration("Cannot find nt!ObHeaderCookie")

        # This should work equally for 32 and 64 bit systems
        LEVEL_MASK = 7

        TableCode = self.TableCode.v() & ~LEVEL_MASK
        table_levels = self.TableCode.v() & LEVEL_MASK
        offset = TableCode

        for h in self._make_handle_array(offset, table_levels):
            yield h
    def get_object_bottom_up(self, struct_name, object_type, skip_type_check):
        """Get the windows object contained within this pool
        by using the bottom-up approach to finding the object
        """

        if not object_type:
            return obj.Object(struct_name, vm = self.obj_vm, 
                        offset = self.obj_offset +
                        self.obj_vm.profile.get_obj_size("_POOL_HEADER"), 
                        native_vm = self.obj_native_vm)

        pool_alignment = obj.VolMagic(self.obj_vm).PoolAlignment.v()

        the_object = obj.Object(struct_name, vm = self.obj_vm, 
                        offset = (self.obj_offset + self.BlockSize * pool_alignment - 
                        common.pool_align(self.obj_vm, struct_name, pool_alignment)),
                        native_vm = self.obj_native_vm)

        header = the_object.get_object_header()

        if (skip_type_check or 
                    header.get_object_type() == object_type):
            return the_object
        else:
            return obj.NoneObject("Cannot find the object")
Ejemplo n.º 10
0
    def __init__(self, addr_space, scanners = [], scan_virtual = False, show_unalloc = False, use_top_down = False, start_offset = None, max_length = None):
        """An interface into the multiple concurrent pool scanner. 

        @param addr_space: a Volatility address space
        
        @param scanners: a list of PoolScanner classes to scan for. 

        @param scan_virtual: True to scan in virtual/kernel space 
        or False to scan at the physical layer.

        @param show_unalloc: True to skip unallocated objects whose
        _OBJECT_TYPE structure are 0xbad0b0b0. 

        @param use_topdown: True to carve objects out of the pool using
        the top-down approach or False to use the bottom-up trick.

        @param start_offset: the starting offset to begin scanning. 

        @param max_length: the size in bytes to scan from the start. 
        """

        self.scanners = scanners
        self.scan_virtual = scan_virtual
        self.show_unalloc = show_unalloc
        self.use_top_down = use_top_down
        self.start_offset = start_offset
        self.max_length = max_length

        self.address_space = addr_space
        self.pool_alignment = obj.VolMagic(self.address_space).PoolAlignment.v()
Ejemplo n.º 11
0
    def check(self, found):
        ## The offset of the object is determined by subtracting the offset
        ## of the PoolTag member to get the start of Pool Object. This done
        ## because PoolScanners search for the PoolTag.
        pool_base = found - self.address_space.profile.get_obj_offset(
            '_POOL_HEADER', 'PoolTag')

        pool_obj = obj.Object("_POOL_HEADER",
                              vm=self.address_space,
                              offset=pool_base)

        ## We work out the _EPROCESS from the end of the
        ## allocation (bottom up).
        pool_alignment = obj.VolMagic(self.address_space).PoolAlignment.v()
        eprocess = obj.Object(
            "_EPROCESS",
            vm=self.address_space,
            offset=pool_base + pool_obj.BlockSize * pool_alignment -
            common.pool_align(self.address_space, '_EPROCESS', pool_alignment))

        if (eprocess.Pcb.DirectoryTableBase == 0):
            return False

        if (eprocess.Pcb.DirectoryTableBase % 0x20 != 0):
            return False

        list_head = eprocess.ThreadListHead

        if (list_head.Flink < self.kernel) or (list_head.Blink < self.kernel):
            return False

        return True
Ejemplo n.º 12
0
 def generate_suggestions(self):
     """Generates a list of possible KDBG structure locations"""
     with UpdateCounterForScope('KDBGScanner'):
         scanner = kdbg.KDBGScanner(needles = [obj.VolMagic(self.obj_vm).KDBGHeader.v()])
         for val in scanner.scan(self.obj_vm):
             val = obj.Object("_KDDEBUGGER_DATA64", offset = val, vm = self.obj_vm)
             yield val
Ejemplo n.º 13
0
    def render_text(self, outfd, data):
        if self._config.DUMP_DIR == None:
            debug.error("Please specify a dump directory (--dump-dir)")
        if not os.path.isdir(self._config.DUMP_DIR):
            debug.error(self._config.DUMP_DIR + " is not a directory")

        self.table_header(outfd, [
            ("Pid", "10"),
            ("Process", "20"),
            ("Start", "[addrpad]"),
            ("End", "[addrpad]"),
            ("Result", ""),
        ])

        for task in data:
            # Walking the VAD tree can be done in kernel AS, but to
            # carve the actual data, we need a valid process AS.
            task_space = task.get_process_address_space()
            if not task_space:
                outfd.write("Unable to get process AS for {0}\n".format(
                    task.UniqueProcessId))
                continue

            max_commit = obj.VolMagic(task_space).MM_MAX_COMMIT.v()
            # as a first step, we try to get the physical offset of the
            # _EPROCESS object using the process address space
            offset = task_space.vtop(task.obj_offset)
            # if this fails, we'll get its physical offset using kernel space
            if offset == None:
                offset = task.obj_vm.vtop(task.obj_offset)
            # if this fails we'll manually set the offset to 0
            if offset == None:
                offset = 0

            for vad in task.VadRoot.traverse():
                if not vad.is_valid():
                    continue

                if self._config.BASE and vad.Start != self._config.BASE:
                    continue

                # Open the file and initialize the data

                vad_start = self.format_value(vad.Start, "[addrpad]")
                vad_end = self.format_value(vad.End, "[addrpad]")

                path = os.path.join(
                    self._config.DUMP_DIR,
                    "{0}.{1:x}.{2}-{3}.dmp".format(task.ImageFileName, offset,
                                                   vad_start, vad_end))

                if (task.IsWow64 and vad.CommitCharge == max_commit
                        and vad.End > 0x7fffffff):
                    result = "Skipping Wow64 MM_MAX_COMMIT range"
                else:
                    result = self.dump_vad(path, vad, task_space)

                self.table_row(outfd, task.UniqueProcessId, task.ImageFileName,
                               vad.Start, vad.End, result)
Ejemplo n.º 14
0
def get_system_time():
    from volatility import obj
    from utils import get_addr_space
    addr_space = get_addr_space()
    k = obj.Object("_KUSER_SHARED_DATA",
                   offset=obj.VolMagic(addr_space).KUSER_SHARED_DATA.v(),
                   vm=addr_space)
    return k.SystemTime.as_datetime()
Ejemplo n.º 15
0
    def TypeIndex(self):
        """Wrap the TypeIndex member with a property that decodes it 
        with the nt!ObHeaderCookie value."""

        cook = obj.VolMagic(self.obj_vm).ObHeaderCookie.v()
        addr = self.obj_offset
        indx = int(self.m("TypeIndex"))

        return ((addr >> 8) ^ cook ^ indx) & 0xFF
Ejemplo n.º 16
0
    def check(self, offset):
        pool_hdr = obj.Object('_POOL_HEADER', vm = self.address_space,
                             offset = offset - 4)

        block_size = pool_hdr.BlockSize.v()

        pool_alignment = obj.VolMagic(self.address_space).PoolAlignment.v()

        return self.condition(block_size * pool_alignment)
Ejemplo n.º 17
0
    def page_file_number(self):
        if not hasattr(self, "_page_file_number"):
            page_file_number = obj.VolMagic(self.paged_as).VSPageFileNumber.v()

            if not page_file_number:
                raise Exception("Invalid Virtual Store page file number value")

            self._page_file_number = page_file_number

        return self._page_file_number
Ejemplo n.º 18
0
 def render_text(self, outfd, data):
     for pool, buf in data:
         pool_alignment = obj.VolMagic(pool.obj_vm).PoolAlignment.v()
         outfd.write("Pool Header: {0:#x}, Size: {1}\n".format(
                 pool.obj_offset, 
                 pool.BlockSize * pool_alignment))
         outfd.write("{0}\n".format("\n".join(
                 ["{0:#010x}  {1:<48}  {2}".format(pool.obj_offset + o, h, ''.join(c))
                 for o, h, c in utils.Hexdump(buf)
                 ])))
         outfd.write("\n")
Ejemplo n.º 19
0
    def sm_globals(self):
        # May raise an exception which causes the AS to fail loading
        if not hasattr(self, "_sm_globals"):
            sm_globals = obj.VolMagic(self.paged_as).SmGlobals.v()

            if not sm_globals:
                raise Exception("Invalid nt!SmGlobals value")

            self._sm_globals = sm_globals

        return self._sm_globals
Ejemplo n.º 20
0
    def __init__(self, address_space):
        poolscan.PoolScanner.__init__(self, address_space)

        self.struct_name = "_OBJECT_SYMBOLIC_LINK"
        self.object_type = "SymbolicLink"
        self.pooltag = obj.VolMagic(address_space).SymlinkPoolTag.v()
        size = 0x48 # self.address_space.profile.get_obj_size("_OBJECT_SYMBOLIC_LINK")

        self.checks = [ 
               ('CheckPoolSize', dict(condition = lambda x: x >= size)),
               ('CheckPoolType', dict(paged = True, non_paged = True, free = True)),
               ]
Ejemplo n.º 21
0
 def load_dtb(self):
     try:
         ## Try to be lazy and see if someone else found dtb for
         ## us:
         return self.base.dtb
     except AttributeError:
         ## Ok so we need to find our dtb ourselves:
         dtb = obj.VolMagic(self.base).DTB.v()
         if dtb:
             ## Make sure to save dtb for other AS's
             self.base.dtb = dtb
             return dtb
Ejemplo n.º 22
0
    def __init__(self, address_space, **kwargs):
        poolscan.PoolScanner.__init__(self, address_space, **kwargs)

        self.struct_name = "_KMUTANT"
        self.object_type = "Mutant"
        self.pooltag = obj.VolMagic(address_space).MutexPoolTag.v()
        size = 0x40  # self.address_space.profile.get_obj_size("_KMUTANT")

        self.checks = [
            ('CheckPoolSize', dict(condition=lambda x: x >= size)),
            ('CheckPoolType', dict(paged=False, non_paged=True, free=True)),
            ('CheckPoolIndex', dict(value=lambda x: x < 5)),
        ]
Ejemplo n.º 23
0
    def __init__(self, address_space, **kwargs):
        poolscan.PoolScanner.__init__(self, address_space, **kwargs)

        self.struct_name = "_OBJECT_TYPE"
        self.object_type = "Type"
        self.pooltag = obj.VolMagic(address_space).ObjectTypePoolTag.v()
        size = 0xc8  # self.address_space.profile.get_obj_size("_OBJECT_TYPE")

        self.checks = [
            ('CheckPoolSize', dict(condition=lambda x: x >= size)),
            ('CheckPoolType', dict(paged=False, non_paged=True, free=True)),
            #('CheckPoolIndex', dict(value = 0)),
        ]
Ejemplo n.º 24
0
    def __init__(self, address_space):
        poolscan.PoolScanner.__init__(self, address_space)

        self.struct_name = "_FILE_OBJECT"
        self.object_type = "File"
        self.pooltag = obj.VolMagic(address_space).FilePoolTag.v()
        size = 0x98  # self.address_space.profile.get_obj_size("_FILE_OBJECT")

        self.checks = [
            ('CheckPoolSize', dict(condition=lambda x: x >= size)),
            ('CheckPoolType', dict(paged=False, non_paged=True, free=True)),
            ('CheckPoolIndex', dict(value=lambda x: x < 5)),
        ]
Ejemplo n.º 25
0
    def calculate(self):
        POOLSIZE_X86_AESDIFF = 976
        POOLSIZE_X86_AESONLY = 504
        POOLSIZE_X64_AESDIFF = 1008
        POOLSIZE_X64_AESONLY = 528

        OFFSET_DB = {
            POOLSIZE_X86_AESDIFF: {
                'CID': 24,
                'FVEK1': 32,
                'FVEK2': 504
            },
            POOLSIZE_X86_AESONLY: {
                'CID': 24,
                'FVEK1': 32,
                'FVEK2': 336
            },
            POOLSIZE_X64_AESDIFF: {
                'CID': 44,
                'FVEK1': 48,
                'FVEK2': 528
            },
            POOLSIZE_X64_AESONLY: {
                'CID': 44,
                'FVEK1': 48,
                'FVEK2': 480
            },
        }

        addr_space = utils.load_as(self._config)

        scanner = poolscan.SinglePoolScanner()
        scanner.checks = [
            ('PoolTagCheck', dict(tag='FVEc')),
            ('CheckPoolSize',
             dict(condition=lambda x: x in list(OFFSET_DB.keys()))),
        ]

        for addr in scanner.scan(addr_space):
            pool = obj.Object('_POOL_HEADER', offset=addr, vm=addr_space)

            pool_alignment = obj.VolMagic(pool.obj_vm).PoolAlignment.v()
            pool_size = int(pool.BlockSize * pool_alignment)

            cid = addr_space.zread(addr + OFFSET_DB[pool_size]['CID'], 2)
            fvek1 = addr_space.zread(addr + OFFSET_DB[pool_size]['FVEK1'], 32)
            fvek2 = addr_space.zread(addr + OFFSET_DB[pool_size]['FVEK2'], 32)

            if ord(cid[1]) == 0x80 and ord(cid[0]) <= 0x03:
                fvek = fvek1 + fvek2
                yield pool, cid, fvek
Ejemplo n.º 26
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

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

        tag = obj.VolMagic(addr_space).ServiceTag.v()

        # On systems more recent than XP/2003, the serH marker doesn't
        # find *all* services, but the ones it does find have linked
        # lists to the others. We use this variable to track which
        # ones we've seen so as to not yield duplicates.
        records = []

        for task in tasks.pslist(addr_space):
            # We only want the Service Control Manager process
            if str(task.ImageFileName).lower() != "services.exe":
                continue
            # Process AS must be valid
            process_space = task.get_process_address_space()
            if process_space == None:
                continue
            # Find all instances of the record tag
            for address in task.search_process_memory(
                [tag], vad_filter=lambda x: x.Length < 0x40000000):
                if version <= (5, 2):
                    # Windows XP/2003
                    rec = obj.Object("_SERVICE_RECORD",
                                     offset=address -
                                     addr_space.profile.get_obj_offset(
                                         '_SERVICE_RECORD', 'Tag'),
                                     vm=process_space)
                    # Apply our sanity checks
                    if rec.is_valid():
                        yield rec
                else:
                    # Windows Vista, 2008, and 7
                    svc_hdr = obj.Object('_SERVICE_HEADER',
                                         offset=address,
                                         vm=process_space)
                    # Apply our sanity checks
                    if svc_hdr.is_valid():
                        # Since we walk the s-list backwards, if we've seen
                        # an object, then we've also seen all objects that
                        # exist before it, thus we can break at that time.
                        for rec in svc_hdr.ServiceRecord.traverse():
                            if rec in records:
                                break
                            records.append(rec)
                            yield rec
Ejemplo n.º 27
0
    def get_image_time(self, addr_space):
        """Get the Image Datetime"""
        result = {}
        KUSER_SHARED_DATA = obj.VolMagic(addr_space).KUSER_SHARED_DATA.v()
        k = obj.Object("_KUSER_SHARED_DATA",
                       offset = KUSER_SHARED_DATA,
                       vm = addr_space)

        if k == None:
            return k
        result['ImageDatetime'] = k.SystemTime
        result['ImageTz'] = timefmt.OffsetTzInfo(-k.TimeZoneBias.as_windows_timestamp() / 10000000)

        return result
Ejemplo n.º 28
0
    def __init__(self,
                 base,
                 config,
                 dtb=0,
                 skip_as_check=False,
                 *args,
                 **kwargs):
        ## We must be stacked on someone else:
        self.as_assert(base, "No base Address Space")

        addrspace.AbstractVirtualAddressSpace.__init__(self, base, config,
                                                       *args, **kwargs)

        ## We can not stack on someone with a dtb
        self.as_assert(
            not (hasattr(base, 'paging_address_space')
                 and base.paging_address_space),
            "Can not stack over another paging address space")

        #rajesh
        if self.get_config().dtb:
            self.dtb = self.get_config().dtb
        else:
            self.dtb = dtb or self.load_dtb()

        if self.get_config().process_id:
            self.process_id = self.get_config().process_id
        else:
            self.process_id = 0

        logging.debug("AbstractPagedMemory dtb:{0} process_id:{1}".format(
            self.dtb, self.process_id))

        # No need to set the base or dtb, it's already been by the inherited class

        self.as_assert(self.dtb != None, "No valid DTB found")

        if not skip_as_check:
            volmag = obj.VolMagic(self)
            if hasattr(volmag, self.checkname):
                self.as_assert(
                    getattr(volmag, self.checkname).v(),
                    "Failed valid Address Space check")
            else:
                self.as_assert(
                    False, "Profile does not have valid Address Space check")

        # Reserved for future use
        #self.pagefile = config.PAGEFILE
        self.name = 'Kernel AS'
Ejemplo n.º 29
0
    def __init__(self, address_space):
        poolscan.PoolScanner.__init__(self, address_space)

        self.struct_name = "_ETHREAD"
        self.object_type = "Thread"
        # this allows us to find terminated threads
        self.skip_type_check = True
        self.pooltag = obj.VolMagic(address_space).ThreadPoolTag.v()
        size = 0x278 # self.address_space.profile.get_obj_size("_ETHREAD")

        self.checks = [
               ('CheckPoolSize', dict(condition = lambda x: x >= size)),
               ('CheckPoolType', dict(paged = False, non_paged = True, free = True)),
               ('CheckPoolIndex', dict(value = lambda x : x < 5)),
               ]
Ejemplo n.º 30
0
    def __init__(self, address_space, **kwargs):
        poolscan.PoolScanner.__init__(self, address_space, **kwargs)

        self.struct_name = "_EPROCESS"
        self.object_type = "Process"
        # this allows us to find terminated processes 
        self.skip_type_check = True
        self.pooltag = obj.VolMagic(address_space).ProcessPoolTag.v()
        size = 0x1ae # self.address_space.profile.get_obj_size("_EPROCESS")

        self.checks = [ 
                ('CheckPoolSize', dict(condition = lambda x: x >= size)),
                ('CheckPoolType', dict(paged = False, non_paged = True, free = True)),
                ('CheckPoolIndex', dict(value = 0)),
                ]