在 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)
从具有模式开头的内存中,转储整个长度。这只是为了确认我们得到了正确的结果!
希望这可以帮助。如果您需要进一步说明,我也可以尝试提供。
我们可以使用pykd来实现这一点。查找PyKD Wiki或PyKD 下载链接的下载。使用 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)
| 归档时间: |
|
| 查看次数: |
7076 次 |
| 最近记录: |