Re: [ctypes-users] How come this is different?
Brought to you by:
theller
From: Michael C <mys...@gm...> - 2016-12-10 23:27:08
|
i have to go to work, will take a look later! thx! On Sat, Dec 10, 2016 at 3:25 PM eryk sun <er...@gm...> wrote: > On Sat, Dec 10, 2016 at 9:30 PM, Michael C > > <mys...@gm...> wrote: > > > I am stuck on which line of information to feed to ReadmemoryProcess with > > > this, I think I properly retrieved the information from Virtualqueryex > > > > Here's an example that uses VirtualQueryEx to determine whether the > > specified address is allocated and readable. If so, it reads up to > > `count` double-precision floats via ReadProcessMemory, but it won't > > read past the allocated region size. > > > > import ctypes > > from ctypes import wintypes > > > > kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) > > > > PROCESS_VM_READ = 0x0010 > > PROCESS_QUERY_INFORMATION = 0x0400 > > > > MEM_COMMIT = 0x00001000 > > MEM_RESERVE = 0x00002000 > > MEM_FREE = 0x00010000 > > MEM_PRIVATE = 0x00020000 > > MEM_MAPPED = 0x00040000 > > MEM_IMAGE = 0x01000000 > > > > PAGE_NOACCESS = 0x00000001 > > PAGE_READONLY = 0x00000002 > > PAGE_READWRITE = 0x00000004 > > PAGE_WRITECOPY = 0x00000008 > > PAGE_EXECUTE = 0x00000010 > > PAGE_EXECUTE_READ = 0x00000020 > > PAGE_EXECUTE_READWRITE = 0x00000040 > > PAGE_EXECUTE_WRITECOPY = 0x00000080 > > PAGE_GUARD = 0x00000100 > > PAGE_NOCACHE = 0x00000200 > > PAGE_WRITECOMBINE = 0x00000400 > > PAGE_TARGETS_INVALID = 0x40000000 > > > > if not hasattr(wintypes, 'PVOID'): > > wintypes.PVOID = wintypes.LPVOID > > > > if not hasattr(wintypes, 'SIZE_T'): > > wintypes.SIZE_T = ctypes.c_size_t > > > > if not hasattr(wintypes, 'PSIZE_T'): > > wintypes.PSIZE_T = ctypes.POINTER(wintypes.SIZE_T) > > > > class MEMORY_BASIC_INFORMATION(ctypes.Structure): > > _fields_ = (('BaseAddress', wintypes.PVOID), > > ('AllocationBase', wintypes.PVOID), > > ('AllocationProtect', wintypes.DWORD), > > ('RegionSize', wintypes.SIZE_T), > > ('State', wintypes.DWORD), > > ('Protect', wintypes.DWORD), > > ('Type', wintypes.DWORD)) > > > > PMEMORY_BASIC_INFORMATION = ctypes.POINTER(MEMORY_BASIC_INFORMATION) > > > > def _check_zero(result, func, args): > > """ Check for zero or NULL return value. """ > > if not result: > > raise ctypes.WinError(ctypes.get_last_error()) > > return args > > > > # https://msdn.microsoft.com/en-us/library/ms683179 > > kernel32.GetCurrentProcess.restype = wintypes.HANDLE > > > > # https://msdn.microsoft.com/en-us/library/ms684320 > > kernel32.OpenProcess.errcheck = _check_zero > > kernel32.OpenProcess.restype = wintypes.HANDLE > > > > # https://msdn.microsoft.com/en-us/library/ms680553 > > kernel32.ReadProcessMemory.errcheck = _check_zero > > kernel32.ReadProcessMemory.argtypes = ( > > wintypes.HANDLE, # _In_ hProcess > > wintypes.LPCVOID, # _In_ lpBaseAddress > > wintypes.LPVOID, # _Out_ lpBuffer > > wintypes.SIZE_T, # _In_ nSize > > wintypes.PSIZE_T) # _Out_ lpNumberOfBytesRead > > > > # https://msdn.microsoft.com/en-us/library/aa366907 > > kernel32.VirtualQueryEx.errcheck = _check_zero > > kernel32.VirtualQueryEx.restype = wintypes.SIZE_T > > kernel32.VirtualQueryEx.argtypes = ( > > wintypes.HANDLE, # _In_ hProcess > > wintypes.LPCVOID, # _In_opt_ lpAddress > > PMEMORY_BASIC_INFORMATION, # _Out_ lpBuffer > > wintypes.SIZE_T) # _In_ dwLength > > > > if __name__ == '__main__': > > import sys > > > > dtype = ctypes.c_double > > > > if len(sys.argv) == 4: > > ph = kernel32.OpenProcess(PROCESS_QUERY_INFORMATION | > > PROCESS_VM_READ, False, int(sys.argv[1])) > > address = int(sys.argv[2], 16) > > count = int(sys.argv[3]) > > elif len(sys.argv) == 1: > > ph = kernel32.GetCurrentProcess() > > count = 10 > > source_array = (dtype * count)(*range(10)) > > address = ctypes.addressof(source_array) > > else: > > sys.exit('Usage: %s pid address count' % sys.argv[0]) > > > > mbi = MEMORY_BASIC_INFORMATION() > > kernel32.VirtualQueryEx(ph, address, ctypes.byref(mbi), > > ctypes.sizeof(mbi)) > > > > if mbi.State & MEM_FREE: > > sys.exit('Address not allocated') > > if mbi.State & MEM_RESERVE: > > sys.exit('Address reserved but not committed') > > if mbi.Protect & PAGE_NOACCESS: > > sys.exit('Address not accessible') > > > > block_size = min(mbi.RegionSize - (address - mbi.BaseAddress), > > ctypes.sizeof(dtype) * count) > > address_list = range(address, address + block_size, > > ctypes.sizeof(dtype)) > > > > input('Press enter to list %d values, or Ctrl+Break to quit\n' > > % len(address_list)) > > > > data = dtype() > > for address in address_list: > > kernel32.ReadProcessMemory(ph, address, ctypes.byref(data), > > ctypes.sizeof(data), None) > > print('%x: %f' % (address, data.value)) > > |