搜索包含未知值的内存

Tho*_*ler 8 windbg

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

s 0012ff40 L?2000 48 65 6c 6c 6f
Run Code Online (Sandbox Code Playgroud)

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

s 0012ff40 L?2000 48 65 ?? ?? ?? 6c 6f
Run Code Online (Sandbox Code Playgroud)

??具有任意值的字节在哪里?

主意

做 ((memory XOR 48 65 00 00 00 6c 6f) AND FF FF 00 00 00 FF FF) 并将其与 比较00 00 00 00 00 00 00怎么样?但我也不知道如何在 WinDbg 中做到这一点。

小智 6

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

这是我用来搜索内存模式的示例,例如 ff ?? 00

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

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

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

{s -[1]b 00007ffabc520000 L100 ff }
Run Code Online (Sandbox Code Playgroud)

将 -[1] 标志与 s 一起使用,以便仅给出内存地址作为输出。

s ${hit}+2 L1 00
Run Code Online (Sandbox Code Playgroud)

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

db hit L3
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助。如果您需要进一步说明,我也可以尝试提供。


Tho*_*ler 1

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

%LOCALAPPDATA%\DBG\EngineExtensions
Run Code Online (Sandbox Code Playgroud)

对于 64 位或

%LOCALAPPDATA%\DBG\EngineExtensions32
Run Code Online (Sandbox Code Playgroud)

对于 32 位。

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

pip install pykd
Run Code Online (Sandbox Code Playgroud)

利用 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()))
Run Code Online (Sandbox Code Playgroud)

该脚本为 Bytes 对象构造一个正则表达式。它用于.通配符并将文字转义.\.

让我们在 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.
Run Code Online (Sandbox Code Playgroud)

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

0:006> .load pykd
Run Code Online (Sandbox Code Playgroud)

并运行脚本:

0:000> !py d:\debug\scripts\memwild.py 00900000 L10 2e ?? 77
Found: 0x2e 0x00 0x77 at address 0x00900008
Run Code Online (Sandbox Code Playgroud)