x64dbg 中的 JIT 调试器设置命令 setjit/jitset 完全指南
【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg
导读:本文围绕 x64dbg 的
setjit(别名jitset)命令展开,讲解如何在 Windows 系统上将 x64dbg 注册为 Just-In-Time(JIT)调试器,涵盖 x86/x64 双架构 JIT 条目、旧条目备份与恢复、AeDebug 注册表底层机制、管理员权限要求等核心细节。读完本文,你将能熟练使用setjit及同族的getjit、getjitauto、setjitauto命令,实现"程序崩溃即自动拉起 x64dbg 附加调试"的完整工作流。
JIT 调试器机制概述
在 Windows 中,当一个进程发生未处理异常而崩溃时,系统会检查注册表中的AeDebug键,读取其中保存的调试器命令行,并把崩溃进程附加到该调试器上,这就是 JIT(Just-In-Time)调试机制。x64dbg 通过setjit命令把自身写入这个注册表位置,从而在目标程序崩溃时自动启动并附加。
Windows 的 JIT 配置存储在注册表键HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug下,这一点可以在 jit.h 中直接确认:
#define JIT_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug"该键下有两个关键值:
| 注册表值名 | 含义 | 对应命令 |
|---|---|---|
Debugger | JIT 调试器命令行 | setjit/getjit |
Auto | 崩溃后是否自动附加(1 为自动,0 为弹窗确认) | setjitauto/getjitauto |
32/64 位双 JIT 条目
在 64 位(WIN64)Windows 系统中,存在两个JIT 条目:一个供 x86(x32)调试器使用,另一个供 x64 调试器使用。当一个 x86 进程崩溃时,Windows 会附加 x32-JIT 条目中保存的 x32 调试器;同理,x64 进程崩溃时使用 x64-JIT 条目。
x64dbg 在底层通过注册表访问标志KEY_WOW64_32KEY/KEY_WOW64_64KEY来区分两个条目,见 jit.cpp:
if(arch_in == x64) { #ifndef _WIN64 if(!IsWow64()) { if(error != NULL) *error = ERROR_RW_NOTWOW64; return false; } key_flags |= KEY_WOW64_64KEY; #endif //_WIN64 } else if(arch_in == x32) { #ifdef _WIN64 key_flags |= KEY_WOW64_32KEY; #endif }这里体现了两个重要约束(也是官方文档强调的两条注意事项):
- 从 x64 调试器修改 x32-JIT 条目:可以,只需使用
x32参数(x64 进程原生支持通过KEY_WOW64_32KEY访问 32 位注册表视图)。 - 从 x32 调试器修改 x64-JIT 条目:仅当该 x32 调试器运行在 WIN64 系统上才允许(即 x32 调试器本身是 WOW64 进程),且必须使用
x64参数。如果当前进程不是 WOW64 进程,操作会失败并返回ERROR_RW_NOTWOW64错误。
setjit/jitset 命令语法
命令的完整形式为setjit [arg1] [arg2],别名是jitset。其解析逻辑实现在 cmd-misc.cpp 的cbDebugSetJIT函数中,参数行为与文档一一对应。
无参数:把当前调试器设为 JIT
setjit不携带任何参数时,x64dbg 会把当前正在运行的调试器自身注册为当前架构(x86 版设置 x32-JIT,x64 版设置 x64-JIT)的 JIT 调试器。
这一步依赖dbggetdefjit生成默认命令行。从 jit.cpp 可以看到,默认命令由当前可执行文件路径加上附加参数拼接而成:
#define ATTACH_CMD_LINE "\" -a %ld -e %ld"即写入注册表的完整命令行形如:
"C:\...\x64dbg\x64\x64dbg.exe" -a %ld -e %ld其中-a接收进程 ID,-e接收事件句柄,Windows 在进程崩溃时用实际值替换%ld后执行。
arg1 = oldsave:备份旧 JIT 并设置当前调试器
setjit oldsave两步操作(见 cmd-misc.cpp):
- 先读取当前注册表中的 JIT 条目,将其保存到 x64dbg 数据库(
BridgeSettingSet("JIT", "Old", ...)); - 再把当前调试器设置为 JIT。
只有当读到的旧条目与当前调试器路径不同时才会真正写入备份,避免无意义覆盖。
arg1 = restore:恢复之前保存的旧 JIT 并清除备份
setjit restore把此前通过oldsave保存的旧 JIT 条目写回注册表,恢复系统原有配置,然后从数据库中删除备份(BridgeSettingSet("JIT", 0, 0),见 cmd-misc.cpp)。如果数据库中没有任何旧条目,命令会报错Error there is no old JIT entry stored.。
arg1 = old:把保存的旧 JIT 设为当前 JIT
setjit old与restore类似,将数据库JIT/Old中保存的旧条目写回注册表,但不会删除备份记录。适合反复切换的场景。
arg1 = old,arg2 = 自定义条目:保存新的旧 JIT 备份
setjit old "C:\path\to\other\debugger.exe"不写注册表,只是把arg2指定的命令行作为"旧 JIT 条目"存入数据库,供后续setjit old/setjit restore使用。命令成功后会输出New OLD JIT stored: <arg2>。
arg1 = x32 / x64:指定架构写入 JIT
setjit x32 "C:\path\to\x86_debugger.exe" setjit x64 "C:\path\to\x64_debugger.exe"显式指定要写入哪个架构的 JIT 条目,arg2为完整的调试器命令行。这正是前面提到的跨架构操作入口:
- 在 x64 调试器中用
x32参数可修改 x32-JIT 条目; - 在 WIN64 系统上的 x32 调试器中用
x64参数可修改 x64-JIT 条目(非 WOW64 进程会报Error using x64 arg. The debugger is not a WOW64 process); - 其余非法参数会提示
Unknown JIT entry type. Use OLD, x64 or x32 as parameter.。
注意:命令帮助中提到的 "x86" 在文档与源码中实际以
x32为准,cmd-misc.cpp的错误提示里两者混用,实际解析只接受x32。
权限要求
所有写入 JIT 注册表键的操作都必须以管理员权限运行 x64dbg。cbDebugSetJIT在开头就做了检查(cmd-misc.cpp):
if(!BridgeIsProcessElevated()) { dputs(QT_TRANSLATE_NOOP("DBG", "Error run the debugger as Admin to setjit\n")); return false; }同理,setjitauto也需要管理员权限。非管理员运行时会直接报错Error run the debugger as Admin to setjit。这背后的原因是HKEY_LOCAL_MACHINE下的 AeDebug 键默认只允许管理员写入——在底层readwritejitkey中,写操作还会再次校验进程是否提升权限并返回ERROR_RW_NOTADMIN(见 jit.cpp)。
读取(getjit)则不需要管理员权限,仅以KEY_READ打开键。
命令执行结果
setjit命令不会设置任何结果变量(如$result),成功与否只能通过命令输出判断:
- 成功时输出形如
New JIT x64: "C:\...\x64dbg.exe" -a %ld -e %ld的确认信息; - 失败时根据错误类型输出对应提示(无旧条目、非 WOW64、非管理员等)。
JIT 命令族配套使用
setjit通常与同目录下的其他 JIT 命令配合使用,构成完整的"备份 → 设置 → 恢复"闭环:
| 命令 | 作用 | 文档位置 |
|---|---|---|
getjit/jitget | 读取当前(或指定 x32/x64)JIT 条目;getjit old读取数据库备份 | getjit.md |
setjitauto/jitsetauto | 设置 Auto 标志:1/ON为崩溃后免确认自动附加,0/OFF为弹窗确认;也支持setjitauto x32 1这种按架构设置 | setjitauto.md |
getjitauto/jitgetauto | 读取 Auto 标志当前值,同样支持x32/x64参数 | getjitauto.md |
Auto 标志对应 AeDebug 键下的Auto值("1"为真、"0"为假,见 jit.cpp 的dbggetjitauto)。当 Auto = FALSE 时,即使设置了 JIT 调试器,Windows 在附加前仍会弹出确认对话框;设置为 TRUE 后则直接附加,这一行为对恶意软件分析场景尤其重要——目标程序崩溃瞬间自动进入调试器,不给进程清理或反调试逻辑喘息机会。
实际使用中,这套命令族全部收录在 misc 命令目录 下,属于"杂项命令"分类。
典型实战流程
下面给出一个完整的逆向分析工作流示例(以管理员身份运行 x64dbg):
; 1. 备份系统当前的 JIT 配置(含 32 位与 64 位) setjit oldsave ; 2. 把当前调试器设为 JIT(无参数即针对当前架构) setjit ; 3. 如需同时接管另一架构,可显式指定 setjit x32 "C:\x64dbg\x32\x32dbg.exe" setjit x64 "C:\x64dbg\x64\x64dbg.exe" ; 4. 关闭附加前的确认弹窗,实现崩溃即附加 setjitauto 1 ; 5. 验证配置是否生效 getjit getjit x32 getjit x64 getjitauto ; 6. 分析完毕后恢复系统原有配置并清除备份 setjit restore从源码实现看,这套命令的完整调用链为:命令行解析 →cbDebugSetJIT(cmd-misc.cpp)→dbgsetjit/dbggetdefjit(jit.cpp、jit.cpp)→readwritejitkey(jit.cpp)→ 注册表 API。理解这条链有助于排查问题:凡是"设置失败"类报错,基本都能归因到权限(非管理员)、WOW64 限制或注册表值缺失三类原因之一。
常见问题排查
Error run the debugger as Admin to setjit:当前 x64dbg 未以管理员权限运行,右键"以管理员身份运行"后重试。Error using x64 arg. The debugger is not a WOW64 process:在 32 位系统或原生 32 位环境中尝试用x64参数访问 64 位 JIT 条目,该操作仅限 WIN64 系统上的 WOW64 进程。Error there is no old JIT entry stored.:执行old/restore前未先执行过oldsave,数据库中不存在JIT/Old备份。Unknown JIT entry type. Use OLD, x64 or x32 as parameter.:arg1拼写错误,合法值只有old、oldsave、restore、x32、x64。
以上行为均可对照 setjit.md 原始文档与 cmd-misc.cpp 命令实现逐一验证,确保每一步操作都有据可依。
【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考