-
Notifications
You must be signed in to change notification settings - Fork 0
/
readmemwin.py
63 lines (51 loc) · 1.84 KB
/
readmemwin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import ctypes
from ctypes import wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
ERROR_PARTIAL_COPY = 0x012B
PROCESS_VM_READ = 0x0010
SIZE_T = ctypes.c_size_t
PSIZE_T = ctypes.POINTER(SIZE_T)
def _check_zero(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
kernel32.OpenProcess.errcheck = _check_zero
kernel32.OpenProcess.restype = wintypes.HANDLE
kernel32.OpenProcess.argtypes = (
wintypes.DWORD, # _In_ dwDesiredAccess
wintypes.BOOL, # _In_ bInheritHandle
wintypes.DWORD) # _In_ dwProcessId
kernel32.ReadProcessMemory.errcheck = _check_zero
kernel32.ReadProcessMemory.argtypes = (
wintypes.HANDLE, # _In_ hProcess
wintypes.LPCVOID, # _In_ lpBaseAddress
wintypes.LPVOID, # _Out_ lpBuffer
SIZE_T, # _In_ nSize
PSIZE_T) # _Out_ lpNumberOfBytesRead
kernel32.CloseHandle.argtypes = (wintypes.HANDLE,)
def read_process_memory(pid, address, size, allow_partial=False):
buf = (ctypes.c_char * size)()
nread = SIZE_T()
hProcess = kernel32.OpenProcess(PROCESS_VM_READ, False, pid)
try:
kernel32.ReadProcessMemory(hProcess, address, buf, size,
ctypes.byref(nread))
except WindowsError as e:
if not allow_partial or e.winerror != ERROR_PARTIAL_COPY:
raise
finally:
kernel32.CloseHandle(hProcess)
return buf[:nread.value]
if __name__ == '__main__':
import os
import sys
# buf = ctypes.create_string_buffer(b'abcdefghij')
# pid = os.getpid()
address = ctypes.addressof(ctypes.create_string_buffer(b'flag'))
# size = len(buf.value)
pid = 6468
address = 0xcb230
size = 100
value = read_process_memory(pid, address, size)
print value
# assert value == buf.value