在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中做到这一点。
答案 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实现这一目标。查找从PyKD Wiki或PyKD 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