Still playing will debug API + add Winprocess.read_[dq]word

This commit is contained in:
hakril
2016-01-21 00:43:41 +01:00
parent 6b75fe3185
commit f6f206b842
5 changed files with 133 additions and 22 deletions
+5 -1
View File
@@ -725,4 +725,8 @@ BOOL WINAPI DebugSetProcessKillOnExit(
BOOL WINAPI DebugBreakProcess (
__in HANDLE Process
);
);
DWORD WINAPI GetProcessId(
_In_ HANDLE Process
);
+92 -20
View File
@@ -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")
+5 -1
View File
@@ -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'),)
+25
View File
@@ -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
#
+6
View File
@@ -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")