PythonForWindows LocalDebugger实战:VEH本地调试与自进程单步调试的3个核心技巧
PythonForWindows LocalDebugger实战VEH本地调试与自进程单步调试的3个核心技巧【免费下载链接】PythonForWindowsA codebase aimed to make interaction with Windows and native execution easier项目地址: https://gitcode.com/gh_mirrors/py/PythonForWindowsPythonForWindows是一个让 Python 与 Windows 系统交互、执行原生代码更简单的开源项目其 windows/debug/localdbg.py 提供的LocalDebugger类让你能调试自己的 Python 进程本身——通过 VEHVectored Exception Handler向量异常处理程序捕获异常、下断点、单步执行指令无需借助外部调试器。LocalDebugger 是什么为什么需要它传统调试方式WinDbg、VS 调试器都是调试器进程调试目标进程而LocalDebugger反过来在被调试的进程内部注册一个 VEH 异常处理回调进程自己的异常断点触发、单步完成、访问违规都会先进入你编写的 Python 回调函数。它基于 Windows 的AddVectoredExceptionHandlerAPI 实现见 windows/winobject/exception.py 中的VectoredException封装原生支持两类断点断点类型常量原理特点标准断点STANDARD_BP写入int30xCC简单可靠需改写/恢复内存硬件执行断点HARDWARE_EXEC_BP使用 DrX 调试寄存器不改写代码可同时设多个断点基类定义在 windows/debug/breakpoints.pyBreakpoint、HXBreakpoint、MemoryBreakpoint均继承自它你只需子类化并重写trigger()方法即可。30 秒上手创建你的第一个本地调试器LocalDebugger实例化时会自动注册 VEH 回调源码见 windows/debug/localdbg.py 的__init__方法import windows class MyDebugger(windows.debug.LocalDebugger): def on_exception(self, exc): # 每次异常都会进入这里 print(self.get_exception_code(), self.get_exception_context().pc) d MyDebugger()两个高频 API 值得记住d.get_exception_code()—— 获取当前异常代码如EXCEPTION_BREAKPOINT、EXCEPTION_SINGLE_STEPd.get_exception_context()—— 获取当前线程的完整寄存器上下文且修改它是原地生效的无需再调set_context⚠️ 注意本地调试仅限Windows 平台且回调运行在目标线程自身的上下文中on_exception里不要做阻塞或重入式调试操作。技巧一用 single_step() 实现自进程单步调试 单步调试的核心只有一行代码——置位 EFLAGS 的TFTrap Flagdef single_step(self): Make the current thread to single step self.get_exception_context().EEFlags.TF 1 return windef.EXCEPTION_CONTINUE_EXECUTION执行single_step()后CPU 每执行完一条指令就触发一次EXCEPTION_SINGLE_STEP异常再次进入你的on_exception。于是单步 N 条指令后放行只需一个计数器class SingleSteppingDebugger(windows.debug.LocalDebugger): SINGLE_STEP_COUNT 4 def on_exception(self, exc): code self.get_exception_code() context self.get_exception_context() print(EXCEPTION !!!! Got a {0!r} at 0x{1:x}.format(code, context.pc)) self.SINGLE_STEP_COUNT - 1 if self.SINGLE_STEP_COUNT: return self.single_step() # 继续单步 return EXCEPTION_CONTINUE_EXECUTION # 放行恢复正常执行官方示例在 samples/debug/local_debugger.py它构造了一段死循环 x86 机器码在新线程里跑起来再用硬件断点命中入口、改写代码、单步 4 条指令完整演示了断点 单步的配合流程。技巧二硬件断点 HXBreakpoint 实时改写代码 ✍️硬件执行断点的最大优势是不破坏原代码断点命中后你可以直接改写该地址的指令。官方示例里有一个经典玩法——把死循环jmp现场改写成两条nopclass RewriteBreakpoint(windows.debug.HXBreakpoint): def trigger(self, dbg, exc): context dbg.get_exception_context() print(GOT AN HXBP at 0x{0:x}.format(context.pc)) # 把死循环改写为两条 nop windows.current_process.write_memory(self.addr, b\x90\x90) return dbg.single_step() # 接着单步走运行 samples/debug/local_debugger.py 可以看到类似这样的输出GOT AN HXBP at 0x6a0002 EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004) at 0x6a0003 EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004) at 0x6a0004 EXCEPTION !!!! Got a EXCEPTION_SINGLE_STEP(0x80000004) at 0x6a0005断点命中 → 改写指令 → 单步穿过 → 原代码自然执行下去整个过程零崩溃、零补丁痕迹。 技巧add_bp的地址参数除了整数地址还支持DLL!ApiName或DLL!偏移字符串形式如ntdll!LdrLoadDllLocalDebugger._local_resolve会基于当前进程 PEB 模块列表自动解析为绝对地址这对断在系统 API 入口非常实用。技巧三把 LocalDebugger 注入其他进程做伪本地调试 因为 LocalDebugger 的本质只是进程内 VEH Python 回调它可以被注入到任意 32 位进程中使用。官方示例 samples/debug/local_debugger_remote_process.py 启动了一个挂起状态的 32 位 Python 进程注入脚本后在里面注册LocalDebugger并给LdrLoadDll下了硬件断点——此后目标进程每次加载 DLL 都会打印日志class YOLOHXBP(windows.debug.HXBreakpoint): def trigger(self, dbg, exc): # 从栈上提取 UNICODE_STRING读出 DLL 名称 ... print(I AM LOADING {0}.format(dll_loaded)) d windows.debug.LocalDebugger() d.add_bp(YOLOHXBP(ldr))这是行为监控、加载器分析、反调试研究等场景的高性价比方案。常见问题与避坑清单 ⚠️断点自删trigger()内可以调用del_bp(self)一次性删除断点框架会自动恢复原始字节并处理单步穿过见_pass_breakpoint逻辑。回调里禁止再触发断点陷阱VEH 回调中抛 Python 异常会被VectoredException装饰器捕获并打印windows/winobject/exception.py返回EXCEPTION_CONTINUE_SEARCH交给下一个处理器。返回值语义回调必须返回EXCEPTION_CONTINUE_SEARCH交给后续处理器或EXCEPTION_CONTINUE_EXECUTION恢复执行这两个常量定义在 windows/winobject/exception.py。多进程调试请换用 Debugger如果需要调试其他进程带DEBUG_PROCESS启动应使用 windows/debug/debugger.py 的Debugger类它额外支持内存断点VirtualProtect 方案并内置事件循环loop()。相关文档与延伸阅读调试模块文档docs/source/debug.rst含LocalDebugger、Breakpoint完整 API 说明与符号调试章节本地调试示例输出docs/source/samples_output/debug_local_debugger.txt远程单步 内存断点示例samples/debug/debugger_membp_singlestep.py调试测试用例tests/test_debugger.py掌握VEH 回调 单步标志位 硬件断点这三件套你就可以用不到百行 Python 代码构建一个属于自己的进程内调试与指令级监控工具了。【免费下载链接】PythonForWindowsA codebase aimed to make interaction with Windows and native execution easier项目地址: https://gitcode.com/gh_mirrors/py/PythonForWindows创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考