SetThreadContext 32<->64 + test

This commit is contained in:
Clement Rouault
2016-02-01 17:31:56 +01:00
parent d720170781
commit 0da86e20aa
7 changed files with 80 additions and 12 deletions
+10
View File
@@ -222,6 +222,12 @@ BOOL WINAPI SetThreadContext(
__in CONST LPCONTEXT lpContext
);
BOOL WINAPI NtSetContextThread(
__in HANDLE hThread,
__in CONST LPCONTEXT lpContext
);
HANDLE WINAPI OpenThread(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
@@ -737,4 +743,8 @@ DWORD WINAPI GetProcessId(
_In_ HANDLE Process
);
BOOL WINAPI Wow64SetThreadContext(
__in HANDLE hThread,
__in CONST WOW64_CONTEXT *lpContext
);
+9 -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', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'NtGetContextThread', 'SetThreadContext', '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']
functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'LdrLoadDll', 'NtQuerySystemInformation', 'NtQueryInformationProcess', 'NtQueryVirtualMemory', 'NtCreateThreadEx', 'NtQueryInformationThread', 'GetExitCodeThread', 'GetExitCodeProcess', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualQuery', 'VirtualQueryEx', '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']
# ExitProcess(uExitCode):
ExitProcessPrototype = WINFUNCTYPE(VOID, UINT)
@@ -129,6 +129,10 @@ NtGetContextThreadParams = ((1, 'hThread'), (1, 'lpContext'))
SetThreadContextPrototype = WINFUNCTYPE(BOOL, HANDLE, LPCONTEXT)
SetThreadContextParams = ((1, 'hThread'), (1, 'lpContext'))
# NtSetContextThread(hThread, lpContext):
NtSetContextThreadPrototype = WINFUNCTYPE(BOOL, HANDLE, LPCONTEXT)
NtSetContextThreadParams = ((1, 'hThread'), (1, 'lpContext'))
# OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId):
OpenThreadPrototype = WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)
OpenThreadParams = ((1, 'dwDesiredAccess'), (1, 'bInheritHandle'), (1, 'dwThreadId'))
@@ -517,3 +521,7 @@ DebugBreakProcessParams = ((1, 'Process'),)
GetProcessIdPrototype = WINFUNCTYPE(DWORD, HANDLE)
GetProcessIdParams = ((1, 'Process'),)
# Wow64SetThreadContext(hThread, lpContext):
Wow64SetThreadContextPrototype = WINFUNCTYPE(BOOL, HANDLE, POINTER(WOW64_CONTEXT))
Wow64SetThreadContextParams = ((1, 'hThread'), (1, 'lpContext'))
+3 -1
View File
@@ -290,4 +290,6 @@ def NtGetContextThread_32_to_64(hThread, lpContext):
def LdrLoadDll_32_to_64(PathToFile, Flags, ModuleFileName, ModuleHandle):
return LdrLoadDll_32_to_64.ctypes_function(PathToFile, Flags, ModuleFileName, ModuleHandle)
@Syswow64ApiProxy(windows.winproxy.NtSetContextThread)
def NtSetContextThread_32_to_64(hThread, lpContext):
return NtSetContextThread_32_to_64.ctypes_function(hThread, lpContext)
+44 -5
View File
@@ -298,6 +298,48 @@ class WindowsTestCase(unittest.TestCase):
self.assertEqual(calc.exit_code, 42)
self.assertEqual(calc.is_exit, True)
def test_set_thread_context_32(self):
code = x86.MultipleInstr()
code += x86.Label(":LOOP")
code += x86.Jmp(":LOOP")
data_len = len(code.get_code())
code += x86.Ret()
with Calc32() as calc:
t = calc.execute(code.get_code())
time.sleep(0.1)
self.assertEqual(calc.is_exit, False)
t.suspend()
ctx = t.context
ctx.Eip += data_len
ctx.Eax = 0x11223344
t.set_context(ctx)
t.resume()
time.sleep(0.1)
self.assertEqual(t.exit_code, 0x11223344)
@windows_64bit_only
def test_set_thread_context_64(self):
code = x64.MultipleInstr()
code += x64.Label(":LOOP")
code += x64.Jmp(":LOOP")
data_len = len(code.get_code())
code += x64.Ret()
with Calc64() as calc:
t = calc.execute(code.get_code())
time.sleep(0.1)
self.assertEqual(calc.is_exit, False)
t.suspend()
ctx = t.context
ctx.Rip += data_len
ctx.Rax = 0x11223344
t.set_context(ctx)
t.resume()
time.sleep(0.1)
self.assertEqual(t.exit_code, 0x11223344)
class WindowsAPITestCase(unittest.TestCase):
def test_createfileA_fail(self):
with self.assertRaises(WindowsError) as ar:
@@ -323,8 +365,7 @@ class NativeUtilsTestCase(unittest.TestCase):
k32 = [mod for mod in windows.current_process.peb.modules if mod.name == "kernel32.dll"][0]
exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring)]
for i in range(15):
name, addr = random.choice(exports)
for name, addr in exports:
name = name.encode()
compute_addr = getprocaddr64("KERNEL32.DLL", name)
# Put name in test to know which function caused the assert fails
@@ -348,9 +389,7 @@ class NativeUtilsTestCase(unittest.TestCase):
k32 = [mod for mod in windows.current_process.peb.modules if mod.name == "kernel32.dll"][0]
exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring)]
for i in range(1500):
name, addr = random.choice(exports)
for name, addr in exports:
name = name.encode()
compute_addr = getprocaddr32("KERNEL32.DLL", name)
# Put name in test to know which function caused the assert fails
+1 -1
View File
@@ -189,7 +189,7 @@ class EDr7(ctypes.Structure):
("LEN3", DWORD, 2),
]
class EnhancedCONTEXTBase():
class EnhancedCONTEXTBase(object):
default_dump = ()
pc_reg = ''
special_reg_type = {}
+5 -1
View File
@@ -171,7 +171,11 @@ class WinThread(THREADENTRY32, AutoHandle):
return x
def set_context(self, context):
return winproxy.SetThreadContext(self.handle, context)
if self.owner.bitness == windows.current_process.bitness:
return winproxy.SetThreadContext(self.handle, context)
if windows.current_process.bitness == 64 and self.owner.bitness == 32:
return winproxy.Wow64SetThreadContext(self.handle, context)
return windows.syswow64.NtSetContextThread_32_to_64(self.handle, ctypes.byref(context))
@property
def start_address(self):
+8 -3
View File
@@ -352,11 +352,12 @@ def GetThreadContext(hThread, lpContext=None):
@Kernel32Proxy("SetThreadContext")
def SetThreadContext(hThread, lpContext):
""" Allows to directly pass a CONTEXT and will call with byref(CONTEXT) by itself"""
if type(lpContext) == CONTEXT:
lpContext = ctypes.byref(lpContext)
return SetThreadContext.ctypes_function(hThread, lpContext)
@Kernel32Proxy("Wow64SetThreadContext")
def Wow64SetThreadContext(hThread, lpContext):
return Wow64SetThreadContext.ctypes_function(hThread, lpContext)
@Kernel32Proxy("OpenThread")
def OpenThread(dwDesiredAccess=THREAD_ALL_ACCESS, bInheritHandle=0, dwThreadId=NeededParameter):
@@ -554,6 +555,10 @@ def NtCreateThreadEx(ThreadHandle=None, DesiredAccess=0x1fffff, ObjectAttributes
return NtCreateThreadEx.ctypes_function(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, lpStartAddress, lpParameter, CreateSuspended, dwStackSize, Unknown1, Unknown2, Unknown3)
@NtdllProxy("NtSetContextThread", error_ntstatus)
def NtSetContextThread(hThread, lpContext):
return NtSetContextThread.ctypes_function(hThread, lpContext)
# ##### ADVAPI32 ####### #
@Advapi32Proxy('OpenProcessToken')