Example #1
0
    def pid_generator(self, cb, addr_space, profile):
        for p in pslist(addr_space, profile):
            pid = p.UniqueProcessId.v()

            ## We only print the handles from the pid or if not provided all pids:
            if self.opts.pid == None or (pid == self.opts.pid):
                yield p, cb(p)
Example #2
0
    def pid_generator(self, cb, addr_space, profile):
        for p in pslist(addr_space, profile):
            pid = p.UniqueProcessId.v()

            ## We only print the handles from the pid or if not provided all pids:
            if self.opts.pid == None or (pid == self.opts.pid):
                yield p, cb(p)
Example #3
0
    def execute(self):
        from vtypes import xpsp2types
        
        xpsp2types['_ETHREAD'][1]['ThreadListEntry'] = [ 0x22c, ['_LIST_ENTRY']]
        xpsp2types['_KTHREAD'][1]['ServiceTable']  = [ 0xe0, ['pointer', ['_SERVICE_DESCRIPTOR_TABLE']]]

        profile = Profile()
        profile.add_types(ssdt_types)

	(addr_space, symtab, types) = load_and_identify_image(self.op,
            self.opts)

        ## Get a sorted list of module addresses
        mods = dict( (mod.BaseAddress.v(),mod) for mod in lsmod(addr_space, profile) )
        mod_addrs = sorted(mods.keys())

        # Gather up all SSDTs referenced by threads
        print "Gathering all referenced SSDTs from KTHREADs..."
        ssdts = set()
        for proc in pslist(addr_space, profile):
            for thread in proc.ThreadListHead.list_of_type("_ETHREAD", "ThreadListEntry"):
                ssdt = thread.Tcb.ServiceTable.dereference()
                ssdts.add(ssdt)

        # Get a list of *unique* SSDT entries. Typically we see only two.
        tables = set()
        
        for ssdt in ssdts:
            for i,desc in enumerate(ssdt.Descriptors):
                if desc.is_valid() and desc.ServiceLimit != 0:
                    tables.add((i,desc.KiServiceTable.v(),desc.ServiceLimit.v()))

        print "Finding appropriate address space for tables..."
        tables_with_vm = []
        for idx, table, n in tables:
            found = False
            for p in pslist(addr_space, profile):
                ## This is the process address space
                ps_ad = p.get_process_address_space()
                ## Is the table accessible from the process AS?
                if ps_ad.is_valid_address(table):
                    tables_with_vm.append( (idx, table, n, ps_ad) )
                    found = True
                    break
            ## If not we use the kernel address space
            if not found:
                # Any VM is equally bad...
                tables_with_vm.append( (idx, table, n, addr_space) )

        # Print out the entries for each table
        for idx,table,n,vm in sorted(tables_with_vm, key=itemgetter(0)):
            print "SSDT[%d] at %x with %d entries" % (idx,table, n)
            if vm.is_valid_address(table):
                for i in range(n):
                    syscall_addr = NewObject('unsigned long', table+(i*4), vm, profile=profile).v()
                    try:
                        syscall_name = xpsp2_syscalls[idx][i]
                    except IndexError:
                        syscall_name = "Unknown"

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

                    print "  Entry %#06x: %#x (%s) owned by %s" % (idx*0x1000+i,
                                                                       syscall_addr,
                                                                       syscall_name,
                                                                       syscall_modname)
            else:
                print "  [SSDT not resident at 0x%08X ]" % table
Example #4
0
    def execute(self):
        from vtypes import xpsp2types

        xpsp2types['_ETHREAD'][1]['ThreadListEntry'] = [0x22c, ['_LIST_ENTRY']]
        xpsp2types['_KTHREAD'][1]['ServiceTable'] = [
            0xe0, ['pointer', ['_SERVICE_DESCRIPTOR_TABLE']]
        ]

        profile = Profile()
        profile.add_types(ssdt_types)

        (addr_space, symtab,
         types) = load_and_identify_image(self.op, self.opts)

        ## Get a sorted list of module addresses
        mods = dict(
            (mod.BaseAddress.v(), mod) for mod in lsmod(addr_space, profile))
        mod_addrs = sorted(mods.keys())

        # Gather up all SSDTs referenced by threads
        print "Gathering all referenced SSDTs from KTHREADs..."
        ssdts = set()
        for proc in pslist(addr_space, profile):
            for thread in proc.ThreadListHead.list_of_type(
                    "_ETHREAD", "ThreadListEntry"):
                ssdt = thread.Tcb.ServiceTable.dereference()
                ssdts.add(ssdt)

        # Get a list of *unique* SSDT entries. Typically we see only two.
        tables = set()

        for ssdt in ssdts:
            for i, desc in enumerate(ssdt.Descriptors):
                if desc.is_valid() and desc.ServiceLimit != 0:
                    tables.add(
                        (i, desc.KiServiceTable.v(), desc.ServiceLimit.v()))

        print "Finding appropriate address space for tables..."
        tables_with_vm = []
        for idx, table, n in tables:
            found = False
            for p in pslist(addr_space, profile):
                ## This is the process address space
                ps_ad = p.get_process_address_space()
                ## Is the table accessible from the process AS?
                if ps_ad.is_valid_address(table):
                    tables_with_vm.append((idx, table, n, ps_ad))
                    found = True
                    break
            ## If not we use the kernel address space
            if not found:
                # Any VM is equally bad...
                tables_with_vm.append((idx, table, n, addr_space))

        # Print out the entries for each table
        for idx, table, n, vm in sorted(tables_with_vm, key=itemgetter(0)):
            print "SSDT[%d] at %x with %d entries" % (idx, table, n)
            if vm.is_valid_address(table):
                for i in range(n):
                    syscall_addr = NewObject('unsigned long',
                                             table + (i * 4),
                                             vm,
                                             profile=profile).v()
                    try:
                        syscall_name = xpsp2_syscalls[idx][i]
                    except IndexError:
                        syscall_name = "Unknown"

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

                    print "  Entry %#06x: %#x (%s) owned by %s" % (
                        idx * 0x1000 + i, syscall_addr, syscall_name,
                        syscall_modname)
            else:
                print "  [SSDT not resident at 0x%08X ]" % table