"DbgCommand()" 也可以得到超链接的结果吗?

Can "DbgCommand()" also get the hyperlinked results?

中,我试图让 Windbg 脚本正常工作,但也许我可以使用 PYKD 解决我的问题。我的问题如下:

我启动命令 ~* k,我得到以下响应(如在提到的问题中,我喜欢强调超链接,因此图像而不是简单的文本):

我想在包含 CServiceModule::Run 的行上模拟鼠标单击。当我将鼠标悬停在相应的超链接 02 上时,我看到以下 Windbg 命令:

dx Debugger.Sessions[0].Processes[4416].Threads[4436].Stack.Frames[2].SwitchTo();dv /t /v

到目前为止,我一直尝试自己重新创建此命令,但现在我意识到,如果我可以从响应本身获取该命令,我的问题就解决了。

据我所知,PYKD DbgCommand() 仅提供响应的文本部分(因此,不提供超链接下的信息)。

有什么方法可以从 DbgCommand() 命令获取这个超链接吗?

如果知道帧号,可以用pykd.setFrame命令切换帧。 但是你应该记住,pykd 不支持内联函数框架。因此,许多帧可能与 windbg 输出不同。您可以使用命令 'inline 0'

禁用内联函数

pykd 脚本可能如下所示:

frames = getStack()
for frameNumber in xrange( len(frames) ):
    if "ServiceModule::Run" in findSymbol(frames[frameNumber].ip):
          setFrame(frameNumber)
          dprintln("frame switched")

额外编辑以提高可读性
如以下评论所述,已向 PYKD 提出一个名为“dbgCommand doesnt support DML command output”的问题:换句话说:PYKD DbgCommand().

目前尚不支持 DML

知识库的结果

0:000> kb
 # ChildEBP RetAddr  Args to Child              
00 000bf618 76fa0e00 7ffdf000 7ffda000 76ff714c ntdll!LdrpDoDebuggerBreak+0x2c
01 000bf778 76f860a7 000bf7ec 76f20000 76c245cb ntdll!LdrpInitializeProcess+0x11a9
02 000bf7c8 76f83659 000bf7ec 76f20000 00000000 ntdll!_LdrpInitialize+0x78
03 000bf7d8 00000000 000bf7ec 76f20000 00000000 ntdll!LdrInitializeThunk+0x10

当我点击 dml link 02 我得到

0:000> dx Debugger.Sessions[0].Processes[2684].Threads[3736].Stack.Frames[2].SwitchTo();dv /t /v
Debugger.Sessions[0].Processes[2684].Threads[3736].Stack.Frames[2].SwitchTo()
Unable to enumerate locals, Win32 error 0n87
Private symbols (symbols.pri) are required for locals.
Type ".hh dbgerr005" for details.

正如我在之前的回答中所强调的,同样可以通过

实现

dx @$curstack.Frames[2].SwitchTo();dv /v /t

键入此内容等同于单击 02 link

0:000> dx @$curstack.Frames[2].SwitchTo();dv /v /t
@$curstack.Frames[2].SwitchTo()
Unable to enumerate locals, Win32 error 0n87
Private symbols (symbols.pri) are required for locals.
Type ".hh dbgerr005" for details.

只有当您使用可用的源进行调试时,这才有意义 这是堆栈和帧 2 的示例,源

我正在使用 kbL 在堆栈跟踪中隐藏我的 src 行信息 然后单击第 2 帧 DML link 然后键入命令,您可以看到它打印出与您单击

相同的信息

现在,如果你说我需要查看 "RUN" 字符串,请不要使用数字 2 你应该编写一个脚本来对每一行进行文本解析,正如我在之前对你 linked

的线程的回答中向你展示的那样
0:000> kbL
 # ChildEBP RetAddr  Args to Child              
00 (Inline) -------- -------- -------- -------- mfctest!CThreadLocal<_AFX_THREAD_STATE>::GetData
01 0025fe48 012fbc2f 015bf7a8 012fd4bd ffffffff mfctest!AfxGetThreadState
02 0025fe64 0151979e 00000000 015c6360 7ffdb000 mfctest!CWinThread::Run+0xf
03 0025fe7c 014c17d5 012e0000 00000000 00322d3e mfctest!AfxWinMain+0x93
04 (Inline) -------- -------- -------- -------- mfctest!invoke_main+0x1a
05 0025fec8 76e8ed6c 7ffdb000 0025ff14 76f837eb mfctest!__scrt_common_main_seh+0xf8
06 0025fed4 76f837eb 7ffdb000 76b22d01 00000000 kernel32!BaseThreadInitThunk+0xe
07 0025ff14 76f837be 014c1892 7ffdb000 00000000 ntdll!__RtlUserThreadStart+0x70
08 0025ff2c 00000000 014c1892 7ffdb000 00000000 ntdll!_RtlUserThreadStart+0x1b


clicking link with number 2
0:000> dx Debugger.Sessions[0].Processes[620].Threads[2228].Stack.Frames[2].SwitchTo();dv /t /v
Debugger.Sessions[0].Processes[620].Threads[2228].Stack.Frames[2].SwitchTo()
@ebx              class CWinThread * this = 0x015bf7a8 {h=0xfffffffe proc={...}}
<unavailable>     long lIdleCount = <value unavailable>
@eax              class _AFX_THREAD_STATE * pState = 0x0153b820
<unavailable>     int bIdle = <value unavailable>


using command (NOT CLICKING BUT TYPING THIS )
0:000> dx @$curstack.Frames[2].SwitchTo();dv /v /t
@$curstack.Frames[2].SwitchTo()
@ebx              class CWinThread * this = 0x015bf7a8 {h=0xfffffffe proc={...}}
<unavailable>     long lIdleCount = <value unavailable>
@eax              class _AFX_THREAD_STATE * pState = 0x0153b820
<unavailable>     int bIdle = <value unavailable>