Windbg脚本-自动解析堆栈的每一帧

时间:2018-09-17 10:19:49

标签: scripting windbg

你好,

我最近正在看几堆书,并且正在手动找到我想要获取地址的某个东西,以便可以用??深入其中。

例如:

00 00000005`9c88a558 00007ffa`bc2713ed ntdll!NtWaitForMultipleObjects+0xa
01 00000005`9c88a560 00007ffa`be477d51 KERNELBASE!WaitForMultipleObjectsEx+0xed
02 00000005`9c88a840 00007ffa`be477773 kernel32!WerpLaunchAeDebug+0x23a1
03 00000005`9c88adb0 00007ffa`bc351c1f kernel32!WerpLaunchAeDebug+0x1dc3
04 00000005`9c88ade0 00007ffa`bedaf1b3 KERNELBASE!UnhandledExceptionFilter+0x23f
05 00000005`9c88aed0 00007ffa`bed91e26 ntdll!memset+0xaaf3
06 00000005`9c88af10 00007ffa`beda349d ntdll!_C_specific_handler+0x96
07 00000005`9c88af80 00007ffa`bed648d7 ntdll!_chkstk+0x9d
08 00000005`9c88afb0 00007ffa`beda262a ntdll!RtlRaiseException+0xf67
09 00000005`9c88b680 00007ffa`aafc1b52 ntdll!KiUserExceptionDispatcher+0x3a
0a 00000005`9c88bd80 00007ffa`ab14e820 function1(class foo1 * bar1 = 0x00000000`0eee4e10)+0xd2 [c:\path\source1.cpp @ 783]
0b 00000005`9c88bdc0 00007ffa`ab11b854 function2(class foo2 * bar2 = 0x00000000`0f034010)+0x540 [c:\path\source2.cpp @ 23044]
0c 00000005`9c88d420 00007ffa`ab06151c function3(class foo3 * bar3 = 0x00000005`9c88dd50)+0x584 [c:\path\source3.cpp @ 5671]
0d 00000005`9c88dcf0 00007ffa`aae1ef08 function4(class foo3 * bar3 = 0x00000000`80001a55)+0x3bc [c:\path\source4.cpp @ 218]
0e 00000005`9c88e7c0 00007ffa`aae2956b function5(unsigned short fcode = 0x3032, class foo3 * bar3 = 0x00007ffa`ab08e8de)+0x1fb8 [path\source5.cpp @ 108]
0f 00000005`9c88fab0 00007ffa`bed254f4 kernel32!BaseThreadInitThunk+0x22
10 00000005`9c88fae0 00000000`00000000 ntdll!RtlUserThreadStart+0x34

我有兴趣提取0x000000059c88dd500x0000000080001a550x00007ffaab08e8de的3个地址并将它们自动传递到一堆?? ((foo3*) 0x000000059c88dd50)->WhatIAmInterestedIn等命令,以便我可以快速扫描输出以获取感兴趣的结果。

有没有办法编写此解析的脚本,所以我可以为bar3的任何实例拖曳当前线程的堆栈,获取该地址并在n x ??命令中使用它,只要将找到的内容回显到“命令窗口”,即使是内存访问错误,它也可以为我加快速度。

我当时正在考虑!for_each_frame,但我必须承认,我什至不知道如何在Windbg内部询问是否存在bar3和地址的特定框架除了,是用我自己的眼睛做的!

2 个答案:

答案 0 :(得分:1)

任何最新版本的调试器均具有内置功能,可使用JavaScript针对目标脚本。商店中的WinDbg Preview也具有与此相关的UI,而UI具有受限的Intellisense。您可以轻松地执行此操作。请看以下示例:

"use strict";

function* returnAllParameters(localName)
{
    var stack = host.currentThread.Stack;
    for (var frame of stack.Frames)
    {
        // Catch any exceptions that might occur due to inability to find PDB
        try
        {
            var locals = frame.Parameters;
            var local = locals[localName];
            if (local !== undefined)
            {
                yield local;
            }
        }
        catch(ex)
        {
        }
    }
}

此结果的示例:

0:000> dx @$scriptContents.returnAllParameters("pExceptionRecord")
@$scriptContents.returnAllParameters("pExceptionRecord")                 : [object Generator]
    [0x0]            : 0x8be2f0ed00 [Type: _EXCEPTION_RECORD *]

答案 1 :(得分:0)

如果您有来源,则可以遵循Messenger脚本并检查Parameters和Locals
(没有源代码和私有pdb Parameters和Locals会吐出未定义的错误)

如果您没有源,并且想摸索字符串输出 您可以使用类似这样的东西

function test(argstr)
{
    var backtrace = host.namespace.Debugger.Utility.Control.ExecuteCommand("kb")
    var collection = []
    var i = 0
    for (var frame of backtrace ) 
    {
        if( frame.toString().includes(argstr) ) {
        host.diagnostics.debugLog("found " + argstr + " at " + frame + "\n" )
        collection[i++] = frame.toString().split(" ")
        }
    }
    return collection
}

这是一个堆栈和文本解析的输出

0:003> dx @$scriptContents.test("Rtl")

found Rtl at 03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
found Rtl at 04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
@$scriptContents.test("Rtl")                 : 

    length           : 0x2
    [0x0]            : 03,
    [0x1]            : 04,
clicking the dml 0x0 
you get the first collection and so on as below

0:003> dx -r1 @$scriptContents.test("Rtl")[0]
found Rtl at 03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
found Rtl at 04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
@$scriptContents.test("Rtl")[0]                 : 03,02cdfe8c,76df37be,76e2f1d3,00000000,00000000,ntdll!__RtlUserThreadStart+0x70
    length           : 0x7
    [0x0]            : 03
    [0x1]            : 02cdfe8c
    [0x2]            : 76df37be
    [0x3]            : 76e2f1d3
    [0x4]            : 00000000
    [0x5]            : 00000000
    [0x6]            : ntdll!__RtlUserThreadStart+0x70
0:003> dx -r1 @$scriptContents.test("Rtl")[1]
found Rtl at 03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
found Rtl at 04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
@$scriptContents.test("Rtl")[1]                 : 04,02cdfea4,00000000,76e2f1d3,00000000,00000000,ntdll!_RtlUserThreadStart+0x1b
    length           : 0x7
    [0x0]            : 04
    [0x1]            : 02cdfea4
    [0x2]            : 00000000
    [0x3]            : 76e2f1d3
    [0x4]            : 00000000
    [0x5]            : 00000000
    [0x6]            : ntdll!_RtlUserThreadStart+0x1b
0:003> kb
 # ChildEBP RetAddr  Args to Child              
00 02cdfe10 76e2f20f 747e8f74 00000000 00000000 ntdll!DbgBreakPoint
01 02cdfe40 752ced6c 00000000 02cdfe8c 76df37eb ntdll!DbgUiRemoteBreakin+0x3c
02 02cdfe4c 76df37eb 00000000 747e8fb8 00000000 kernel32!BaseThreadInitThunk+0xe
03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b