fix queryworkingset / add test / add virtual protect context manager

This commit is contained in:
Clement Rouault
2016-04-18 11:24:41 +02:00
parent 3454801ad0
commit b621e6a09f
6 changed files with 202 additions and 10 deletions
+26
View File
@@ -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
+16 -1
View File
@@ -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)
+9
View File
@@ -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
View File
@@ -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:
+37 -4
View File
@@ -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
View File
@@ -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: