def get_call_parameters(self, count, is_syscall = False): if is_syscall: bits = 64 #TODO: support 32 bit parameter_values = pykd.loadQWords(pykd.reg("r10"), len(parameter_definition)) else: parameters = [] try: bits = 64 parameters = [] if count>0: parameters.append(pykd.reg("rcx")) if count>1: parameters.append(pykd.reg("rdx")) if count>2: parameters.append(pykd.reg("r8")) if count>3: parameters.append(pykd.reg("r9")) if count>4: try: rsp = pykd.reg("rsp") parameters+= pykd.loadQWords(rsp+8, count-4) except: self.Logger.info('Accessing memory %x failed', rsp+8) except: bits = 32 esp = pykd.reg("esp") try: parameters = pykd.loadDWords(esp+4, count) except: self.Logger.info('Accessing memory %x failed', esp) return (bits, parameters)
def parse_pool(self): print("[+] from standardalloclist") pool = 0 if self.alloc_size == 0x50: pool = STANDARDALLOCLIST[0] elif self.alloc_size == 0x68: pool = STANDARDALLOCLIST[1] elif self.alloc_size == 0x88: pool = STANDARDALLOCLIST[2] elif self.alloc_size == 0xa0: pool = STANDARDALLOCLIST[3] _free_pool = [] free_ptr = pykd.loadQWords(pool, 1)[0] print("[+] 0x%x" % (free_ptr), end='') col = 0 for i in range(0x55): if free_ptr == 0x0: break _free_pool.append(free_ptr) if pykd.loadBytes(free_ptr + 4, 1)[0] == 0xee: # free next_ptr = pykd.loadQWords(free_ptr + 8, 1)[0] free_ptr = next_ptr print(" -> 0x%x " % (next_ptr), end='') elif pykd.loadBytes(free_ptr + 4, 1)[0] == 0xbb: print(" 0x%x in use" % free_ptr) col = +1 if col >= 8: print("") col = 0 print("")
def testWriteQWords(self): testArray = pykd.loadQWords(target.module.ulonglongArray, 5) pykd.writeQWords(target.module.ulonglongArrayPlace, testArray) ulonglongArray = pykd.loadQWords(target.module.ulonglongArrayPlace, 5) self.assertEqual( 0, len([ ulonglongArray[i] for i in range(5) if ulonglongArray[i] != testArray[i] ]))
def get_arguments(self, count): arguments = [] if self.debugger.get_arch() == 'AMD64': arguments.append(pykd.reg('rcx')) count -= 1 if count > 0: arguments.append(pykd.reg('rdx')) count -= 1 if count > 0: arguments.append(pykd.reg('r8')) count -= 1 if count > 0: arguments.append(pykd.reg('r9')) count -= 1 if count > 0: rsp = pykd.reg('rsp') arguments += pykd.loadQWords(int(rsp + 8), count) else: esp = pykd.reg('esp') arguments += pykd.loadDWords(int(esp + 4), count) return arguments
def main(): nt_module = pykd.module("nt") ObpTypeDirectoryObject_addr = int(nt_module.ObpTypeDirectoryObject) ObpTypeDirectoryObject_value = pykd.loadQWords(ObpTypeDirectoryObject_addr, 1)[0] dict_entry_list = pykd.loadQWords(ObpTypeDirectoryObject_value, 37) print 'TypeName PoolTag PoolType' for dict_entry in dict_entry_list: if dict_entry == 0: continue type_obj_addr = pykd.loadQWords(dict_entry + 8, 1)[0] name_str = pykd.loadUnicodeString(type_obj_addr + 0x10) key_str = pykd.loadCStr(type_obj_addr + 0xc0) pool_type = pykd.loadDWords(type_obj_addr + 0x40 + 0x24, 1)[0] if pool_type == 1: pool_type = 'PagedPool' elif pool_type == 0x200: pool_type = 'NonPagedPoolNx' print '%s\n%s\n%s\n' % (name_str, key_str, pool_type)
def testLoadQWords(self): loadArray = pykd.loadQWords(target.module.ulonglongArray, 5) testArray = [ 0, 0xFF, 0xFFFFFFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF ] self.assertEqual(len(testArray), len(loadArray)) self.assertEqual( 0, len([ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ]))
def get_return_address(self): sp = self.get_stack_pointer() try: if self.get_arch() == 'AMD64': return pykd.loadQWords(sp, 1)[0] else: return pykd.loadDWords(sp, 1)[0] except: logging.info('Accessing memory %x failed', sp) return 0
def examine_data(value, step=4): try: out = pykd.loadQWords(value,1)[0] if step==8 else pykd.loadDWords(value,1)[0] if self.is_address(out): return out except: return value str = pykd.loadCStr(value) #str = pykd.loadWStr(value) if is_printable(str): if len(str)<step: return "%x \"%s\"" % (out, str) return str return out
def get_return_address(self): try: rsp = pykd.reg("rsp") try: return pykd.loadQWords(rsp, 1)[0] except: self.Logger.info('Accessing memory %x failed', rsp) except: esp = pykd.reg("esp") try: return pykd.loadDWords(esp, 1)[0] except: self.Logger.info('Accessing memory %x failed', esp) return 0
def dumpmem(self, start, count=0, step=''): result = [] step = self._target()['addr_size'] if not dc: dc = "d%s" % ("q" if step == 8 else "d") if count is not None: try: ret = pykd.loadQWords(value,count) if step==8 else pykd.loadDWords(value,count) except: error_msg("dump memory failed") return "" if result: return result[:count] else: return result
def main(argv): if len(argv) == 0: print "Usage: !py filter.py from_level to_level filtered" print "Filtered syscalls for 5th level: !py filter.py 5 5 1" exit(-1) ntMod = pykd.module("nt") KeServiceDescriptorTableFilter = int(ntMod.KeServiceDescriptorTableFilter) win32Mod = pykd.module("win32k") W32pServiceTableFilter = int(win32Mod.W32pServiceTableFilter) W32pServiceLimitFilter = pykd.loadDWords(win32Mod.W32pServiceLimitFilter, 1)[0] + 0x1000 print '[*]W32pServiceTableFilter Address:' print '[*]'+str(hex(W32pServiceTableFilter)) win32BaseMod = pykd.module("win32kbase") gaWin32KFilterBitmap = int(win32BaseMod.gaWin32KFilterBitmap) print '[*]gaWin32KFilterBitmap Address:' print '[*]'+str(hex(gaWin32KFilterBitmap)) start_level = int(argv[0]) end_level = int(argv[1]) filter = int(argv[2]) sum = 0 syscallsLimit = W32pServiceLimitFilter - 0x1000 for i in range(start_level, end_level + 1): bitmap = pykd.loadQWords(gaWin32KFilterBitmap + i * 8, 1)[0] print '[*]=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=' print '[*]Bitmap filter level ' + str(hex(i)) if filter: print '[*]Show Filtered' else: print '[*]Show Unfiltered' if not bitmap: print '[*] None' continue # Check SSSDT ID for 0x1000 for j in range(0x1000, W32pServiceLimitFilter): # bit index in byte syscallNum = j & 0xfff # function offset in W32pServiceTableFilter offset = pykd.loadDWords(W32pServiceTableFilter + syscallNum * 4, 1)[0] offset = (0xfffffffff0000000 | (offset >> 4)) # function address syscall = W32pServiceTableFilter + offset syscall = syscall % 2**64 # check check_byte = pykd.loadBytes(bitmap + (syscallNum >> 3), 1)[0] filtered = check_byte & (1 << (syscallNum & 7)) filtered = filtered != 0 # 1 is filtered,0 is unfiltered if filtered == filter: sum = sum + 1 print '[*]'+pykd.findSymbol(syscall) + ' ' + hex(j) if filter: print "[*]number of filtered system calls" else: print "[*]number of allowed system calls" print '[*]'+str(syscallsLimit) + "/" + str(sum) exit(0)
def read_dwords(addr, size): if get_dword_size() == 4: return pykd.loadDWords(addr, size) else: return pykd.loadQWords(addr, size)