Windbg脚本将命令的结果分配给变量

问题描述 投票:-1回答:1

我经常需要以相同的方式调查dumpfile,并且我想自动执行此操作。我正在使用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".

现在,如何在Windbg脚本中执行此操作?

  1. 启动kb命令并将结果放入变量中。 (怎么做?我已经尝试过使用asaS但似乎都没有工作)
  2. 如果我无法将整个kb结果放在一个变量中,请尝试使用.foreach,如下例所示: .foreach ( token { kb} ) { .printf "TEST\n" } =>即使这不起作用:kb有大约8行结果,而TEST这个词打印78次。
  3. 而不是打印单词“TEST”,打印变量token,看看它是什么样子。 =>怎么做?我已经尝试了.printf "%msu \n" , ${token},或@$token,......但没有任何工作。
  4. 即使我得到这个工作:如何进行字符串操作,十进制/十六进制数字转换,...​​...?
  5. 不要忘记:我如何编译这样的脚本?我目前正在尝试在Windbg中运行该脚本,它有时会出现编译错误,但这些都是非常难以理解的(我添加了一行,导致出现问题,但是并发错误(不是拼写错误)甚至没有提到新添加的线)。

您可能会说:只看一下this URL下提到的示例,但我找不到标准Windbg命令的一个示例,正在运行,并将其结果存储在变量中(这是我需要的第一件事)做)。

如果我让我的脚本工作,我可能会将这篇文章变成一个通用的“Windbg脚本常见问题解答”,用于提及(和新添加的)问题。

第一次回答后编辑 我意识到我错误地使用了kb命令:我需要使用的实际命令是~* k,给出以下结果:

enter image description here

(小注:我只是一个截图,而不是文本副本,以强调DML超链接)

正如您所看到的,有一些DML结果,我想在包含CServiceModule::Run的行上“单击”。当我手动执行此操作时,似乎存在对以下命令的转换:

dx Debugger.Sessions[0].Processes[26520].Threads[14812].Stack.Frames[2].SwitchTo()

这里26520是HexToDec转换为6798, 和14812是39DC的HexToDec转换。 (两者都可以从截图的Id: 6798.39dc中检索)

所以我“需要”字符串操作和HexToDec转换以模拟DML点击。但是,如果你知道一种更简单的方法将这个“点击”动作放入脚本中,我会非常感激!

debugging scripting windbg dump
1个回答
1
投票

for .foreach space是分隔符,此命令不适用于读取行

如果要打印令牌,请在别名解释器中使用它

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

我不明白你的进一步询问,所以我假设你的意图如下

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

再次,我不知道你想要转换为十六进制或十进制 所以假设如下 试图从堆栈中分解十六进制以及大写字符串

像这样的脚本

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(), " ")
            }

        }
    }
}

用它就像

.load jsprovider .scriptload ---路径---- 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()

你不编译脚本脚本被解释

对于windbg脚本使用$$> a <---脚本路径---- 对于javascript使用.scriptload命令

© www.soinside.com 2019 - 2024. All rights reserved.