搜索内存包括未知值

时间:2014-01-06 13:59:11

标签: windbg

在WinDbg中,我可以使用s命令在内存中搜索字节,例如

s 0012ff40 L?2000 48 65 6c 6c 6f

是否还有一种方法可以在搜索序列中包含未知字节,例如

s 0012ff40 L?2000 48 65 ?? ?? ?? 6c 6f

其中??是一个具有任意值的字节?

如何做((记忆XOR 48 65 00 00 00 6c 6f)和FF FF 00 00 00 FF FF)并将其与00 00 00 00 00 00 00进行比较?但我不知道如何在WinDbg中做到这一点。

3 个答案:

答案 0 :(得分:4)

我不确定搜索命令是否支持通配符。但是你可以使用.foreach command来实现你想要的目标。

以下是我用于搜索内存模式的示例,例如ff ?? 00

.foreach(hit {s - [1] b 00007ffabc520000 L100 ff}){db hit L3; s $ {hit} +2 L1 00}

以下是其工作原理的简要说明:

注意 - 从windbg打开调试器帮助以获取完整的文档。那是在Windbg,帮助|内容

{s -[1]b 00007ffabc520000 L100 ff }

使用 - [1]标志和s,以便只给出内存地址作为输出。

s ${hit}+2 L1 00

对于每次点击,将该内存地址传递给下一个搜索命令。通过要跳过的字节数增加内存,并提及搜索模式的最后部分。

db hit L3

从具有模式开头的内存中,转储整个长度。这只是为了确认我们得到了正确的结果!

希望这会有所帮助。如果您需要进一步澄清,我也可以尝试提供。

答案 1 :(得分:1)

我们可以使用实现这一目标。查找从PyKD WikiPyKD Downloads链接的下载。使用WinDbg Preview时,将DLL复制到

%LOCALAPPDATA%\DBG\EngineExtensions

用于64位或

%LOCALAPPDATA%\DBG\EngineExtensions32

32位。

由于这只是WinDbg扩展,因此您还需要Python模块:

pip install pykd

使用Python的功能来完成WinDbg无法完成的工作。将以下脚本保存在WinDbg的适当位置,即在没有空格的短路径中。

from pykd import *
import sys
import re
import struct

if len(sys.argv)<4:
    print("Wildcard search for memory")
    print("Usage:", sys.argv[0], "<address> <length> <pattern> [-v]", sep=" ")
    print("      <address>: Memory address where searching begins.")
    print("                 This can be a WinDbg expression like ntdll!NtCreateThreadEx.")
    print("      <length> : Number of bytes that will be considered as the haystack.")
    print("      <pattern>: Bytes that you're looking for. May contain ?? for unknown bytes.")
    print("      [-v]     : (optional) Verbose output")
    print()
    print("Examples:")
    print("     ", sys.argv[0], "00770000 L50 01 02 03 ?? 05")
    print("         will find 01 02 03 04 05 or 01 02 03 FF 05, if present in memory")
    sys.exit(0)

verbose = False
if sys.argv[-1][0:2] == "-v":
    verbose = True

if verbose:
    for n in range(1, len(sys.argv)):
        print(f"param {n}: " + sys.argv[n])

address = expr(sys.argv[1])
if verbose: print("Start address:", "0x{:08x}".format(address), sep=" ")

length = sys.argv[2]
length = length.replace("L?","") # consider large address range syntax
length = length.replace("L","") # consider address range syntax
length = expr(length)
if verbose: print("Length:", "0n"+str(length), "bytes", sep=" ")

regex = b""
for n in range(3, len(sys.argv) - 1 if verbose else 0):
    if sys.argv[n] == "??":
        regex += bytes(".", "ascii")
    else:
        char = struct.pack("B", expr(sys.argv[n]))
        if char == b".":
            regex += struct.pack("B", ord("\\"))
        regex += char
if verbose: print("Regex:", regex, sep=" ")

memorycontent = loadBytes(address, length)
if verbose: print("Memory:", memorycontent, sep=" ")

result = re.search(regex, bytes(memorycontent))
print("Found:", ' '.join("0x{:02x}".format(x) for x in result.group(0)), "at address", "0x{:08x}".format(address+result.start()))

该脚本为Bytes对象构造一个Regex。它将.用作通配符,并将文字.转义为\.

让我们在WinDbg中准备适当的示例:

0:006> .dvalloc 1000
Allocated 1000 bytes starting at 00900000
0:000> eu 0x00900000 "Test.with.regex"
0:000> db 0x00900000 L0n30
00900000  54 00 65 00 73 00 74 00-2e 00 77 00 69 00 74 00  T.e.s.t...w.i.t.
00900010  68 00 2e 00 72 00 65 00-67 00 65 00 78 00        h...r.e.g.e.x.

加载PyKD扩展名,这样我们就可以运行脚本:

0:006> .load pykd

并运行脚本:

0:000> !py d:\debug\scripts\memwild.py 00900000 L10 2e ?? 77
Found: 0x2e 0x00 0x77 at address 0x00900008

答案 2 :(得分:0)

如果搜索范围不是非常大,您可以将十六进制转储复制/粘贴到sublime文本中,然后在启用了正则表达式模式的情况下执行查找。例如,我正在寻找(1200

add esp, X
ret

在崇高的文字中,我使用正则表达式81 c4 .. .. .. 00 c3进行了搜索,并找到了一个包含

指示的地址
add esp,600h
ret