def testWriteDWords(self): testArray = pykd.loadDWords(target.module.ulongArray, 5) pykd.writeDWords(target.module.ulongArrayPlace, testArray) ulongArray = pykd.loadDWords(target.module.ulongArrayPlace, 5) self.assertEqual( 0, len([ ulongArray[i] for i in range(5) if ulongArray[i] != testArray[i] ]))
def DumpOperand(self, operand): operand_type = operand['Type'] value = '' pointer = 0 if operand_type == 'Displacement': base = pykd.reg(operand['Base']) if operand['Index']: index = pykd.reg(operand['Index']) else: index = 0 offset = operand['Offset'] if offset: if operand['Offset'] & 0x80000000: offset = (0x100000000 - offset) * -1 pointer = base + index + offset elif operand_type == 'Register': value = pykd.reg(operand['Value']) elif operand_type == 'Memory': pointer = operand['Value'] elif operand_type == 'Near': pass else: pass if pointer > 0: (value, ) = pykd.loadDWords(pointer, 1) return value
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 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 testLoadDWords(self): loadArray = pykd.loadDWords(target.module.ulongArray, 5) testArray = [0, 0xFF, 0x8000, 0x80000000, 0xFFFFFFFF] 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(): 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 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 show_stack(self): print('* Stack----') for dword in pykd.loadDWords(pykd.reg("esp"), 5): print('%x' % dword)
def HandleBreakpoint(self): eip = self.Debugger.GetEIP() if eip in self.BreakpointsMap: record = {'Address': eip} record['Type'] = 'Enter' record['Module'] = self.BreakpointsMap[eip]['Module'] record['RVA'] = self.BreakpointsMap[eip]['RVA'] record['Symbol'] = self.BreakpointsMap[eip]['Symbol'] record['ThreadContext'] = self.Debugger.GetThreadContext() esp = self.Debugger.GetESP() record['StackPointer'] = esp record['DumpTargets'] = [] if record['Symbol']: self.Logger.info('> %s!%s (+%.8x) (%.8x)' % (record['Module'], record['Symbol'], record['RVA'], record['Address'])) for dump_target in self.BreakpointsMap[eip]['DumpTargets']: if dump_target['Type'] == 'Operand': dump_result = {} dump_result['Operand'] = self.DumpOperand( dump_target['Value']) if dump_target['DataType'] == 'Pointer': try: bytes = self.Debugger.GetBytes( parameter_values[index], 0x100) dump_result['Bytes'] = base64.b64encode(bytes) except: pass elif dump_target['Type'] == 'Parameters': (parameter_map, dump_result) = self.DumpParameters(dump_target['Value']) elif dump_target['Type'] == 'ReturnParameters' and len( dump_target['Value']) > 0: return_address = self.Debugger.GetReturnAddress() for (parameter_name, dump_instruction) in dump_target['Value'].items(): if dump_instruction['Length']['Type'] == 'Parameter': parameter_length = parameter_map[ dump_instruction['Length']['Value']] else: parameter_length = 0 self.ReturnBreakpointsMap[return_address] = { 'Type': 'ReturnParameter', 'EIP': eip, 'DumpInstruction': dump_instruction, 'Pointer': parameter_map[parameter_name], 'Length': parameter_length } bp = self.SetBp(return_address, self.HandleReturnBreakpoint) self.Logger.info('\tSet Return BP on %.8x - %d' % (return_address, bp.getId())) elif dump_target['Type'] == 'Function': dump_result = [] for (arg_name, arg_offset) in dump_target['Args']: arg_addr = esp + arg_offset (arg_value, ) = pykd.loadDWords(arg_addr, 1) try: bytes = self.Debugger.GetBytes(arg_value, 0x100) base64_bytes = base64.b64encode(bytes) except: base64_bytes = '' dump_result.append({ 'Name': arg_name, 'Value': arg_value, 'Bytes': base64_bytes }) else: dump_result = [] record['DumpTargets'].append({ 'Target': dump_target, 'Value': dump_result }) if self.RecordsDB: self.RecordsDB.WriteRecord(record) else: self.Logger.info(pprint.pformat(record)) else: self.Logger.info('> BP @%.8x' % eip)
def DumpModuleParams(self, bp_type, module_base, dump_targets): dump_outputs = [] if bp_type == 'Function': dump_targets_values = pykd.loadDWords( pykd.reg("esp") + 4, len(dump_targets)) arg_i = 0 for (arg_type, dump_target_name) in dump_targets: dump_output = '' if arg_type == "LPCWSTR": dump_output = self.Debugger.RunCmd( "du %.8x" % dump_targets_values[arg_i]) elif arg_type == "DWORD" or "HANDLE": dump_output = "%.8x" % dump_targets_values[arg_i] else: dump_output = "%.8x" % dump_targets_values[arg_i] dump_output_item = {} dump_output_item['DumpTargetName'] = dump_target_name dump_output_item['ArgPosition'] = i dump_output_item['DumpOutput'] = dump_output dump_outputs.append(dump_output_item) self.loggger.debug("%s (%s):\n%s" % (dump_target_name, arg_type, dump_output)) arg_i += 1 elif bp_type == 'Instruction': for dump_target in dump_targets: arg_type = dump_target['Type'] data_type = dump_target['DataType'] dump_target_name = '' dump_output = '' if arg_type == "Register": dump_target_name = dump_target['Value'] dump_output = "%.8x" % pykd.reg(str(dump_target_name)) elif arg_type == "Memory" or arg_type == "Displacement" or arg_type == "Phrase": memory_str = dump_target['Base'] if dump_target['Index']: memory_str += '+%s*%x' % (dump_target['Index'], dump_target['Scale']) if arg_type == "Memory": memory_str += '+%x' % (module_base + dump_target['Address']) elif arg_type == "Displacement": memory_str += '+%x' % dump_target['Offset'] dump_target_name = memory_str if data_type == 'Byte': d_cmd = 'db' d_length = 10 elif data_type == 'Word': d_cmd = 'dw' d_length = 10 elif data_type == 'DWORD': d_cmd = 'dd' d_length = 10 dump_output = self.Debugger.RunCmd( "%s %s L%x" % (d_cmd, memory_str, d_length)) if dump_target_name: dump_output_item = {} dump_output_item['DumpTargetName'] = dump_target_name dump_output_item['Position'] = dump_target['Position'] dump_output_item['DumpOutput'] = dump_output dump_outputs.append(dump_output_item) if dump_output.find('\n'): self.loggger.debug("%s (%s):" % (dump_target_name, arg_type)) for line in dump_output.splitlines(): self.loggger.debug("\t%s" % (line)) else: self.loggger.debug( "%s (%s): %s" % (dump_target_name, arg_type, dump_output)) return dump_outputs
def read_dwords(addr, size): if get_dword_size() == 4: return pykd.loadDWords(addr, size) else: return pykd.loadQWords(addr, size)
def read_dwords(addr, size): if get_dword_size() == 4: return pykd.loadDWords(addr, size) else: return pykd.loadQWords(addr, size)