mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Still playing will debug API + add Winprocess.read_[dq]word
This commit is contained in:
@@ -725,4 +725,8 @@ BOOL WINAPI DebugSetProcessKillOnExit(
|
||||
|
||||
BOOL WINAPI DebugBreakProcess (
|
||||
__in HANDLE Process
|
||||
);
|
||||
);
|
||||
|
||||
DWORD WINAPI GetProcessId(
|
||||
_In_ HANDLE Process
|
||||
);
|
||||
|
||||
+92
-20
@@ -1,6 +1,8 @@
|
||||
import windows
|
||||
import windows.winproxy as winproxy
|
||||
|
||||
from windows.winobject import WinProcess, WinThread
|
||||
|
||||
import windows.native_exec.simple_x86 as x86
|
||||
import windows.native_exec.simple_x64 as x64
|
||||
|
||||
@@ -8,8 +10,6 @@ from windows.generated_def.winstructs import *
|
||||
from .generated_def import windef
|
||||
|
||||
|
||||
|
||||
|
||||
class DEBUG_EVENT(DEBUG_EVENT):
|
||||
KNOWN_EVENT_CODE = dict((x,x) for x in [EXCEPTION_DEBUG_EVENT,
|
||||
CREATE_THREAD_DEBUG_EVENT, CREATE_PROCESS_DEBUG_EVENT,
|
||||
@@ -22,26 +22,23 @@ class DEBUG_EVENT(DEBUG_EVENT):
|
||||
|
||||
class Debugger(object):
|
||||
|
||||
#define EXCEPTION_DEBUG_EVENT 1
|
||||
#define CREATE_THREAD_DEBUG_EVENT 2
|
||||
#define CREATE_PROCESS_DEBUG_EVENT 3
|
||||
#define EXIT_THREAD_DEBUG_EVENT 4
|
||||
#define EXIT_PROCESS_DEBUG_EVENT 5
|
||||
#define LOAD_DLL_DEBUG_EVENT 6
|
||||
#define UNLOAD_DLL_DEBUG_EVENT 7
|
||||
#define OUTPUT_DEBUG_STRING_EVENT 8
|
||||
#define RIP_EVENT 9
|
||||
|
||||
dwDebugEventCode_handlers = {}
|
||||
|
||||
def handle_dwDebugEventCode(code_number, d=dwDebugEventCode_handlers):
|
||||
def wrapper(f):
|
||||
d[code_number] = (f)
|
||||
return f
|
||||
return wrapper
|
||||
|
||||
def __init__(self, target):
|
||||
# Todo: accept PID / String / WinProcess
|
||||
self.target = target
|
||||
winproxy.DebugActiveProcess(target.pid)
|
||||
self._handle_initial_debug_event()
|
||||
|
||||
def _handle_initial_debug_event(self):
|
||||
pass
|
||||
self.processes = {}
|
||||
self.threads = {}
|
||||
self.current_process = None
|
||||
self.current_thread = None
|
||||
|
||||
def _debug_event_generator(self):
|
||||
while True:
|
||||
@@ -55,9 +52,84 @@ class Debugger(object):
|
||||
winproxy.ContinueDebugEvent(event.dwProcessId, event.dwThreadId, action)
|
||||
|
||||
def loop(self):
|
||||
for x, i in enumerate(self._debug_event_generator()):
|
||||
print(i, i.code)
|
||||
self._finish_debug_event(i, windef.DBG_CONTINUE)
|
||||
for x, debug_event in enumerate(self._debug_event_generator()):
|
||||
#print(debug_event, debug_event.code)
|
||||
self._dispatch_debug_event(debug_event)
|
||||
self._finish_debug_event(debug_event, windef.DBG_CONTINUE)
|
||||
# TODO: exit on process exit
|
||||
if x == 100:
|
||||
break
|
||||
|
||||
def _update_debugger_state(self, debug_event):
|
||||
self.current_process = self.processes[debug_event.dwProcessId]
|
||||
self.current_thread = self.threads[debug_event.dwThreadId]
|
||||
|
||||
def _dispatch_debug_event(self, debug_event):
|
||||
handler = self.dwDebugEventCode_handlers.get(debug_event.dwDebugEventCode, self._handle_unknown_debug_event)
|
||||
return handler(self, debug_event)
|
||||
|
||||
@staticmethod
|
||||
def _handle_unknown_debug_event(self, debug_event):
|
||||
raise NotImplementedError("dwDebugEventCode = {0}".format(debug_event.dwDebugEventCode))
|
||||
|
||||
@handle_dwDebugEventCode(EXCEPTION_DEBUG_EVENT)
|
||||
def _handle_exception(self, debug_event):
|
||||
print("_handle_exception")
|
||||
self._update_debugger_state(debug_event)
|
||||
|
||||
@handle_dwDebugEventCode(CREATE_THREAD_DEBUG_EVENT)
|
||||
def _handle_create_thread(self, debug_event):
|
||||
print("_handle_create_thread")
|
||||
create_thread = debug_event.u.CreateThread
|
||||
self.current_thread = WinThread._from_handle(create_thread.hThread)
|
||||
self.threads[self.current_thread.tid] = self.current_thread
|
||||
|
||||
@handle_dwDebugEventCode(CREATE_PROCESS_DEBUG_EVENT)
|
||||
def _handle_create_process(self, debug_event):
|
||||
print("_handle_create_process")
|
||||
create_process = debug_event.u.CreateProcessInfo
|
||||
|
||||
self.current_process = WinProcess._from_handle(create_process.hProcess)
|
||||
self.current_thread = WinThread._from_handle(create_process.hThread)
|
||||
# TODO: verif debug_event.dwProcessId for REAL process creation :)
|
||||
# Voir ce qu'on fout en current ? le parent ? (!le fils ?)
|
||||
self.threads[self.current_thread.tid] = self.current_thread
|
||||
self.processes[self.current_process.pid] = self.current_process
|
||||
self._update_debugger_state(debug_event)
|
||||
|
||||
|
||||
@handle_dwDebugEventCode(EXIT_PROCESS_DEBUG_EVENT)
|
||||
def _handle_exit_process(self, debug_event):
|
||||
self._update_debugger_state(debug_event)
|
||||
del self.processes[self.current_process.pid]
|
||||
print("Remove PID {0}".format(self.current_process.pid))
|
||||
print("Bye")
|
||||
exit()
|
||||
|
||||
@handle_dwDebugEventCode(EXIT_THREAD_DEBUG_EVENT)
|
||||
def _handle_exit_thread(self, debug_event):
|
||||
self._update_debugger_state(debug_event)
|
||||
del self.threads[self.current_thread.tid]
|
||||
print("Remove TID {0}".format(self.current_thread.tid))
|
||||
|
||||
@handle_dwDebugEventCode(LOAD_DLL_DEBUG_EVENT)
|
||||
def _handle_load_dll(self, debug_event):
|
||||
self._update_debugger_state(debug_event)
|
||||
load_dll = debug_event.u.LoadDll
|
||||
print("_handle_load_dll")
|
||||
|
||||
@handle_dwDebugEventCode(UNLOAD_DLL_DEBUG_EVENT)
|
||||
def _handle_unload_dll(self, debug_event):
|
||||
self._update_debugger_state(debug_event)
|
||||
pass
|
||||
print("_handle_unload_dll")
|
||||
|
||||
@handle_dwDebugEventCode(OUTPUT_DEBUG_STRING_EVENT)
|
||||
def _handle_output_debug_string(self, debug_event):
|
||||
self._update_debugger_state(debug_event)
|
||||
pass
|
||||
print("_handle_output_debug_string")
|
||||
|
||||
@handle_dwDebugEventCode(RIP_EVENT)
|
||||
def _handle_rip(self, debug_event):
|
||||
self._update_debugger_state(debug_event)
|
||||
pass
|
||||
print("_handle_rip")
|
||||
|
||||
@@ -3,7 +3,7 @@ from ctypes import *
|
||||
from ctypes.wintypes import *
|
||||
from .winstructs import *
|
||||
|
||||
functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', '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']
|
||||
functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', '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']
|
||||
|
||||
# ExitProcess(uExitCode):
|
||||
ExitProcessPrototype = WINFUNCTYPE(VOID, UINT)
|
||||
@@ -509,3 +509,7 @@ DebugSetProcessKillOnExitParams = ((1, 'KillOnExit'),)
|
||||
DebugBreakProcessPrototype = WINFUNCTYPE(BOOL, HANDLE)
|
||||
DebugBreakProcessParams = ((1, 'Process'),)
|
||||
|
||||
# GetProcessId(Process):
|
||||
GetProcessIdPrototype = WINFUNCTYPE(DWORD, HANDLE)
|
||||
GetProcessIdParams = ((1, 'Process'),)
|
||||
|
||||
|
||||
@@ -512,6 +512,14 @@ class WinProcess(PROCESSENTRY32, Process):
|
||||
is_pythondll_injected = 0
|
||||
is_remote_slave_running = False
|
||||
|
||||
@staticmethod
|
||||
def _from_handle(handle):
|
||||
pid = winproxy.GetProcessId(handle)
|
||||
proc = [p for p in windows.system.processes if p.pid == pid][0]
|
||||
proc._handle = handle
|
||||
return proc
|
||||
|
||||
|
||||
@utils.fixedpropety
|
||||
def name(self):
|
||||
"""Name of the process
|
||||
@@ -572,6 +580,23 @@ class WinProcess(PROCESSENTRY32, Process):
|
||||
self.low_read_memory(addr, ctypes.byref(buffer), size)
|
||||
return buffer[:]
|
||||
|
||||
def read_char(self, addr):
|
||||
sizeof_char = sizeof(CHAR)
|
||||
return struct.unpack("<B", self.read_memory(addr, sizeof_char))[0]
|
||||
|
||||
def read_dword(self, addr):
|
||||
sizeof_dword = sizeof(DWORD)
|
||||
return struct.unpack("<I", self.read_memory(addr, sizeof_dword))[0]
|
||||
|
||||
def read_qword(self, addr):
|
||||
sizeof_qword = sizeof(ULONG64)
|
||||
return struct.unpack("<Q", self.read_memory(addr, sizeof_qword))[0]
|
||||
|
||||
def read_ptr(self, addr):
|
||||
if self.bitness == 32:
|
||||
return self.read_dword(addr)
|
||||
return self.read_qword(addr)
|
||||
|
||||
# Simple cache test
|
||||
# real_read = read_memory
|
||||
#
|
||||
|
||||
@@ -162,6 +162,10 @@ class WinTrustProxy(ApiProxy):
|
||||
APIDLL = "wintrust"
|
||||
default_error_check = staticmethod(no_error_check)
|
||||
|
||||
class Ole32Proxy(ApiProxy):
|
||||
APIDLL = "ole32"
|
||||
default_error_check = staticmethod(no_error_check)
|
||||
|
||||
|
||||
|
||||
class OptionalExport(object):
|
||||
@@ -245,6 +249,8 @@ GetThreadId = TransparentKernel32Proxy("GetThreadId")
|
||||
VirtualQueryEx = TransparentKernel32Proxy("VirtualQueryEx")
|
||||
GetExitCodeThread = TransparentKernel32Proxy("GetExitCodeThread")
|
||||
GetExitCodeProcess = TransparentKernel32Proxy("GetExitCodeProcess")
|
||||
GetProcessId = TransparentKernel32Proxy("GetProcessId")
|
||||
|
||||
|
||||
Wow64DisableWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64DisableWow64FsRedirection")
|
||||
Wow64RevertWow64FsRedirection = OptionalExport(TransparentKernel32Proxy)("Wow64RevertWow64FsRedirection")
|
||||
|
||||
Reference in New Issue
Block a user