window服务调试(二):调试windows服务方法
调试服务程序的方法有三种 直接设置EIP法 设置循环法 设置JIT法
一、直接设置EIP法
较为简单的服务程序,可以用这个方法,直接启动调试,用调试器设置当前EIP为svcMain的入口,调试功能
二、设置循环法
由于直接调试的服务程序与SCM(Services Control Manager)启动的程序表现不一样,所以我们用附加SCM启动的程序,但是有个问题是,一旦启动那么就会执行功能,我们如何动态调试前面的功能呢,其实很简单,我只要的服务程序的入口点设置无限循环如EB FE
,这个指令的意思是跳转到当前位置,这样就会陷入无限循环,这个时候附加后还原改动的代码就能调试完整的功能了
上面的EB FE
是自循环指令,可能会导致调试器断点设置失败
我们可多往上跳转几个字节,如下图所示
但是注意在循环中有push ebp
,这个指令,由于栈空间是有限的,所以这样程序会崩溃,我们把循环中的指令都改成nop(记得保存原来的指令)
事实上循环中最好全部改成nop,避免造成和正常逻辑不同的影响
三、设置JIT法
设置JIT法就是设置默认调试器,每当系统接收到的程序不能自己处理的异常就会启动默认调试器,所以我们可以修改程序在合适的位置触发异常,这样当异常发生的时候就会自动打开调试器附加程序,这个时候附加后还原改动的代码就能调试完整的功能了
1.延长服务启动时间
SCM开始启动服务后,默认等待30秒,若30秒后,服务程序没有设置启动标识为运行,SCM就会认为启动失败,这时我们可以修改注册表的HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServicesPipeTimeout
值可以设长一点,单位为秒
2.开启JIT自动附加
- 32位调试器程序注册表路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug - 64位调试器程序注册表路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
在这个表下有个 REG_SZ 类型的 Auto 子项, 这个子项的键值我系统上缺省是 0, 测试发现把他手动修改成1 就能即时调试了.
3.JIT的设置方法
x64dbg和ollydeg都有自动设置
x64dbg:
菜单栏选择 选项(o)->选项(p)->杂项->将这份x64dbg设为即时调试器
ollydbg:
菜单栏选择 选项(T)->实时调试设置(J)->设置OllyICE为实时调试器
JIT法并不不是万能的,有两种情况是无法即时附加的
1.异常发生带dllMain里面的,无法被即时调试
2.异常被异常处理程序处理的,无法被即时调试(因为程序只有在没有任何异常处理的时候调用系统的默认异常处理时,会去尝试即时附加)