In WinDbg I can search the memory for bytes using the s
command, e.g.
s 0012ff40 L?2000 48 65 6c 6c 6f
Is there also a way to include unknown bytes in the search sequence, e.g.
s 0012ff40 L?2000 48 65 ?? ?? ?? 6c 6f
where ??
is a byte with an arbitrary value?
Idea
How about doing ((memory XOR 48 65 00 00 00 6c 6f
) AND FF FF 00 00 00 FF FF
) and compare that against 00 00 00 00 00 00 00
? But I don't know how to do that in WinDbg either.
Am not sure if the search command supports wild card. But you can use .foreach command
, to achieve what you want.
Here is a sample that i used to search a memory pattern such as ff ?? 00
.foreach (hit {s -[1]b 00007ffabc520000 L100 ff }) {db hit L3; s ${hit}+2 L1 00}
Here is a brief description of how it works :
NOTE - Open up the debugger help from windbg to get complete documentation. That is within Windbg, Help | Contents
{s -[1]b 00007ffabc520000 L100 ff }
Use -[1] flag with s, so that only the memory address is given as the output.
s ${hit}+2 L1 00
For each hit, pass that memory address to the next search command. Increase the memory by the number of bytes that you want to skip and mention the last part of search pattern.
db hit L3
From the memory that has the beginning of the patter, dump the entire length. This is just to confirm that we are getting the right results!
Hope this helps. In case you need further clarification, i can try to provide that as well.
We can use pykd to achieve this. Find the downloads linked from PyKD Wiki or PyKD Downloads. When using WinDbg Preview, copy the DLLs into
%LOCALAPPDATA%\DBG\EngineExtensions
for 64 bit or
%LOCALAPPDATA%\DBG\EngineExtensions32
for 32 Bit.
Since this is only the WinDbg extension, you also need the Python module as well:
pip install pykd
Use the power of Python to do what WinDbg can't do. Save the following script in a good place for WinDbg, i.e. in a short path without spaces.
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()))
The script constructs a Regex for a Bytes object. It uses .
for the wildcard and escapes literal .
to \.
.
Let's prepare a proper sample in 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.
Load the PyKD extension, so we'll be able to run the script:
0:006> .load pykd
and run the script:
0:000> !py d:\debug\scripts\memwild.py 00900000 L10 2e ?? 77
Found: 0x2e 0x00 0x77 at address 0x00900008
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With