使用 WINDBg 脚本解析 Windows 转储文件

Parsing through Windows Dump File with WINDBg scripting

我正在 windbg 转储文件 (s 0 L?80000000 4D 00 69 00 63 00 72) 中搜索十六进制模式,我想将找到该模式的内存地址分配给一个变量,例如if windbg returns: 00b871b4 4d 00 69 00 63 我想将 00b871b4 存储到一个变量中,然后对该地址执行一些进一步的计算。如何通过 windbg 脚本将返回的地址分配给变量?

你确定你只会得到一个结果吗?
s returns 多个 returns 如果找到

您想指定哪个结果?

您使用的是最新版本的 windbg 吗?

如果是那么你可以将执行命令的结果分配给一个变量 并在本地或使用 javascript

进行迭代

多个结果的示例

0:000> s 0 l?0x30000000 4d 5a
000aa37c  4d 5a 01 00 52 5a 01 00-58 5a 01 00 5e 5a 01 00  MZ..RZ..XZ..^Z..
000e0000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
000f0000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
00100000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
00150000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
00160000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
00170000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
00180000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
001967fe  4d 5a 00 00 66 39 05 00-00 18 00 75 55 8b 0d 3c  MZ..f9.....uU..<
00196c02  4d 5a 00 00 66 39 10 75-32 8b 50 3c 85 d2 78 2b  MZ..f9.u2.P<..x+
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
0ff50000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
0ffd0000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
0:000>

这里是你如何使用 natvis 表达式计算器 dx

0:000> dx  @$foo = Debugger.Utility.Control.ExecuteCommand ("s 0 l?0x30000000 4d 5a")
@$foo = Debugger.Utility.Control.ExecuteCommand ("s 0 l?0x30000000 4d 5a")
    [0x0]            : 000aa37c  4d 5a 01 00 52 5a 01 00-58 5a 01 00 5e 5a 01 00  MZ..RZ..XZ..^Z..
    [0x1]            : 000e0000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
    [0x2]            : 00240000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
    [0x3]            : 00288979  4d 5a 00 00 66 39 08 74-04 33 c0 5d c3 8b 48 3c  MZ..f9.t.3.]..H<
    [0x4]            : 002bf505  4d 5a 00 00 66 39 01 75-f3 8b 41 3c 03 c1 81 38  MZ..f9.u..A<...8
    [0x5]            : 002d6bfb  4d 5a e8 0f fc ff ff 83-c4 14 84 c0 0f 84 9e fd  MZ..............

并对变量使用 linq 查询

0:000> dx @$foo.First()
@$foo.First()    : 000aa37c  4d 5a 01 00 52 5a 01 00-58 5a 01 00 5e 5a 01 00  MZ..RZ..XZ..^Z..
    Length           : 0x4b
0:000> dx @$foo.Last()
@$foo.Last()     : 104153e0  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
    Length           : 0x4b
0:000> dx @$foo.First(a=>a.Contains("2400") ==true)
@$foo.First(a=>a.Contains("2400") ==true) : 00240000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
    Length           : 0x4b
0:000>

对于旧的 windbg,您可以使用一些复杂的技巧进行分配 见下文,伪寄存器分配了最后一个地址 传递类型为 bor w 或 d 的 -[1] 标志将导致仅打印匹配的地址,并且 .foreach 可用于每个结果 在这里,我将其保存为 C++ 伪注册器

0:000> .foreach ( val { s -[1]b 0 l?0x30000000 4d 5a} ) { r? $t0 = ((int *) val ) }
0:000> ? @$t0
Evaluate expression: 17067465 = 01046dc9
0:000> s -[1]b 0 l?0x30000000 4d 5a
0x000aa37c
0x01030000
0x010467fe
0x01046c02
0x01046dc9
0:000>

将字符串转换为数字并进行算术运算

0:000> dx @$foo= Debugger.Utility.Control.ExecuteCommand("s -[1]b 0 l?0x30000000 4d 5a")

@$foo= Debugger.Utility.Control.ExecuteCommand("s -[1]b 0 l?0x30000000 4d 5a")
    [0x0]            : 0x0024a37c
    [0x1]            : 0x00ef0000
    [0x2]            : 0x00f067fe
    [0x3]            : 0x00f06c02
    [0x4]            : 0x00f06dc9

0:000> $$ load a dummy scriptfile for taking advantage of host.namespace

0:000> .scriptload e:\wdjs\blank.js
JavaScript script successfully loaded from 'e:\wdjs\blank.js'


0:000> dx @$blah = @$scriptContents.host.parseInt64(@$foo[0],16)
@$blah = @$scriptContents.host.parseInt64(@$foo[0],16) : 0x24a37c

0:000> dx @$bar = @$blah + 15  << decimal here not hex
@$bar = @$blah + 15 : 0x24a38b

0:000> dx @$bar = @$blah + 0xf4  << hex needs forced qualification of 0x
@$bar = @$blah + 0xf4 : 0x24a470
0:000>

一个javascript

function srchadd() 
{
    var exec = host.namespace.Debugger.Utility.Control.ExecuteCommand
    var hits = exec("s -[1]b 0 L?0x30000000 4d 5a")
    for ( i of hits )
    {
        j = host.parseInt64(i,16)
        k = j.add(15).toString()
        l = j.add(0xf4).toString()
        host.diagnostics.debugLog( j.toString() +" "+ k +" "+ l + "\n")
    }        
}

执行结果javascript(每个地址都被操作过)

0:000> .scriptload e:\wdjs\srchadd.js
JavaScript script successfully loaded from 'e:\wdjs\srchadd.js'
0:000> dx @$scriptContents.srchadd()
0xaa37c 0xaa38b 0xaa470
0xef0000 0xef000f 0xef00f4
0xf067fe 0xf0680d 0xf068f2
0xf06c02 0xf06c11 0xf06cf6
0xf06dc9 0xf06dd8 0xf06ebd
@$scriptContents.srchadd()
0:000>