mirror of https://github.com/pwndbg/pwndbg.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.6 KiB
Python
96 lines
2.6 KiB
Python
import argparse
|
|
import string
|
|
|
|
import gdb
|
|
from pwnlib.util.cyclic import cyclic
|
|
from pwnlib.util.cyclic import cyclic_find
|
|
|
|
import pwndbg.commands
|
|
import pwndbg.gdblib.arch
|
|
from pwndbg.color import message
|
|
|
|
parser = argparse.ArgumentParser(description="Cyclic pattern creator/finder.")
|
|
|
|
parser.add_argument(
|
|
"-a",
|
|
"--alphabet",
|
|
metavar="charset",
|
|
default=string.ascii_lowercase,
|
|
type=str.encode,
|
|
help="The alphabet to use in the cyclic pattern",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-n",
|
|
"--length",
|
|
metavar="length",
|
|
type=int,
|
|
help="Size of the unique subsequences (defaults to the pointer size for the current arch)",
|
|
)
|
|
|
|
group = parser.add_mutually_exclusive_group(required=False)
|
|
group.add_argument(
|
|
"-l",
|
|
"-o",
|
|
"--offset",
|
|
"--lookup",
|
|
dest="lookup",
|
|
metavar="lookup_value",
|
|
type=str,
|
|
help="Do a lookup instead of printing the sequence (accepts constant values as well as expressions)",
|
|
)
|
|
|
|
group.add_argument(
|
|
"count",
|
|
type=int,
|
|
nargs="?",
|
|
default=100,
|
|
help="Number of characters to print from the sequence (default: print the entire sequence)",
|
|
)
|
|
|
|
|
|
@pwndbg.commands.ArgparsedCommand(parser, command_name="cyclic")
|
|
def cyclic_cmd(alphabet, length, lookup, count=100) -> None:
|
|
if length:
|
|
# Convert from gdb.Value
|
|
length = int(length)
|
|
else:
|
|
length = pwndbg.gdblib.arch.ptrsize
|
|
|
|
if lookup:
|
|
lookup = pwndbg.commands.fix(lookup, sloppy=True)
|
|
|
|
if isinstance(lookup, (gdb.Value, int)):
|
|
lookup = int(lookup).to_bytes(length, pwndbg.gdblib.arch.endian)
|
|
elif isinstance(lookup, str):
|
|
lookup = bytes(lookup, "utf-8")
|
|
|
|
if len(lookup) != length:
|
|
print(
|
|
message.error(
|
|
f"Lookup pattern must be {length} bytes (use `-n <length>` to lookup pattern of different length)"
|
|
)
|
|
)
|
|
return
|
|
|
|
hexstr = "0x" + lookup.hex()
|
|
print(
|
|
message.notice(
|
|
f"Finding cyclic pattern of {length} bytes: {str(lookup)} (hex: {hexstr})"
|
|
)
|
|
)
|
|
|
|
if any(c not in alphabet for c in lookup):
|
|
print(message.error("Pattern contains characters not present in the alphabet"))
|
|
return
|
|
|
|
offset = cyclic_find(lookup, alphabet, length)
|
|
|
|
if offset == -1:
|
|
print(message.error("Given lookup pattern does not exist in the sequence"))
|
|
else:
|
|
print(message.success(f"Found at offset {offset}"))
|
|
else:
|
|
sequence = cyclic(int(count), alphabet, length)
|
|
print(sequence.decode())
|