1from minidump.utils.winapi.defines import *
2import enum
3
4
5# DWORD WINAPI GetLastError(void);
6def GetLastError():
7    _GetLastError = windll.kernel32.GetLastError
8    _GetLastError.argtypes = []
9    _GetLastError.restype  = DWORD
10    return _GetLastError()
11
12class WindowsMinBuild(enum.Enum):
13	WIN_XP = 2500
14	WIN_2K3 = 3000
15	WIN_VISTA = 5000
16	WIN_7 = 7000
17	WIN_8 = 8000
18	WIN_BLUE = 9400
19	WIN_10 = 9800
20
21#utter microsoft bullshit commencing..
22def getWindowsBuild():
23    class OSVersionInfo(ctypes.Structure):
24        _fields_ = [
25            ("dwOSVersionInfoSize" , ctypes.c_int),
26            ("dwMajorVersion"      , ctypes.c_int),
27            ("dwMinorVersion"      , ctypes.c_int),
28            ("dwBuildNumber"       , ctypes.c_int),
29            ("dwPlatformId"        , ctypes.c_int),
30            ("szCSDVersion"        , ctypes.c_char*128)];
31    GetVersionEx = getattr( ctypes.windll.kernel32 , "GetVersionExA")
32    version  = OSVersionInfo()
33    version.dwOSVersionInfoSize = ctypes.sizeof(OSVersionInfo)
34    GetVersionEx( ctypes.byref(version) )
35    return version.dwBuildNumber
36
37def get_all_access_flags():
38    DELETE = 0x00010000
39    READ_CONTROL = 0x00020000
40    WRITE_DAC = 0x00040000
41    WRITE_OWNER = 0x00080000
42
43    SYNCHRONIZE = 0x00100000
44
45    STANDARD_RIGHTS_REQUIRED = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER
46    STANDARD_RIGHTS_ALL = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE
47
48    if getWindowsBuild() >= WindowsMinBuild.WIN_VISTA.value:
49        return STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF
50    else:
51        return STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF
52
53PROCESS_ALL_ACCESS = get_all_access_flags()
54
55# Process access rights for OpenProcess
56PROCESS_TERMINATE                 = 0x0001
57PROCESS_CREATE_THREAD             = 0x0002
58PROCESS_SET_SESSIONID             = 0x0004
59PROCESS_VM_OPERATION              = 0x0008
60PROCESS_VM_READ                   = 0x0010
61PROCESS_VM_WRITE                  = 0x0020
62PROCESS_DUP_HANDLE                = 0x0040
63PROCESS_CREATE_PROCESS            = 0x0080
64PROCESS_SET_QUOTA                 = 0x0100
65PROCESS_SET_INFORMATION           = 0x0200
66PROCESS_QUERY_INFORMATION         = 0x0400
67PROCESS_SUSPEND_RESUME            = 0x0800
68PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
69
70# Thread access rights for OpenThread
71THREAD_TERMINATE                 = 0x0001
72THREAD_SUSPEND_RESUME            = 0x0002
73THREAD_ALERT                     = 0x0004
74THREAD_GET_CONTEXT               = 0x0008
75THREAD_SET_CONTEXT               = 0x0010
76THREAD_SET_INFORMATION           = 0x0020
77THREAD_QUERY_INFORMATION         = 0x0040
78THREAD_SET_THREAD_TOKEN          = 0x0080
79THREAD_IMPERSONATE               = 0x0100
80THREAD_DIRECT_IMPERSONATION      = 0x0200
81THREAD_SET_LIMITED_INFORMATION   = 0x0400
82THREAD_QUERY_LIMITED_INFORMATION = 0x0800
83
84# typedef struct DECLSPEC_ALIGN(16) _MEMORY_BASIC_INFORMATION64 {
85#     ULONGLONG BaseAddress;
86#     ULONGLONG AllocationBase;
87#     DWORD     AllocationProtect;
88#     DWORD     __alignment1;
89#     ULONGLONG RegionSize;
90#     DWORD     State;
91#     DWORD     Protect;
92#     DWORD     Type;
93#     DWORD     __alignment2;
94# } MEMORY_BASIC_INFORMATION64, *PMEMORY_BASIC_INFORMATION64;
95class MEMORY_BASIC_INFORMATION64(Structure):
96    _fields_ = [
97        ('BaseAddress',         ULONGLONG),     # remote pointer
98        ('AllocationBase',      ULONGLONG),     # remote pointer
99        ('AllocationProtect',   DWORD),
100        ('__alignment1',        DWORD),
101        ('RegionSize',          ULONGLONG),
102        ('State',               DWORD),
103        ('Protect',             DWORD),
104        ('Type',                DWORD),
105        ('__alignment2',        DWORD),
106    ]
107
108# typedef struct _MEMORY_BASIC_INFORMATION {
109#     PVOID BaseAddress;
110#     PVOID AllocationBase;
111#     DWORD AllocationProtect;
112#     SIZE_T RegionSize;
113#     DWORD State;
114#     DWORD Protect;
115#     DWORD Type;
116# } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
117class MEMORY_BASIC_INFORMATION(Structure):
118    _fields_ = [
119        ('BaseAddress',         SIZE_T),    # remote pointer
120        ('AllocationBase',      SIZE_T),    # remote pointer
121        ('AllocationProtect',   DWORD),
122        ('RegionSize',          SIZE_T),
123        ('State',               DWORD),
124        ('Protect',             DWORD),
125        ('Type',                DWORD),
126    ]
127PMEMORY_BASIC_INFORMATION = POINTER(MEMORY_BASIC_INFORMATION)
128
129
130# HANDLE WINAPI OpenProcess(
131#   __in  DWORD dwDesiredAccess,
132#   __in  BOOL bInheritHandle,
133#   __in  DWORD dwProcessId
134# );
135def OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId):
136    _OpenProcess = windll.kernel32.OpenProcess
137    _OpenProcess.argtypes = [DWORD, BOOL, DWORD]
138    _OpenProcess.restype  = HANDLE
139
140    hProcess = _OpenProcess(dwDesiredAccess, bool(bInheritHandle), dwProcessId)
141    if hProcess == NULL:
142        raise ctypes.WinError()
143    return hProcess
144
145# SIZE_T WINAPI VirtualQueryEx(
146#   __in      HANDLE hProcess,
147#   __in_opt  LPCVOID lpAddress,
148#   __out     PMEMORY_BASIC_INFORMATION lpBuffer,
149#   __in      SIZE_T dwLength
150# );
151def VirtualQueryEx(hProcess, lpAddress):
152    _VirtualQueryEx = windll.kernel32.VirtualQueryEx
153    _VirtualQueryEx.argtypes = [HANDLE, LPVOID, PMEMORY_BASIC_INFORMATION, SIZE_T]
154    _VirtualQueryEx.restype  = SIZE_T
155
156    lpBuffer  = MEMORY_BASIC_INFORMATION()
157    dwLength  = sizeof(MEMORY_BASIC_INFORMATION)
158    success   = _VirtualQueryEx(hProcess, lpAddress, byref(lpBuffer), dwLength)
159    if success == 0:
160        raise ctypes.WinError()
161    return lpBuffer
162
163
164# BOOL WINAPI ReadProcessMemory(
165#   __in   HANDLE hProcess,
166#   __in   LPCVOID lpBaseAddress,
167#   __out  LPVOID lpBuffer,
168#   __in   SIZE_T nSize,
169#   __out  SIZE_T* lpNumberOfBytesRead
170# );
171def ReadProcessMemory(hProcess, lpBaseAddress, nSize):
172    _ReadProcessMemory = windll.kernel32.ReadProcessMemory
173    _ReadProcessMemory.argtypes = [HANDLE, LPVOID, LPVOID, SIZE_T, POINTER(SIZE_T)]
174    _ReadProcessMemory.restype  = bool
175
176    lpBuffer            = ctypes.create_string_buffer(b'', nSize)
177    lpNumberOfBytesRead = SIZE_T(0)
178    success = _ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, byref(lpNumberOfBytesRead))
179    if not success and GetLastError() != ERROR_PARTIAL_COPY:
180        raise ctypes.WinError()
181    return str(lpBuffer.raw)[:lpNumberOfBytesRead.value]