mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
fix queryworkingset / add test / add virtual protect context manager
This commit is contained in:
@@ -110,6 +110,15 @@ LPVOID WINAPI VirtualAllocEx(
|
||||
_In_ DWORD flProtect
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtProtectVirtualMemory(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_Inout_ PVOID *BaseAddress,
|
||||
_Inout_ PULONG NumberOfBytesToProtect,
|
||||
_In_ ULONG NewAccessProtection,
|
||||
_Out_ PULONG OldAccessProtection
|
||||
);
|
||||
|
||||
|
||||
BOOL WINAPI VirtualFree(
|
||||
_In_ LPVOID lpAddress,
|
||||
_In_ SIZE_T dwSize,
|
||||
@@ -130,6 +139,15 @@ BOOL WINAPI VirtualProtect(
|
||||
_Out_ PDWORD lpflOldProtect
|
||||
);
|
||||
|
||||
BOOL WINAPI VirtualProtectEx(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ LPVOID lpAddress,
|
||||
_In_ SIZE_T dwSize,
|
||||
_In_ DWORD flNewProtect,
|
||||
_Out_ PDWORD lpflOldProtect
|
||||
);
|
||||
|
||||
|
||||
DWORD VirtualQuery(
|
||||
LPCVOID lpAddress,
|
||||
PMEMORY_BASIC_INFORMATION lpBuffer,
|
||||
@@ -281,6 +299,14 @@ BOOL WINAPI WriteProcessMemory(
|
||||
_Out_ SIZE_T *lpNumberOfBytesWritten
|
||||
);
|
||||
|
||||
BOOL WINAPI NtWow64WriteVirtualMemory64(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ ULONG64 lpBaseAddress,
|
||||
_Out_ LPVOID lpBuffer,
|
||||
_In_ ULONG64 nSize,
|
||||
_Out_ PULONG64 *lpNumberOfBytesWritten
|
||||
);
|
||||
|
||||
HANDLE WINAPI CreateToolhelp32Snapshot(
|
||||
_In_ DWORD dwFlags,
|
||||
_In_ DWORD th32ProcessID
|
||||
|
||||
@@ -3,7 +3,7 @@ from ctypes import *
|
||||
from ctypes.wintypes import *
|
||||
from .winstructs import *
|
||||
|
||||
functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'LdrLoadDll', 'NtQuerySystemInformation', 'NtQueryInformationProcess', 'NtQueryVirtualMemory', 'NtCreateThreadEx', 'NtQueryInformationThread', 'GetExitCodeThread', 'GetExitCodeProcess', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualQuery', 'VirtualQueryEx', 'QueryWorkingSet', 'QueryWorkingSetEx', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'NtGetContextThread', 'SetThreadContext', 'NtSetContextThread', 'OpenThread', 'OpenProcess', 'CloseHandle', 'ReadProcessMemory', 'NtWow64ReadVirtualMemory64', 'WriteProcessMemory', 'CreateToolhelp32Snapshot', 'Thread32First', 'Thread32Next', 'Process32First', 'Process32Next', 'Process32FirstW', 'Process32NextW', 'GetProcAddress', 'LoadLibraryA', 'LoadLibraryW', 'OpenProcessToken', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW', 'AdjustTokenPrivileges', 'FindResourceA', 'FindResourceW', 'SizeofResource', 'LoadResource', 'LockResource', 'GetVersionExA', 'GetVersionExW', 'GetVersion', 'GetCurrentThread', 'GetCurrentThreadId', 'GetCurrentProcessorNumber', 'AllocConsole', 'FreeConsole', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject', 'GetThreadId', 'LoadLibraryExA', 'LoadLibraryExW', 'SymInitialize', 'SymFromName', 'SymLoadModuleEx', 'SymSetOptions', 'SymGetTypeInfo', 'DeviceIoControl', 'GetTokenInformation', 'RegOpenKeyExA', 'RegOpenKeyExW', 'RegGetValueA', 'RegGetValueW', 'RegCloseKey', 'Wow64DisableWow64FsRedirection', 'Wow64RevertWow64FsRedirection', 'Wow64EnableWow64FsRedirection', 'Wow64GetThreadContext', 'SetConsoleCtrlHandler', 'WinVerifyTrust', 'GlobalAlloc', 'GlobalFree', 'GlobalUnlock', 'GlobalLock', 'OpenClipboard', 'EmptyClipboard', 'CloseClipboard', 'SetClipboardData', 'GetClipboardData', 'EnumClipboardFormats', 'GetClipboardFormatNameA', 'GetClipboardFormatNameW', 'WinVerifyTrust', 'OpenProcessToken', 'OpenThreadToken', 'GetTokenInformation', 'SetTokenInformation', 'GetSidIdentifierAuthority', 'GetSidSubAuthority', 'GetSidSubAuthorityCount', 'DebugBreak', 'WaitForDebugEvent', 'ContinueDebugEvent', 'DebugActiveProcess', 'DebugActiveProcessStop', 'DebugSetProcessKillOnExit', 'DebugBreakProcess', 'GetProcessId', 'Wow64SetThreadContext', 'GetMappedFileNameW', 'GetMappedFileNameA', 'RtlInitString', 'RtlInitUnicodeString', 'RtlAnsiStringToUnicodeString', 'OpenEventA', 'OpenEventW', 'NtOpenEvent', 'NtAlpcCreatePort', 'NtAlpcConnectPort', 'NtAlpcAcceptConnectPort', 'AlpcInitializeMessageAttribute', 'AlpcGetMessageAttribute', 'NtAlpcSendWaitReceivePort', 'lstrcmpA', 'lstrcmpW', 'CreateFileMappingA', 'CreateFileMappingW', 'MapViewOfFile', 'OpenSCManagerA', 'OpenSCManagerW', 'EnumServicesStatusExA', 'EnumServicesStatusExW', 'EnumWindows', 'GetWindowTextA', 'GetWindowTextW', 'GetWindowModuleFileNameA', 'GetWindowModuleFileNameW', 'CryptCATAdminCalcHashFromFileHandle', 'CryptCATAdminEnumCatalogFromHash', 'CryptCATAdminAcquireContext', 'CryptCATCatalogInfoFromContext', 'CryptCATAdminReleaseCatalogContext', 'CryptCATAdminReleaseContext', 'GetLogicalDriveStringsA', 'GetLogicalDriveStringsW', 'GetVolumeInformationA', 'GetVolumeInformationW', 'GetVolumeNameForVolumeMountPointA', 'GetVolumeNameForVolumeMountPointW', 'GetDriveTypeA', 'GetDriveTypeW', 'QueryDosDeviceA', 'QueryDosDeviceW', 'NtQueryObject', 'DuplicateHandle', 'GetModuleBaseNameA', 'GetModuleBaseNameW', 'GetProcessImageFileNameA', 'GetProcessImageFileNameW', 'GetFileVersionInfoA', 'GetFileVersionInfoW', 'GetFileVersionInfoSizeA', 'GetFileVersionInfoSizeW', 'VerQueryValueA', 'VerQueryValueW', 'GetSystemMetrics', 'GetComputerNameA', 'GetComputerNameW', 'LookupAccountSidA', 'LookupAccountSidW', 'CoInitializeEx', 'CoInitializeSecurity', 'CoCreateInstance', 'GetInterfaceInfo', 'GetIfTable', 'GetIpAddrTable', 'NtOpenDirectoryObject', 'NtQueryDirectoryObject', 'NtQuerySymbolicLinkObject', 'NtOpenSymbolicLinkObject']
|
||||
functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'LdrLoadDll', 'NtQuerySystemInformation', 'NtQueryInformationProcess', 'NtQueryVirtualMemory', 'NtCreateThreadEx', 'NtQueryInformationThread', 'GetExitCodeThread', 'GetExitCodeProcess', 'VirtualAlloc', 'VirtualAllocEx', 'NtProtectVirtualMemory', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualProtectEx', 'VirtualQuery', 'VirtualQueryEx', 'QueryWorkingSet', 'QueryWorkingSetEx', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'NtGetContextThread', 'SetThreadContext', 'NtSetContextThread', 'OpenThread', 'OpenProcess', 'CloseHandle', 'ReadProcessMemory', 'NtWow64ReadVirtualMemory64', 'WriteProcessMemory', 'NtWow64WriteVirtualMemory64', 'CreateToolhelp32Snapshot', 'Thread32First', 'Thread32Next', 'Process32First', 'Process32Next', 'Process32FirstW', 'Process32NextW', 'GetProcAddress', 'LoadLibraryA', 'LoadLibraryW', 'OpenProcessToken', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW', 'AdjustTokenPrivileges', 'FindResourceA', 'FindResourceW', 'SizeofResource', 'LoadResource', 'LockResource', 'GetVersionExA', 'GetVersionExW', 'GetVersion', 'GetCurrentThread', 'GetCurrentThreadId', 'GetCurrentProcessorNumber', 'AllocConsole', 'FreeConsole', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject', 'GetThreadId', 'LoadLibraryExA', 'LoadLibraryExW', 'SymInitialize', 'SymFromName', 'SymLoadModuleEx', 'SymSetOptions', 'SymGetTypeInfo', 'DeviceIoControl', 'GetTokenInformation', 'RegOpenKeyExA', 'RegOpenKeyExW', 'RegGetValueA', 'RegGetValueW', 'RegCloseKey', 'Wow64DisableWow64FsRedirection', 'Wow64RevertWow64FsRedirection', 'Wow64EnableWow64FsRedirection', 'Wow64GetThreadContext', 'SetConsoleCtrlHandler', 'WinVerifyTrust', 'GlobalAlloc', 'GlobalFree', 'GlobalUnlock', 'GlobalLock', 'OpenClipboard', 'EmptyClipboard', 'CloseClipboard', 'SetClipboardData', 'GetClipboardData', 'EnumClipboardFormats', 'GetClipboardFormatNameA', 'GetClipboardFormatNameW', 'WinVerifyTrust', 'OpenProcessToken', 'OpenThreadToken', 'GetTokenInformation', 'SetTokenInformation', 'GetSidIdentifierAuthority', 'GetSidSubAuthority', 'GetSidSubAuthorityCount', 'DebugBreak', 'WaitForDebugEvent', 'ContinueDebugEvent', 'DebugActiveProcess', 'DebugActiveProcessStop', 'DebugSetProcessKillOnExit', 'DebugBreakProcess', 'GetProcessId', 'Wow64SetThreadContext', 'GetMappedFileNameW', 'GetMappedFileNameA', 'RtlInitString', 'RtlInitUnicodeString', 'RtlAnsiStringToUnicodeString', 'OpenEventA', 'OpenEventW', 'NtOpenEvent', 'NtAlpcCreatePort', 'NtAlpcConnectPort', 'NtAlpcAcceptConnectPort', 'AlpcInitializeMessageAttribute', 'AlpcGetMessageAttribute', 'NtAlpcSendWaitReceivePort', 'lstrcmpA', 'lstrcmpW', 'CreateFileMappingA', 'CreateFileMappingW', 'MapViewOfFile', 'OpenSCManagerA', 'OpenSCManagerW', 'EnumServicesStatusExA', 'EnumServicesStatusExW', 'EnumWindows', 'GetWindowTextA', 'GetWindowTextW', 'GetWindowModuleFileNameA', 'GetWindowModuleFileNameW', 'CryptCATAdminCalcHashFromFileHandle', 'CryptCATAdminEnumCatalogFromHash', 'CryptCATAdminAcquireContext', 'CryptCATCatalogInfoFromContext', 'CryptCATAdminReleaseCatalogContext', 'CryptCATAdminReleaseContext', 'GetLogicalDriveStringsA', 'GetLogicalDriveStringsW', 'GetVolumeInformationA', 'GetVolumeInformationW', 'GetVolumeNameForVolumeMountPointA', 'GetVolumeNameForVolumeMountPointW', 'GetDriveTypeA', 'GetDriveTypeW', 'QueryDosDeviceA', 'QueryDosDeviceW', 'NtQueryObject', 'DuplicateHandle', 'GetModuleBaseNameA', 'GetModuleBaseNameW', 'GetProcessImageFileNameA', 'GetProcessImageFileNameW', 'GetFileVersionInfoA', 'GetFileVersionInfoW', 'GetFileVersionInfoSizeA', 'GetFileVersionInfoSizeW', 'VerQueryValueA', 'VerQueryValueW', 'GetSystemMetrics', 'GetComputerNameA', 'GetComputerNameW', 'LookupAccountSidA', 'LookupAccountSidW', 'CoInitializeEx', 'CoInitializeSecurity', 'CoCreateInstance', 'GetInterfaceInfo', 'GetIfTable', 'GetIpAddrTable', 'NtOpenDirectoryObject', 'NtQueryDirectoryObject', 'NtQuerySymbolicLinkObject', 'NtOpenSymbolicLinkObject']
|
||||
|
||||
#def ExitProcess(uExitCode):
|
||||
# return ExitProcess.ctypes_function(uExitCode)
|
||||
@@ -85,6 +85,11 @@ VirtualAllocParams = ((1, 'lpAddress'), (1, 'dwSize'), (1, 'flAllocationType'),
|
||||
VirtualAllocExPrototype = WINFUNCTYPE(LPVOID, HANDLE, LPVOID, SIZE_T, DWORD, DWORD)
|
||||
VirtualAllocExParams = ((1, 'hProcess'), (1, 'lpAddress'), (1, 'dwSize'), (1, 'flAllocationType'), (1, 'flProtect'))
|
||||
|
||||
#def NtProtectVirtualMemory(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection):
|
||||
# return NtProtectVirtualMemory.ctypes_function(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection)
|
||||
NtProtectVirtualMemoryPrototype = WINFUNCTYPE(NTSTATUS, HANDLE, POINTER(PVOID), PULONG, ULONG, PULONG)
|
||||
NtProtectVirtualMemoryParams = ((1, 'ProcessHandle'), (1, 'BaseAddress'), (1, 'NumberOfBytesToProtect'), (1, 'NewAccessProtection'), (1, 'OldAccessProtection'))
|
||||
|
||||
#def VirtualFree(lpAddress, dwSize, dwFreeType):
|
||||
# return VirtualFree.ctypes_function(lpAddress, dwSize, dwFreeType)
|
||||
VirtualFreePrototype = WINFUNCTYPE(BOOL, LPVOID, SIZE_T, DWORD)
|
||||
@@ -100,6 +105,11 @@ VirtualFreeExParams = ((1, 'hProcess'), (1, 'lpAddress'), (1, 'dwSize'), (1, 'dw
|
||||
VirtualProtectPrototype = WINFUNCTYPE(BOOL, LPVOID, SIZE_T, DWORD, PDWORD)
|
||||
VirtualProtectParams = ((1, 'lpAddress'), (1, 'dwSize'), (1, 'flNewProtect'), (1, 'lpflOldProtect'))
|
||||
|
||||
#def VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect):
|
||||
# return VirtualProtectEx.ctypes_function(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect)
|
||||
VirtualProtectExPrototype = WINFUNCTYPE(BOOL, HANDLE, LPVOID, SIZE_T, DWORD, PDWORD)
|
||||
VirtualProtectExParams = ((1, 'hProcess'), (1, 'lpAddress'), (1, 'dwSize'), (1, 'flNewProtect'), (1, 'lpflOldProtect'))
|
||||
|
||||
#def VirtualQuery(lpAddress, lpBuffer, dwLength):
|
||||
# return VirtualQuery.ctypes_function(lpAddress, lpBuffer, dwLength)
|
||||
VirtualQueryPrototype = WINFUNCTYPE(DWORD, LPCVOID, PMEMORY_BASIC_INFORMATION, DWORD)
|
||||
@@ -205,6 +215,11 @@ NtWow64ReadVirtualMemory64Params = ((1, 'hProcess'), (1, 'lpBaseAddress'), (1, '
|
||||
WriteProcessMemoryPrototype = WINFUNCTYPE(BOOL, HANDLE, LPVOID, LPCVOID, SIZE_T, POINTER(SIZE_T))
|
||||
WriteProcessMemoryParams = ((1, 'hProcess'), (1, 'lpBaseAddress'), (1, 'lpBuffer'), (1, 'nSize'), (1, 'lpNumberOfBytesWritten'))
|
||||
|
||||
#def NtWow64WriteVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten):
|
||||
# return NtWow64WriteVirtualMemory64.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten)
|
||||
NtWow64WriteVirtualMemory64Prototype = WINFUNCTYPE(BOOL, HANDLE, ULONG64, LPVOID, ULONG64, POINTER(PULONG64))
|
||||
NtWow64WriteVirtualMemory64Params = ((1, 'hProcess'), (1, 'lpBaseAddress'), (1, 'lpBuffer'), (1, 'nSize'), (1, 'lpNumberOfBytesWritten'))
|
||||
|
||||
#def CreateToolhelp32Snapshot(dwFlags, th32ProcessID):
|
||||
# return CreateToolhelp32Snapshot.ctypes_function(dwFlags, th32ProcessID)
|
||||
CreateToolhelp32SnapshotPrototype = WINFUNCTYPE(HANDLE, DWORD, DWORD)
|
||||
|
||||
@@ -286,6 +286,15 @@ def NtQueryVirtualMemory_32_to_64(ProcessHandle, BaseAddress, MemoryInformationC
|
||||
return NtQueryVirtualMemory_32_to_64.ctypes_function(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation, MemoryInformationLength, ReturnLength)
|
||||
|
||||
|
||||
@Syswow64ApiProxy(winproxy.NtProtectVirtualMemory)
|
||||
def NtProtectVirtualMemory_32_to_64(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection=None):
|
||||
if OldAccessProtection is None:
|
||||
XOldAccessProtection = DWORD()
|
||||
OldAccessProtection = ctypes.addressof(XOldAccessProtection)
|
||||
return NtProtectVirtualMemory_32_to_64.ctypes_function(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection)
|
||||
|
||||
|
||||
|
||||
@Syswow64ApiProxy(winproxy.NtGetContextThread)
|
||||
def NtGetContextThread_32_to_64(hThread, lpContext):
|
||||
if type(lpContext) == windows.winobject.exception.ECONTEXT64:
|
||||
|
||||
+96
-2
@@ -144,6 +144,34 @@ class WindowsTestCase(unittest.TestCase):
|
||||
sections[0].start
|
||||
sections[0].size
|
||||
|
||||
# Read / write
|
||||
|
||||
def test_read_memory_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "MZ")
|
||||
|
||||
@windows_64bit_only
|
||||
def test_read_memory_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "MZ")
|
||||
|
||||
def test_write_memory_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
with calc.virtual_protected(k32.baseaddr, 2, PAGE_EXECUTE_READWRITE):
|
||||
calc.write_memory(k32.baseaddr, "XD")
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "XD")
|
||||
|
||||
@windows_64bit_only
|
||||
def test_write_memory_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
with calc.virtual_protected(k32.baseaddr, 2, PAGE_EXECUTE_READWRITE):
|
||||
calc.write_memory(k32.baseaddr, "XD")
|
||||
self.assertEqual(calc.read_memory(k32.baseaddr, 2), "XD")
|
||||
|
||||
# Native execution
|
||||
def test_execute_to_32(self):
|
||||
with Calc32() as calc:
|
||||
@@ -451,7 +479,7 @@ class WindowsTestCase(unittest.TestCase):
|
||||
|
||||
@windows_64bit_only
|
||||
def test_get_working_set_64(self):
|
||||
with Calc32() as calc:
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
api_addr = k32.pe.exports["CreateFileA"]
|
||||
data = calc.read_memory(api_addr, 5)
|
||||
@@ -462,7 +490,8 @@ class WindowsTestCase(unittest.TestCase):
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
data = calc.write_memory(api_addr, data)
|
||||
with calc.virtual_protected(api_addr, 5, PAGE_EXECUTE_READWRITE):
|
||||
data = calc.write_memory(api_addr, data)
|
||||
for page_info in calc.query_working_set():
|
||||
if page_info.virtualpage == page_target:
|
||||
self.assertEqual(page_info.shared, False)
|
||||
@@ -470,6 +499,71 @@ class WindowsTestCase(unittest.TestCase):
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
def test_get_working_setex_32(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
|
||||
text = [s for s in k32.pe.sections if s.name == ".text"][0]
|
||||
pages = [text.start + off for off in range(0, text.size, 0x1000)]
|
||||
|
||||
api_addr = k32.pe.exports["CreateFileA"]
|
||||
data = calc.read_memory(api_addr, 5)
|
||||
page_target = (api_addr >> 12) << 12
|
||||
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, True)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
with calc.virtual_protected(api_addr, 5, PAGE_EXECUTE_READWRITE):
|
||||
data = calc.write_memory(api_addr, data)
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, False)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
@windows_64bit_only
|
||||
def test_get_working_setex_64(self):
|
||||
with Calc64() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
|
||||
text = [s for s in k32.pe.sections if s.name == ".text"][0]
|
||||
pages = [text.start + off for off in range(0, text.size, 0x1000)]
|
||||
|
||||
api_addr = k32.pe.exports["CreateFileA"]
|
||||
|
||||
data = calc.read_memory(api_addr, 5)
|
||||
page_target = (api_addr >> 12) << 12
|
||||
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, True)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
with calc.virtual_protected(api_addr, 5, PAGE_EXECUTE_READWRITE):
|
||||
data = calc.write_memory(api_addr, data)
|
||||
for page_info in calc.query_working_setex(pages):
|
||||
self.assertIn(page_info.VirtualAddress, pages)
|
||||
if page_info.VirtualAddress == page_target:
|
||||
self.assertEqual(page_info.VirtualAttributes.shared, False)
|
||||
break
|
||||
else:
|
||||
raise ValueError("query_working_set page info for <0x{0:x}> not found".format(page_target))
|
||||
|
||||
def test_mapped_filename(self):
|
||||
with Calc32() as calc:
|
||||
k32 = [m for m in calc.peb.modules if m.name == "kernel32.dll"][0]
|
||||
mapped_filname = calc.get_mapped_filename(k32.baseaddr)
|
||||
self.assertTrue(mapped_filname.endswith("kernel32.dll"))
|
||||
|
||||
class WindowsAPITestCase(unittest.TestCase):
|
||||
def test_createfileA_fail(self):
|
||||
with self.assertRaises(WindowsError) as ar:
|
||||
|
||||
@@ -279,6 +279,32 @@ class Process(AutoHandle):
|
||||
finally:
|
||||
winproxy.VirtualFreeEx(self.handle, addr)
|
||||
|
||||
@contextmanager
|
||||
def virtual_protected(self, addr, size, protect):
|
||||
old_protect = DWORD()
|
||||
self.low_virtual_protect(addr, size, protect, old_protect)
|
||||
try:
|
||||
yield addr
|
||||
finally:
|
||||
self.low_virtual_protect(addr, size, old_protect.value, old_protect)
|
||||
|
||||
def low_virtual_protect(self, addr, size, protect, old_protect):
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
#addr = (addr >> 12) << 12
|
||||
#addr = ULONG64(addr)
|
||||
size = ((size >> 12) + 1) << 12
|
||||
#ssize = ULONG(size)
|
||||
#import pdb;pdb.set_trace()
|
||||
old_protect = ctypes.addressof(old_protect)
|
||||
xaddr = ULONG64(addr)
|
||||
addr = ctypes.addressof(xaddr)
|
||||
xsize = ULONG(size)
|
||||
size = ctypes.addressof(xsize)
|
||||
return windows.syswow64.NtProtectVirtualMemory_32_to_64(self.handle, addr, size, protect, old_protect)
|
||||
else:
|
||||
winproxy.VirtualProtectEx(self.handle, addr, size, protect, old_protect)
|
||||
|
||||
|
||||
def execute(self, code, parameter=0):
|
||||
"""Execute some native code in the context of the process
|
||||
|
||||
@@ -338,9 +364,9 @@ class Process(AutoHandle):
|
||||
if e.winerror != 24:
|
||||
raise
|
||||
|
||||
NumberOfEntriesType = [f for f in WSET_BLOCK._fields_ if f[0] == "Flags"][0][1]
|
||||
for i in range(10):
|
||||
# use the same type as WSET_BLOCK.Flags
|
||||
NumberOfEntriesType = [f for f in WSET_BLOCK._fields_ if f[0] == "Flags"][0][1]
|
||||
class GENERATED_PSAPI_WORKING_SET_INFORMATION(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("NumberOfEntries", NumberOfEntriesType),
|
||||
@@ -363,9 +389,10 @@ class Process(AutoHandle):
|
||||
dummy.NumberOfEntries = res.NumberOfEntries
|
||||
continue
|
||||
return res.WorkingSetInfo
|
||||
# Raise ?
|
||||
return None
|
||||
|
||||
def query_working_set_ex(self, addresses):
|
||||
def query_working_setex(self, addresses):
|
||||
if self.bitness == 64 or windows.current_process.bitness == 64:
|
||||
info_type = EPSAPI_WORKING_SET_EX_INFORMATION64
|
||||
else:
|
||||
@@ -373,7 +400,10 @@ class Process(AutoHandle):
|
||||
info_array = (info_type * len(addresses))()
|
||||
for i, data in enumerate(info_array):
|
||||
info_array[i].VirtualAddress = addresses[i]
|
||||
winproxy.QueryWorkingSetEx(self.handle, ctypes.byref(info_array), ctypes.sizeof(info_array))
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
windows.syswow64.NtQueryVirtualMemory_32_to_64(self.handle, 0, 4, info_array)
|
||||
else:
|
||||
winproxy.QueryWorkingSetEx(self.handle, ctypes.byref(info_array), ctypes.sizeof(info_array))
|
||||
return info_array
|
||||
|
||||
|
||||
@@ -703,6 +733,10 @@ class WinProcess(Process):
|
||||
|
||||
def write_memory(self, addr, data):
|
||||
"""Write `data` at `addr`"""
|
||||
if windows.current_process.bitness == 32 and self.bitness == 64:
|
||||
if winproxy.NtWow64WriteVirtualMemory64 is None:
|
||||
raise ValueError("NtWow64WriteVirtualMemory64 non available in ntdll: cannot write into 64bits processus")
|
||||
return winproxy.NtWow64WriteVirtualMemory64(self.handle, addr, data, len(data))
|
||||
return winproxy.WriteProcessMemory(self.handle, addr, lpBuffer=data)
|
||||
|
||||
def low_read_memory(self, addr, buffer_addr, size):
|
||||
@@ -711,7 +745,6 @@ class WinProcess(Process):
|
||||
if winproxy.NtWow64ReadVirtualMemory64 is None:
|
||||
raise ValueError("NtWow64ReadVirtualMemory64 non available in ntdll: cannot read into 64bits processus")
|
||||
return winproxy.NtWow64ReadVirtualMemory64(self.handle, addr, buffer_addr, size)
|
||||
NtWow64ReadVirtualMemory64
|
||||
#if self.is_wow_64 and addr > 0xffffffff:
|
||||
# return winproxy.NtWow64ReadVirtualMemory64(self.handle, addr, buffer_addr, size)
|
||||
return winproxy.ReadProcessMemory(self.handle, addr, lpBuffer=buffer_addr, nSize=size)
|
||||
|
||||
+18
-3
@@ -338,6 +338,12 @@ def VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect=None):
|
||||
return VirtualProtect.ctypes_function(lpAddress, dwSize, flNewProtect, lpflOldProtect)
|
||||
|
||||
|
||||
@Kernel32Proxy("VirtualProtectEx")
|
||||
def VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect=None):
|
||||
if lpflOldProtect is None:
|
||||
lpflOldProtect = ctypes.byref(DWORD())
|
||||
return VirtualProtectEx.ctypes_function(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect)
|
||||
|
||||
@Kernel32Proxy("CreateProcessA")
|
||||
def CreateProcessA(lpApplicationName, lpCommandLine=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=False,
|
||||
dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None, lpProcessInformation=None):
|
||||
@@ -538,14 +544,14 @@ def QueryWorkingSetWrapper(hProcess, pv, cb):
|
||||
QueryWorkingSet = OptionalExport(Kernel32Proxy("QueryWorkingSet"))(QueryWorkingSetWrapper)
|
||||
|
||||
def QueryWorkingSetExWrapper(hProcess, pv, cb):
|
||||
return QueryWorkingSet.ctypes_function(hProcess, pv, cb)
|
||||
QueryWorkingSetEx = OptionalExport(Kernel32Proxy("QueryWorkingSetEx"))(QueryWorkingSetWrapper)
|
||||
return QueryWorkingSetEx.ctypes_function(hProcess, pv, cb)
|
||||
QueryWorkingSetEx = OptionalExport(Kernel32Proxy("QueryWorkingSetEx"))(QueryWorkingSetExWrapper)
|
||||
|
||||
if GetMappedFileNameA is None:
|
||||
GetMappedFileNameW = PsapiProxy("GetMappedFileNameW")(GetMappedFileNameWWrapper)
|
||||
GetMappedFileNameA = PsapiProxy("GetMappedFileNameA")(GetMappedFileNameAWrapper)
|
||||
QueryWorkingSet = PsapiProxy("QueryWorkingSet")(QueryWorkingSetWrapper)
|
||||
QueryWorkingSetEx = PsapiProxy("QueryWorkingSetEx")(QueryWorkingSetWrapper)
|
||||
QueryWorkingSetEx = PsapiProxy("QueryWorkingSetEx")(QueryWorkingSetExWrapper)
|
||||
|
||||
def GetModuleBaseNameAWrapper(hProcess, hModule, lpBaseName, nSize=None):
|
||||
if nSize is None:
|
||||
@@ -631,6 +637,9 @@ def GetVolumeInformationW(lpRootPathName, lpVolumeNameBuffer=None, nVolumeNameSi
|
||||
def NtWow64ReadVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead=None):
|
||||
return NtWow64ReadVirtualMemory64.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead)
|
||||
|
||||
@OptionalExport(NtdllProxy('NtWow64WriteVirtualMemory64', error_ntstatus))
|
||||
def NtWow64WriteVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten=None):
|
||||
return NtWow64WriteVirtualMemory64.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten)
|
||||
|
||||
def ntquerysysteminformation_error_check(func_name, result, func, args):
|
||||
if result == 0:
|
||||
@@ -676,6 +685,12 @@ def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInforma
|
||||
return NtQueryInformationThread.ctypes_function(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength)
|
||||
|
||||
|
||||
@NtdllProxy('NtProtectVirtualMemory', error_ntstatus)
|
||||
def NtProtectVirtualMemory(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection=None):
|
||||
if OldAccessProtection is None:
|
||||
OldAccessProtection = DWORD()
|
||||
return NtProtectVirtualMemory.ctypes_function(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection)
|
||||
|
||||
@OptionalExport(NtdllProxy('NtQueryVirtualMemory', error_ntstatus))
|
||||
def NtQueryVirtualMemory(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation=NeededParameter, MemoryInformationLength=0, ReturnLength=None):
|
||||
if ReturnLength is None:
|
||||
|
||||
Reference in New Issue
Block a user