diff --git a/TODO b/TODO index 389b9e6..3bc6d43 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,9 @@ TODO: - CRASH if API is not found.. - fail when resolving xxxW function + - Debugger: + - clean Syswow64 debugging code (_handle_syswow64_exception) + FIXME: - WMI - COM initialisation when injected in another process diff --git a/windows/debug.py b/windows/debug.py index b9be50a..34b3d3c 100644 --- a/windows/debug.py +++ b/windows/debug.py @@ -86,7 +86,6 @@ class Debugger(object): bp.trigger(self, exception) return bp - def _setup_breakpoint_BP(self, bp, targets): for target in targets: if not isinstance(target, WinProcess): @@ -154,10 +153,41 @@ class Debugger(object): def _handle_unknown_debug_event(self, debug_event): raise NotImplementedError("dwDebugEventCode = {0}".format(debug_event.dwDebugEventCode)) + def _handle_syswow64_exception(self, debug_event): + exception = debug_event.u.Exception + self._update_debugger_state(debug_event) + exception.__class__ = windows.vectored_exception.EEXCEPTION_DEBUG_INFO64 + excp_code = exception.ExceptionRecord.ExceptionCode + excp_addr = exception.ExceptionRecord.ExceptionAddress + if excp_code in [EXCEPTION_BREAKPOINT, 0x4000001f] and excp_addr in self.breakpoints: + self._dispatch_breakpoint(exception, excp_addr) + self._pass_breakpoint(excp_addr) + return + elif excp_code in [EXCEPTION_SINGLE_STEP, 0x4000001e]: + if self.current_thread.tid in self._breakpoint_to_reput: + addr = self._breakpoint_to_reput[self.current_thread.tid] + del self._breakpoint_to_reput[self.current_thread.tid] + # Re-put the breakpoint + self.current_process.write_memory(addr, "\xcc") + elif excp_addr in self.breakpoints: + # Verif that's not a standard BP ? + bp = self.breakpoints[excp_addr] + bp.trigger(self, exception) + ctx = self.current_thread.context + ctx.EEFlags.RF = 1 + self.current_thread.set_context(ctx) + else: + self.on_exception(exception) + else: # Do not trigger self.on_exception if breakpoint was registered + self.on_exception(exception) + def _handle_exception(self, debug_event): """Handle EXCEPTION_DEBUG_EVENT""" exception = debug_event.u.Exception self._update_debugger_state(debug_event) + if windows.current_process.bitness == 64 and self.current_process.bitness == 32: + return self._handle_syswow64_exception(debug_event) + if self.current_process.bitness == 32: exception.__class__ = windows.vectored_exception.EEXCEPTION_DEBUG_INFO32 else: diff --git a/windows/test/mytest.py b/windows/test/mytest.py index 0c90559..6f920b5 100644 --- a/windows/test/mytest.py +++ b/windows/test/mytest.py @@ -423,8 +423,16 @@ class DebuggerTestCase(unittest.TestCase): d.current_process.exit() calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS) + + if windows.current_process.bitness == 32: + LdrLoadDll32 = windows.current_process.peb.modules[1].pe.exports["LdrLoadDll"] + else: + calcref = pop_calc_32() + LdrLoadDll32 = calcref.peb.modules[1].pe.exports["LdrLoadDll"] + calcref.exit() + d = windows.debug.Debugger(calc) - d.add_bp(TSTBP(windows.current_process.peb.modules[1].pe.exports["LdrLoadDll"])) + d.add_bp(TSTBP(LdrLoadDll32)) d.loop() def test_simple_hwx_breakpoint(self): @@ -438,8 +446,16 @@ class DebuggerTestCase(unittest.TestCase): d.current_process.exit() calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS) + + if windows.current_process.bitness == 32: + LdrLoadDll32 = windows.current_process.peb.modules[1].pe.exports["LdrLoadDll"] + else: + calcref = pop_calc_32() + LdrLoadDll32 = calcref.peb.modules[1].pe.exports["LdrLoadDll"] + calcref.exit() + d = windows.debug.Debugger(calc) - d.add_bp(TSTBP(windows.current_process.peb.modules[1].pe.exports["LdrLoadDll"])) + d.add_bp(TSTBP(LdrLoadDll32)) d.loop() def test_multiple_hwx_breakpoint(self): @@ -489,7 +505,7 @@ class DebuggerTestCase(unittest.TestCase): calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS) d = windows.debug.Debugger(calc) addr = calc.virtual_alloc(0x1000) - calc.write_memory(addr, "\x90" * 8) + calc.write_memory(addr, "\x90" * 8 + "\xc3") d.add_bp(TSTBP(addr, 0)) d.add_bp(TSTBP(addr + 1, 1)) d.add_bp(TSTBP(addr + 2, 2)) @@ -530,7 +546,7 @@ class DebuggerTestCase(unittest.TestCase): calc = pop_calc_32(dwCreationFlags=DEBUG_PROCESS) d = MyDbg(calc) addr = calc.virtual_alloc(0x1000) - calc.write_memory(addr, "\x90" * 2) + calc.write_memory(addr, "\x90" * 2 + "\xc3") d.add_bp(TSTBP(addr, 0)) calc.create_thread(addr, 0) d.loop() diff --git a/windows/vectored_exception.py b/windows/vectored_exception.py index fe6a4ea..325faf4 100644 --- a/windows/vectored_exception.py +++ b/windows/vectored_exception.py @@ -41,7 +41,7 @@ def generate_enhanced_exception_record(base, name_suffix=""): @property def ExceptionCode(self): real_code = super(EnhancedEXCEPTION_RECORD, self).ExceptionCode - return exception_name_by_value.get(real_code, 'UNKNOW_EXCEPTION({0})'.format(hex(real_code))) + return exception_name_by_value.get(real_code, windows.generated_def.windef.Flag("UNKNOW_EXCEPTION", real_code)) @property def ExceptionAddress(self):