Life
只有不断探索,才会有不断的进步,每一天都是美好的一天
上个方案回顾
老实说,上一篇文章里面的方案,我自己并不是很满意,原因就是每次都得加载下脚本,解析,然后才能工作,这样子会浪费很多的时间,所以,在实际使用时,还是得使用下函数的方案。于是乎就有了这篇令我满意的文章。
前提
在使用javascript 前,还是需要初始化环境
kd>.load jsprovider.dll
kd> .scriptproviders
Available Script Providers:
NatVis (extension '.NatVis')
JavaScript (extension '.js')
之后,先把脚本加载到内存
kd> .scriptload e:\bug\auto.js
JavaScript script successfully loaded from 'e:\bug\auto.js'
设置断点
脚本里面的内容如下
// WinDbg JavaScript sample
function IsNeedBreak()
{
var ctl = host.namespace.Debugger.Utility.Control;
host.diagnostics.debugLog("called\n");
ctl.ExecuteCommand("r $t0=0x0");
var stackInfo = ctl.ExecuteCommand("kv");
for (var line of stackInfo)
{
host.diagnostics.debugLog(line+"\n");
if(line.indexOf("AtdrAgent") != -1 ){
host.diagnostics.debugLog("hit \n");
ctl.ExecuteCommand("r $t0=0x1");
break;
}
}
host.diagnostics.debugLog("go on \n");
}
虽然脚本加载后,无法解析出来里面的函数,但是直接使用还是没问题的。
kd> dx Debugger.State.Scripts.auto.Contents
Debugger.State.Scripts.auto.Contents : [object Object]
host : [object Object]
下面就可以直接设置断点了
kd> bp nt!NtTerminateProcess "dx Debugger.State.Scripts.auto.Contents.IsNeedBreak(); .if (@$t0 == 1) {} .else {gc}"
breakpoint 0 redefined
kd> bl
0 e Disable Clear 840b8a51 0001 (0001) nt!NtTerminateProcess "dx Debugger.State.Scripts.auto.Contents.IsNeedBreak(); .if (@$t0 == 1) {} .else {gc}"
经过优化后的脚本,速度比以前有了很大的改善,这才是心目中想象的样子
called
# ChildEBP RetAddr Args to Child
00 9c6f7140 866561a9 8000151c 00000000 00000000 nt!NtTerminateProcess
WARNING: Frame IP not in any known module. Following frames may be wrong.
01 9c6f71e8 83e8fa6a 8000151c 00000000 9c6f72bc 0x866561a9
<Intermediate frames may have been skipped due to lack of complete unwind>
02 9c6f71e8 83e8e8d9 (T) 8000151c 00000000 9c6f72bc nt!KiSystemServicePostCall (FPO: [0,3] TrapFrame @ 9c6f71f8)
<Intermediate frames may have been skipped due to lack of complete unwind>
03 9c6f7268 9289c4bd (T) 8000151c 00000000 00000000 nt!ZwTerminateProcess+0x11 (FPO: [2,0,0])
04 9c6f72bc 92887133 00001de4 00001e08 00000001 AtdrAgent+0x194bd
hit
go on
Debugger.State.Scripts.auto.Contents.IsNeedBreak()
nt!NtTerminateProcess:
840b8a51 8bff mov edi,edi
后记
上面的脚本内容里面还是有点不够优雅,后来经过改良,变成了下面这样子
kd> bp nt!NtTerminateProcess "dx @$t0=Debugger.State.Scripts.auto.Contents.IsNeedBreak(); .if (@$t0 == 1) {} .else {gc}"
breakpoint 0 redefined
改良的地方从脚本内设置 @$t0 变成了 @$t0 接收函数的返回值,这样子就实现了真正调用函数一样的习惯。 且减少了内部不必要的调用,脚本内容如下:
// WinDbg JavaScript sample
function IsNeedBreak()
{
var ctl = host.namespace.Debugger.Utility.Control;
host.diagnostics.debugLog("called\n");
var bBreak = 0;
var stackInfo = ctl.ExecuteCommand("kv");
for (var line of stackInfo)
{
host.diagnostics.debugLog(line+"\n");
if(line.indexOf("AtdrAgent") != -1 ){
host.diagnostics.debugLog("hit \n");
bBreak = 1
break;
}
}
host.diagnostics.debugLog("go on \n");
return bBreak;
}
至此完美了