Dom*_*que 1 debugging scripting windbg dump
我需要定期以相同的方式调查转储文件,并且我想自动执行此操作。我正在使用 Windbg 作为工具,并且正在考虑使用 Windbg 脚本。
我已经对 PYKD 进行了一些初步尝试,但我不太喜欢这种开销,因此我选择了标准 Windbg 脚本,但这正在陷入一场噩梦,让我向您展示我想要做什么:
0:001> kb
# RetAddr : Args to Child : Call Site
00 00007ffc`26272685 : ffffffff`fffffffe 00007ff7`06e563f0 00007ff7`00000000 0000005a`1fb6fd70 : user32!NtUserGetMessage+0xa
01 00007ff7`06d87596 : 00000000`00000008 00007ff7`06e5d048 00000000`00007c1c 0000005a`00000004 : user32!GetMessageW+0x25
02 00007ff7`06d87673 : 0000005a`1f2b3710 00007ff7`06e5c7d0 0000005a`1f2ac270 00000000`00000002 : <Application>!CServiceModule::Run+0x8ee [sourcefile.cpp @ 1905]
03 00007ffc`26875ada : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : <Application>!CServiceModule::ServiceMain+0x63 [sourcefile.cpp @ 1379]
04 00007ffc`26ef13d2 : 00007ffc`26875aa0 0000005a`1f2ac270 00000000`00000000 00000000`00000000 : sechost!ScSvcctrlThreadA+0x3a
05 00007ffc`270454f4 : 00007ffc`26ef13b0 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x22
06 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x34
0:001> dx Debugger.Sessions[0].Processes[26520].Threads[14812].Stack.Frames[2].SwitchTo();dv /t /v
// The second command "dx ..." happens by clicking on the DML link of the line, corresponding with the line, containing "CServiceModule::Run".
Run Code Online (Sandbox Code Playgroud)
现在,如何在 Windbg 脚本中执行此操作?
kb命令并将结果放入变量中。(如何做到这一点?我已经尝试过使用asandaS但似乎都不起作用)如果我无法kb在一个变量中获得完整结果,请尝试使用 a .foreach,如下例所示:
.foreach ( token { kb} )
{
.printf "TEST\n"
}
Run Code Online (Sandbox Code Playgroud)
=> 即使这样也不起作用:kb大约有 8 行结果,而该单词TEST被打印了 78 次。
不要打印“TEST”一词,而是打印变量token并看看它是什么样子。
=> 如何做到这一点?我已经尝试过.printf "%msu \n" , ${token},或者@$token,...但没有任何效果。
即使我得到这个工作:我怎样才能进行字符串操作,十进制/十六进制数字转换,......?
不要忘记:如何编译这样的脚本?我目前正在尝试在 Windbg 中运行脚本,有时会出现编译错误,但这些错误非常不可读(我添加了一个新行,导致了问题,但复杂错误(不是打字错误)甚至没有提到新添加的线)。
您可能会说:只需看看此 URL下提到的示例,但我找不到正在运行的标准 Windbg 命令的示例,并将其结果存储在变量中(这是我需要的第一件事)去做)。
如果我的脚本能够正常工作,我可能会将这篇文章变成针对提到的(和新添加的)问题的通用“Windbg 脚本常见问题解答”。
在第一个答案后编辑
我意识到我错误地使用了命令kb:我需要使用的实际命令是~* k,给出以下结果:
(小注:我只是一个屏幕截图,而不是文本副本,以强调 DML 超链接)
如您所见,有一些 DML 结果,我想“单击”包含CServiceModule::Run. 当我手动执行此操作时,似乎有以下命令的翻译:
dx Debugger.Sessions[0].Processes[26520].Threads[14812].Stack.Frames[2].SwitchTo()
Run Code Online (Sandbox Code Playgroud)
这里26520是6798的HexToDec转换,
14812是39DC的HexToDec转换。
(两者均可从屏幕截图中检索Id: 6798.39dc)
所以我“需要”字符串操作和 HexToDec 转换来模拟 DML 单击。但是,如果您知道一种更简单的方法来将此“单击”操作放入脚本中,我将非常非常感激!
for .foreach 空格是分隔符,此命令不适用于读取行
如果您想打印令牌,请按原样在别名解释器中使用它
0:001> kb
# ChildEBP RetAddr Args to Child
00 0147fa44 7706f20f 7642d6f7 00000000 00000000 ntdll!DbgBreakPoint
01 0147fa74 75d1ed6c 00000000 0147fac0 770337eb ntdll!DbgUiRemoteBreakin+0x3c
02 0147fa80 770337eb 00000000 7642d643 00000000 kernel32!BaseThreadInitThunk+0xe
03 0147fac0 770337be 7706f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
04 0147fad8 00000000 7706f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:001> r $t0 =0 ;.foreach (token { kb } ) { r $t0 = @$t0+1 ; .printf "\"token\" %2d ${token}\n" , @$t0 }
"token" 1 #
"token" 2 ChildEBP
"token" 3 RetAddr
"token" 4 Args
"token" 5 to
"token" 6 Child
"token" 7 00
"token" 8 0147fa44
"token" 9 7706f20f
"token" 10 7642d6f7
"token" 11 00000000
"token" 12 00000000
"token" 13 ntdll!DbgBreakPoint
"token" 14 01
"token" 15 0147fa74
"token" 16 75d1ed6c
"token" 17 00000000
"token" 18 0147fac0
"token" 19 770337eb
"token" 20 ntdll!DbgUiRemoteBreakin+0x3c
"token" 21 02
"token" 22 0147fa80
"token" 23 770337eb
"token" 24 00000000
"token" 25 7642d643
"token" 26 00000000
"token" 27 kernel32!BaseThreadInitThunk+0xe
"token" 28 03
"token" 29 0147fac0
"token" 30 770337be
"token" 31 7706f1d3
"token" 32 00000000
"token" 33 00000000
"token" 34 ntdll!__RtlUserThreadStart+0x70
"token" 35 04
"token" 36 0147fad8
"token" 37 00000000
"token" 38 7706f1d3
"token" 39 00000000
"token" 40 00000000
"token" 41 ntdll!_RtlUserThreadStart+0x1b
Run Code Online (Sandbox Code Playgroud)
我不明白你的进一步疑问,所以我假设你的意图如下
0:001> $$ putting the result of kb into a variable use javascript
0:001> dx @$foo = Debugger.Utility.Control.ExecuteCommand("kb")
@$foo = Debugger.Utility.Control.ExecuteCommand("kb")
[0x0] : # ChildEBP RetAddr Args to Child
[0x1] : 00 0147fa44 7706f20f 7642d6f7 00000000 00000000 ntdll!DbgBreakPoint
[0x2] : 01 0147fa74 75d1ed6c 00000000 0147fac0 770337eb ntdll!DbgUiRemoteBreakin+0x3c
[0x3] : 02 0147fa80 770337eb 00000000 7642d643 00000000 kernel32!BaseThreadInitThunk+0xe
[0x4] : 03 0147fac0 770337be 7706f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
[0x5] : 04 0147fad8 00000000 7706f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:001> dx -r0 @$foo[1]
@$foo[1] : 00 0147fa44 7706f20f 7642d6f7 00000000 00000000 ntdll!DbgBreakPoint
0:001> dx -r0 @$foo[2]
@$foo[2] : 01 0147fa74 75d1ed6c 00000000 0147fac0 770337eb ntdll!DbgUiRemoteBreakin+0x3c
Run Code Online (Sandbox Code Playgroud)
再次,我不知道你想将什么转换为十六进制或十进制
,所以下面的假设
尝试从堆栈中十进制以及大写字符串
像这样的脚本
function log(a1,a2)
{
host.diagnostics.debugLog(a1 +" " +a2 + "\n");
}
function exec (cmdstr)
{
return host.namespace.Debugger.Utility.Control.ExecuteCommand(cmdstr);
}
function kbtok()
{
var temp = exec("kb")
for ( line of temp )
{
var token = line.split(" ")
for (tok of token)
{
//log(tok)
try {
var num = host.parseInt64(tok,16)
log(tok , num)
}
catch(err) {
log(tok.toUpperCase(), " ")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
像使用它一样
.load jsprovider
.scriptload ---path----
dx @$scriptcontents.kbtok()
第一段中堆栈的示例输出
0:001> dx @$scriptContents.kbtok()
#
CHILDEBP
RETADDR
ARGS
TO
CHILD
00 0
013bfef4 20709108
7706f20f 1996943887
763ed3a7 1983828903
00000000 0
00000000 0
NTDLL!DBGBREAKPOINT
01 1
013bff24 20709156
75d1ed6c 1976692076
00000000 0
013bff70 20709232
770337eb 1996699627
NTDLL!DBGUIREMOTEBREAKIN+0X3C
02 2
013bff30 20709168
770337eb 1996699627
00000000 0
763ed3f3 1983828979
00000000 0
KERNEL32!BASETHREADINITTHUNK+0XE
03 3
013bff70 20709232
770337be 1996699582
7706f1d3 1996943827
00000000 0
00000000 0
NTDLL!__RTLUSERTHREADSTART+0X70
04 4
013bff88 20709256
00000000 0
7706f1d3 1996943827
00000000 0
00000000 0
NTDLL!_RTLUSERTHREADSTART+0X1B
@$scriptContents.kbtok()
Run Code Online (Sandbox Code Playgroud)
您不编译脚本 脚本会被解释
对于 Windbg 脚本,请使用 $$>a< ---path to script----
对于 javascript,请使用.scriptload命令