Scripting Windbg脚本-自动解析堆栈的每个帧
喂 我最近查看了一些堆栈,我手动找到了一个特定的东西,我想得到它的地址,这样我就可以用Scripting Windbg脚本-自动解析堆栈的每个帧,scripting,windbg,Scripting,Windbg,喂 我最近查看了一些堆栈,我手动找到了一个特定的东西,我想得到它的地址,这样我就可以用?深入研究它 例如: 00 00000005`9c88a558 00007ffa`bc2713ed ntdll!NtWaitForMultipleObjects+0xa 01 00000005`9c88a560 00007ffa`be477d51 KERNELBASE!WaitForMultipleObjectsEx+0xed 02 00000005`9c88a840 00007ffa`be477773 ker
?
深入研究它
例如:
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
我感兴趣的是提取0x000000059c88dd50
、0x0000000080001a55
和0x00007ffaab08e8de
的3个地址,并将它们自动传递给一组??((foo3*)0x000000059c88dd50)->WhatIAmInterestedIn
等命令,以便我可以快速扫描输出以查找感兴趣的结果
有没有一种方法可以编写这个解析脚本,这样我就可以在当前线程的堆栈中搜寻bar3
的任何实例,获取该地址并在n
x?
命令中使用它,只需在命令窗口中回显它找到的任何内容,即使是内存访问错误,它也可以为我加快速度
我在想
!对于每一帧,我必须承认,我甚至不知道如何在Windbg内询问特定帧是否有bar3
和地址,除非用我自己的眼睛 任何最新版本的调试器都具有内置功能,可以使用JavaScript针对目标编写脚本。商店中的WinDbg Preview也具有有限的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 *]
如果您有源代码,则可以按照messmers脚本检查参数和局部变量
(没有源和私有pdb参数和局部变量将抛出未定义的错误)
如果您没有源代码,并且希望摸索字符串输出
你可以用这样的东西
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
我以前也做过类似的事情,就是把链子拴在上面。也许像这样的东西会有用:~*e!为每一帧!如果(@#local==“bar3”){??bar3}
谢谢!使用!如果($spat(“@#local”,“bar3”)==1{.echo“Yes”}。否则{.echo“No”}
我可以得到每帧一个好的“Yes”或“No”。。。我现在只想得到每个bar3
的地址。。。正在取得进展。我不需要,我需要。我不需要地址。我能??直接输入bar3->WhatIAmInterestedIn
,可以吗?因为我已经为这个框架设置了上下文。我从来不知道!!!通过执行!为每一帧!如果($spat(“@#local”,“hUser”)==1{bar3->WhatIAmInterestedIn}
我从得到大量噪音!对于每个帧
-有没有一种方法可以让我安静地完成?MS帮助说明:“如果包含CommandString,调试器将在为该帧执行命令之前显示该帧及其索引。”-但如果可能的话,我想停止它这样做。使这些扩展命令保持沉默听起来很棘手。你可能会有一些运气与一些创造性的呼吁。也许您可以设置.outmask 0
,然后只在打印变量之前以及脚本完成时设置.outmask/d
。我从未尝试过,所以这只是一个猜测。是否有任何文档说明如何使用诸如host.currentThread.Stack
之类的东西,以及还有哪些其他可用的API?我在WinDbg预览版中使用了新的脚本支持,最大的障碍是缺少文档——仅仅依靠示例是没有乐趣的。您应该能够访问并查看一些文档。host.*API在中介绍。您应该在WinDbg预览的脚本窗口中获得某种程度的智能感知。此外,可以在调试器中探索host.namespace.Debugger.*下的任何内容。您只需“dx调试器”并单击周围即可。在JavaScript中,任何内容都应该大体相同。您可以添加“-v”以查看所有方法,添加“-h”以查看任何可用的帮助文本(例如:dx-v-h调试器)。