x64dbg serun/sego 命令详解:吞掉异常并继续运行调试器 📅 发布时间:2026/9/19 14:48:37 👁 浏览次数: x64dbg serun/sego 命令详解吞掉异常并继续运行调试器【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg导读serun别名sego是 x64dbg 调试器专用于异常场景的运行命令。当调试器因异常而中断停锁时serun会在不通知被调试程序的情况下吞掉当前异常、跳过调试对象内的异常分发并立即释放调试锁让程序继续运行。本文结合 关联文档 与 命令实现源码完整讲解其用法、底层实现、与run/erun的区别以及在反调试与异常分析中的典型实战场景。一、命令速览项目说明命令名serun别名sego所属类别debug-control调试控制注册位置src/dbg/x64dbg.cpp#L152dbgcmdnew(serun,sego, cbDebugSerun, true); //run swallow exception功能定位吞掉当前异常 放行程序继续运行是否设置结果变量否serun与同族的seStepIntosrc/dbg/x64dbg.cpp#L157、seStepOversrc/dbg/x64dbg.cpp#L160共享相同的seswallow exception吞异常前缀语义是异常中断场景下继续执行一族命令的成员。二、参数与结果变量参数serun [arg1] sego [arg1][arg1]可选指定一个地址或表达式。当提供该参数时x64dbg 会在该位置放置一个一次性single-shot断点然后才开始运行。程序运行到该地址时自动停下相当于运行到此处。若省略参数则直接释放调试锁程序无条件下继续运行直到遇到下一个断点或异常。结果变量根据 serun.md 的说明该命令不设置任何结果变量如$result等因此不能在脚本中依赖其返回值判断执行结果判断执行是否成功应依靠后续的调试状态如是否停到目标断点或检查dbgisrunning()之类的状态。参数内部处理arg1参数并不是独立实现的运行到地址逻辑而是复用断点命令在 cbDebugRunInternal 中当argc 2时执行DbgCmdExecDirect(StringUtils::sprintf(bp \%s\, ss, argv[1]).c_str())即内部调用bp 地址, ss设置一个一次性single-shotss软件断点后再放行程序。因此arg1支持 x64dbg 断点命令所接受的地址表达式语法。三、底层实现两步走serun的命令处理函数 cbDebugSerun 实现非常简洁仅两行bool cbDebugSerun(int argc, char* argv[]) { cbDebugContinue(argc, argv); return cbDebugRunInternal(argc, argv, history_clear); }可以看出serun是两步操作的组合第一步设置异常处理状态吞掉异常调用 cbDebugContinue即continue命令的处理函数。由于serun通常不带参数调用此时走argc 2分支dbgsetcontinuestatus(DBG_CONTINUE); dputs(QT_TRANSLATE_NOOP(DBG, Exception will be swallowed));dbgsetcontinuestatus(DBG_CONTINUE)将当前异常的继续状态设置为DBG_CONTINUE表示异常已被处理调试器后续会把该异常当作已处理事件返回给系统不再向被调试程序分发。这也正是文档中swallowing the current exception, skipping exception dispatching in the debuggee吞掉当前异常、跳过调试对象内的异常分发的实现位置。第二步释放锁并放行调用 cbDebugRunInternal清空/记录历史此处传history_clear即清空历史若提供了arg1先执行bp arg1, ss设置一次性断点若程序已在运行则直接返回调用GuiSetDebugStateAsync(running)将 GUI 状态切为运行中调用unlock(WAITID_RUN)释放调试等待锁唤醒调试循环让程序继续执行触发CB_RESUMEDEBUG插件回调通知各插件调试已恢复。四、与 run、erun 的差异对比在 cmd-debug-control.cpp 中三个运行命令并排实现语义差异非常清晰命令处理函数异常处理适用场景run/go/r/gcbDebugRun不做特殊处理仅跳过 INT3 单步skipInt3Stepping普通运行交由异常过滤器决定是否中断eruncbDebugErun未运行时调用dbgsetskipexceptions(true)开启跳过所有异常模式想连续跨过后续所有异常直到目标serun/segocbDebugSerun将当前这一次异常标记为已处理DBG_CONTINUE只吞掉当前这次异常立即继续关键区别在于erun是跳过未来所有异常通过dbgsetskipexceptions(true)设置全局跳过标志bSkipExceptions见 debugger.cpp#L61、debugger.cpp#L2311后续异常在(bSkipExceptions || filter.breakOn ! ExceptionBreakOn::FirstChance) (!maxSkipExceptionCount || skipExceptionCount maxSkipExceptionCount)条件下不再停表直到再次遇到显式断点。serun是只处理当前这一次它只修改当前异常的继续状态异常循环回到 debugger.cpp#L2310 的dbgsetcontinuestatus(...)时已设置的DBG_CONTINUE会生效——注意 debugger.cpp#L2301-L2313 中首次异常会按过滤器重置继续状态若过滤器配置为中断所有首次异常则下一次异常仍会照常中断。这正是serun与erun行为差异的本质。提示还有无前缀的continue命令cbDebugContinue它只设置异常继续状态、不释放运行锁必须配合run族命令使用。serun则是把设状态和放行合并为一条命令。五、异常中断循环中的执行流程当程序在异常处被 x64dbg 停住时执行serun的完整流程为调试器当前处于异常中断态调试循环停在异常处理处WAITID_RUN等待锁被占用用户执行serun或不带参数的segocbDebugContinue(argc, argv)以argc 2进入dbgsetcontinuestatus(DBG_CONTINUE)把当前异常继续状态设为已处理cbDebugRunInternal检查是否提供了目标地址有则下一次性断点、检查程序是否已在运行unlock(WAITID_RUN)释放等待锁调试循环从 debugger.cpp 的等待点恢复调试器把DBG_CONTINUE返回给 Windows 调试 API异常被标记为已处理不会进入被调试程序的 SEH 异常处理链程序继续运行直到下一次断点或异常。正是因为第 6 步异常不再进入程序自身的处理链serun成为反调试场景与异常陷阱绕过的常用手段。六、典型实战场景场景一跳过反调试异常陷阱许多保护壳/反调试代码会在执行路径上主动触发异常如int3、int 2d并用结构化异常处理SEH检测异常是否被正常处理从而判断是否处于调试状态。此时若直接run异常处理链会被触发、程序可能走反调试分支而执行serun后异常被调试器吞掉、不进入程序处理链可让程序按未发生异常的路径继续执行。注意serun吞异常是代为处理而非转发给程序若程序依赖该异常被自身 SEH 捕获行为会与真实环境不同需结合具体样本判断。场景二快速跨过频繁的良性异常某些程序在正常运行中会高频产生良性异常如未处理的内存访问探测。在异常中断后逐个按run效率低下可执行serun立即放行当前这一次若此类异常会反复触发改用erun一次性跳过后续所有异常可通过 Engine/MaxSkipExceptionCount 配置 限制跳过的异常数量上限避免完全失控更精细的做法是在 异常过滤器 中将该异常类型配置为不中断从源头减少停表。场景三运行到目标位置serun 00401000先设置一次性断点于0x00401000再放行等价于运行到该地址常用于从异常点快速跳到关键代码段。场景四脚本化控制在 x64dbg 脚本脚本命令参考中serun ; 吞掉当前异常继续跑 serun 7FF700000000 ; 或一路跑到指定地址由于serun不设置结果变量脚本中如需判断是否到达目标可配合在目标地址预置断点并检查是否停在该地址来验证。七、相关命令对照命令别名行为文档rungo、r、g普通运行run.mderun-跳过异常运行erun.mdserunsego吞异常运行serun.mdStepIntosti、si等单步步入StepInto.mdseStepIntosesti等吞异常单步seStepInto.mdcontinue-仅设置异常继续状态-八、源码索引命令注册src/dbg/x64dbg.cpp#L152处理函数声明src/dbg/commands/cmd-debug-control.h#L18处理函数实现src/dbg/commands/cmd-debug-control.cpp#L386-L390运行内部逻辑含一次性断点与解锁src/dbg/commands/cmd-debug-control.cpp#L46-L65异常继续状态设置src/dbg/commands/cmd-debug-control.cpp#L483-L496异常循环与继续状态生效点src/dbg/debugger.cpp#L2301-L2313异常过滤器配置说明docs/gui/settings/Exceptions.md结语serun/sego的核心价值在于把吞掉当前异常与继续运行两个动作原子化一条命令即可完成continue加run的组合。理解其底层对DBG_CONTINUE的设置逻辑以及它相对于run不干预异常与erun跳过全部异常的差异是准确使用异常控制命令、高效绕过反调试陷阱的关键。在调试会话中根据只处理这一次还是跳过后续所有的意图在serun与erun之间做选择能显著提升异常密集场景下的调试效率。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考