在this question,我试图让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”的问题:换句话说:目前DY尚未得到PYKD DbgCommand()
的支持。
kb的结果
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链接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链接完全相同
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链接然后键入命令,因为你可以看到它打印相同的信息,如你单击
现在,如果你说我需要看到“RUN”字符串不使用数字2你应该写一个脚本来解析每一行文本,因为我在我之前的答案中向你展示了你链接的主题
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>