Loops Windbg-can!对于_,每个_帧可以用.for、.do或.while来模拟?

Loops Windbg-can!对于_,每个_帧可以用.for、.do或.while来模拟?,loops,for-loop,while-loop,windbg,Loops,For Loop,While Loop,Windbg,!对于_,每个_帧将迭代线程的每个帧,并允许您在一行上运行命令(甚至是一组命令) 有没有一种方法可以在Windbg脚本中执行一个简单的循环,以便您可以从当前线程的帧00开始,迭代到最后一帧,并在一个漂亮的多行多步骤代码块中的每个帧中执行您想做的任何操作 这段代码显然会进行迭代,但在执行调试中断之前,它永远不会停止。即使Windbg开始报告找不到帧0xXX,前一个作用域保持不变,这也是事实,那么我如何才能检查我需要的条件呢 .frame 0n0 .do { .f+ } (1==1) 在.do

!对于_,每个_帧
将迭代线程的每个帧,并允许您在一行上运行命令(甚至是一组命令)

有没有一种方法可以在Windbg脚本中执行一个简单的循环,以便您可以从当前线程的帧
00
开始,迭代到最后一帧,并在一个漂亮的多行多步骤代码块中的每个帧中执行您想做的任何操作

这段代码显然会进行迭代,但在执行调试中断之前,它永远不会停止。即使Windbg开始报告
找不到帧0xXX,前一个作用域保持不变,这也是事实,那么我如何才能检查我需要的条件呢

.frame 0n0
.do
{
  .f+
}
(1==1)

.do
开始之前,我是否可以检索和存储一些东西,或者我可以在条件中检查一些内置的线程令牌,或者当
.f+
遍历到更高的帧时,会遇到一些错误条件,我可以跳出来执行类似的脚本任务,我鼓励您看看JavaScript的内置支持(特别是WinDbg预览版)。总的来说,它使类似这样的任务比在调试器中使用了很长时间的“命令/点脚本”要容易得多。下面的脚本显示了一个示例:

"use strict";

function invokeScript()
{
    for (var frame of host.currentThread.Stack.Frames)
    {
        // Do whatever you want:
        host.diagnostics.debugLog("I just found frame: ", frame, "\n");
    }
}
只需单击功能区上的“执行”按钮,即可在WinDbg预览中运行此脚本。。。或者将其放入文件并“.scriptrun FullScriptPath.js”

如果有什么东西它不支持,让你回到一个旧的脚本,我们当然希望听到反馈

0:000> dx @$curstack.Frames.Count()
@$curstack.Frames.Count() : 0x4
0:000> .cxr;r $t0 = 0;.do { .f+ ; r $t0 = @$t0+1 } (@$t0 < 4 )
Resetting default scope
01 0014fa14 770060a7 ntdll!LdrpInitializeProcess+0x11a9
02 0014fa64 77003659 ntdll!_LdrpInitialize+0x78
03 0014fa74 00000000 ntdll!LdrInitializeThunk+0x10
Cannot find frame 0x4, previous scope unchanged
03 0014fa74 00000000 ntdll!LdrInitializeThunk+0x10
但这就是问题所在

你可以用

**dx @$t0 = @$curstack.Frames.Count()** and use the Pseudo Register inside any loop variables 
分配了值的伪寄存器不会导致错误

尽管这似乎相当于创建一个用户变量
dx@$foo=@$curStack.Frames.Count()

看来我们不能将@$foo用作循环变量

下面是基于测试的简单poc

C:>cdb cdb
Microsoft(R)Windows调试器版本10.0.16299.15 X86

Resetting default scope
@$t0 =0          : 0 [Type: int]
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Cannot find frame 0x4, previous scope unchanged
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
0:000>
0:000>dx@$t1=@$curstack.Frames.Count()

Resetting default scope
@$t0 =0          : 0 [Type: int]
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Cannot find frame 0x4, previous scope unchanged
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
0:000>
0:000>.for(dx@$t0=0;@$t0<@$t1;r$t0=@$t0+1){.frame@$t0}

@$t0 =0          : 0 [Type: int]
00 0012fad0 77000e00 ntdll!LdrpDoDebuggerBreak+0x2c
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Resetting default scope
@$t0 =0          : 0 [Type: int]
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Cannot find frame 0x4, previous scope unchanged
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
0:000>
@$t0 =0          : 0 [Type: int]
hi
double 0
hi
double 3.1415000000000001812
hi
double 6.2830000000000003624
hi
double 9.4245000000000000995
hi
double 12.566000000000000725
hi
double 15.70750000000000135
hi
double 18.849000000000000199
hi
double 21.990500000000000824
hi
double 25.13200000000000145
hi
double 28.273500000000002075
hi
double 31.4150000000000027
0:001>
@$t0 =0          : 0 [Type: int]
hi
Evaluate expression: 0 = 00000000
hi
Evaluate expression: 3 = 00000003
hi
Evaluate expression: 6 = 00000006
hi
Evaluate expression: 9 = 00000009
hi
Evaluate expression: 12 = 0000000c
hi
Evaluate expression: 15 = 0000000f
hi
Evaluate expression: 18 = 00000012
hi
Evaluate expression: 21 = 00000015
hi
Evaluate expression: 24 = 00000018
hi
Evaluate expression: 27 = 0000001b
hi
Evaluate expression: 30 = 0000001e
0:000>.cxr;dx@$t0=0;。do{.f+;r$t0=@$t0+1}(@$t0<@$t1)

Resetting default scope
@$t0 =0          : 0 [Type: int]
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Cannot find frame 0x4, previous scope unchanged
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
0:000>
0:001>.for(dx@$t0=0;@$t0<@$t1;r$t0=@$t0+1){.echo“hi”?(@$t0*3.1415)}

