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)
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
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