@$t0 =0          : 0 [Type: int]
00 0012fad0 77000e00 ntdll!LdrpDoDebuggerBreak+0x2c
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Resetting default scope
@$t0 =0          : 0 [Type: int]
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Cannot find frame 0x4, previous scope unchanged
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
0:000>
@$t0 =0          : 0 [Type: int]
hi
double 0
hi
double 3.1415000000000001812
hi
double 6.2830000000000003624
hi
double 9.4245000000000000995
hi
double 12.566000000000000725
hi
double 15.70750000000000135
hi
double 18.849000000000000199
hi
double 21.990500000000000824
hi
double 25.13200000000000145
hi
double 28.273500000000002075
hi
double 31.4150000000000027
0:001>
@$t0 =0          : 0 [Type: int]
hi
Evaluate expression: 0 = 00000000
hi
Evaluate expression: 3 = 00000003
hi
Evaluate expression: 6 = 00000006
hi
Evaluate expression: 9 = 00000009
hi
Evaluate expression: 12 = 0000000c
hi
Evaluate expression: 15 = 0000000f
hi
Evaluate expression: 18 = 00000012
hi
Evaluate expression: 21 = 00000015
hi
Evaluate expression: 24 = 00000018
hi
Evaluate expression: 27 = 0000001b
hi
Evaluate expression: 30 = 0000001e

需要C++而不是MASM进行评估吗?它将出现语法错误

<> p>但常数C++似乎是用来评估

**0:001>.expr
当前表达式计算器:MASM-Microsoft汇编程序表达式

0:001>.for(dx@$t0=0;@$t0<@$t1;r$t0=@$t0+1){.echo“hi”?(@$t0*3.1415)}**

0:001>.for(dx@$t0=0;@$t0<$t1;r$t0=@$t0+1){.echo“hi”?(@$t0*@@c++(3.1415))}

@$t0 =0          : 0 [Type: int]
00 0012fad0 77000e00 ntdll!LdrpDoDebuggerBreak+0x2c
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Resetting default scope
@$t0 =0          : 0 [Type: int]
01 0012fc30 76fe60a7 ntdll!LdrpInitializeProcess+0x11a9
02 0012fc80 76fe3659 ntdll!_LdrpInitialize+0x78
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
Cannot find frame 0x4, previous scope unchanged
03 0012fc90 00000000 ntdll!LdrInitializeThunk+0x10
0:000>
@$t0 =0          : 0 [Type: int]
hi
double 0
hi
double 3.1415000000000001812
hi
double 6.2830000000000003624
hi
double 9.4245000000000000995
hi
double 12.566000000000000725
hi
double 15.70750000000000135
hi
double 18.849000000000000199
hi
double 21.990500000000000824
hi
double 25.13200000000000145
hi
double 28.273500000000002075
hi
double 31.4150000000000027
0:001>
@$t0 =0          : 0 [Type: int]
hi
Evaluate expression: 0 = 00000000
hi
Evaluate expression: 3 = 00000003
hi
Evaluate expression: 6 = 00000006
hi
Evaluate expression: 9 = 00000009
hi
Evaluate expression: 12 = 0000000c
hi
Evaluate expression: 15 = 0000000f
hi
Evaluate expression: 18 = 00000012
hi
Evaluate expression: 21 = 00000015
hi
Evaluate expression: 24 = 00000018
hi
Evaluate expression: 27 = 0000001b
hi
Evaluate expression: 30 = 0000001e

如果我可以访问类似内置伪寄存器
@$frame
,但对于最后一个/最高的帧,可能是吗?以下是
.cxr的示例;r$t0=0;。do{.f+;r$t0=@$t0+1}(@$t0<4)
是一件美好的事情,但是我不能从
@$curstack.Frames.Count()
中得到任何东西,除了
错误:使用未定义的变量
-我在网上也找不到任何东西;也许我这里的Windbg版本有点旧,但我可以尝试更新的版本。我想这是因为
dx Debugger.State.DebuggerVariables
没有显示有关
curstack
的任何内容。
$curstack
是否仅在Windbg预览中可用?由于操作系统的要求,我目前无法安装它。当我在Windbg的两个版本中尝试
dx Debugger.State.DebuggerVariables
时,我没有看到返回的
curstack
,我可以访问-10.0.10586.567和10.0.15063.0。是否有其他方法从
.dmp
获取此信息?我深入研究了
curprocess
内部的
dx@$curprocess.Threads[0x3508].Stack.Frames
,但我不能做
dx@$curprocess.Threads[0x3508].Stack.Frames.First()
dx@$curprocess.Threads[0x3508].Stack.Frames.Last()之类的事情
.windbg中的javascript支持已经提供了一年多了现在$curstack不是命令它是@$curstack否您不能将dx分配到伪寄存器(伪寄存器可以处理masm而不是dx表达式)使用dx表达式使用javascript,如var foo=host.blah,foo,然后,无论您如何操作,您都可以完全利用“dx”将值分配给旧的伪寄存器($t0、$t1等)。“dx”表达式的结果必须能够在旧的求值器中表达,如“?”(例如:没有LINQ…没有对合成对象的赋值,如“调试器”,等等)。只要做一些像“dx@$t0=@$curthread.Stack.Frames.Count()”@William Messmer我的意思是它不像r$t0=@$curthread.Frames.Stack.Count()那样是可赋值的,对于你所做的事情,你也可以使用一个用户变量,比如dx@$foo=@$curxx.yy.zz,不是吗?谢谢你。。。我知道它通常应该是“工作中最好的工具”,但是-为了我自己的学习经验(我正在尝试),我想继续关注Windbg脚本。我想尝试在这方面做得越来越好(现在)。