Merge branch 'dev' of https://github.com/pwndbg/pwndbg into vmmap-opt

pull/3390/head
jxuanli 1 month ago
commit 1e62c62c42

@ -8,7 +8,7 @@ usage: klookup [-h] [-a] [symbol]
Lookup kernel symbols Lookup kernel symbols
**Alias:** kallsyms **Aliases:** kallsyms, ks
### Positional arguments ### Positional arguments
|Positional Argument|Help| |Positional Argument|Help|

@ -2,7 +2,7 @@
# hexdump # hexdump
```text ```text
usage: hexdump [-h] [address] [count] usage: hexdump [-h] [-C [{py,c}]] [address] [count]
``` ```
@ -19,6 +19,7 @@ Hexdumps data at the specified address or module name.
|Short|Long|Help| |Short|Long|Help|
| :--- | :--- | :--- | | :--- | :--- | :--- |
|-h|--help|show this help message and exit| |-h|--help|show this help message and exit|
|-C|--code|Output as Python or C code data definition (default: py)|
<!-- END OF AUTOGENERATED PART. Do not modify this line or the line below, they mark the end of the auto-generated part of the file. If you want to extend the documentation in a way which cannot easily be done by adding to the command help description, write below the following line. --> <!-- END OF AUTOGENERATED PART. Do not modify this line or the line below, they mark the end of the auto-generated part of the file. If you want to extend the documentation in a way which cannot easily be done by adding to the command help description, write below the following line. -->
<!-- ------------\>8---- ----\>8---- ----\>8------------ --> <!-- ------------\>8---- ----\>8---- ----\>8------------ -->

@ -82,10 +82,6 @@ def get_file(path: str, try_local_path: bool = False) -> str:
The local path to the file The local path to the file
""" """
has_target_prefix = path.startswith("target:") has_target_prefix = path.startswith("target:")
has_good_prefix = path.startswith(("/", "./", "../")) or has_target_prefix
if not has_good_prefix:
raise OSError("get_file called with incorrect path", errno.ENOENT)
if has_target_prefix: if has_target_prefix:
path = path[7:] # len('target:') == 7 path = path[7:] # len('target:') == 7

@ -53,6 +53,24 @@ def address_or_module_name(s) -> int:
raise argparse.ArgumentTypeError("Unknown hexdump argument type.") raise argparse.ArgumentTypeError("Unknown hexdump argument type.")
def format_c(data: bytes) -> str:
toks = [f"{b:#02x}" for b in data]
lines = []
for i in range(0, len(toks), 16):
elem = ", ".join(toks[i : i + 16])
lines.append(f" {elem},")
body = "\n".join(lines)
return f"static const unsigned char data[] = {{\n{body}\n}};\n"
def format_py(data: bytes) -> str:
lines = []
for i in range(0, len(data), 16):
seg = "".join(f"\\x{b:02x}" for b in data[i : i + 16])
lines.append(f' b"{seg}"')
return "data = (\n{}\n)\n".format("\n".join(lines))
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Hexdumps data at the specified address or module name." description="Hexdumps data at the specified address or module name."
) )
@ -66,11 +84,20 @@ parser.add_argument(
parser.add_argument( parser.add_argument(
"count", nargs="?", default=pwndbg.config.hexdump_bytes, help="Number of bytes to dump" "count", nargs="?", default=pwndbg.config.hexdump_bytes, help="Number of bytes to dump"
) )
parser.add_argument(
"-C",
"--code",
type=str,
nargs="?",
const="py",
choices=("py", "c"),
help="Output as Python or C code data definition (default: py)",
)
@pwndbg.commands.Command(parser, category=CommandCategory.MEMORY) @pwndbg.commands.Command(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning @pwndbg.commands.OnlyWhenRunning
def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None: def hexdump(address, count=pwndbg.config.hexdump_bytes, code: str | None = None) -> None:
if hexdump.repeat: if hexdump.repeat:
address = hexdump.last_address address = hexdump.last_address
else: else:
@ -129,6 +156,11 @@ def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None:
print(e) print(e)
return return
if code:
source = format_py(data) if code == "py" else format_c(data)
print(source)
hexdump.offset += len(data)
else:
result = pwndbg.hexdump.hexdump( result = pwndbg.hexdump.hexdump(
data, data,
address=address, address=address,
@ -137,11 +169,10 @@ def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None:
flip_group_endianness=flip_group_endianness, flip_group_endianness=flip_group_endianness,
offset=hexdump.offset, offset=hexdump.offset,
) )
for line in result: for line in result:
print(line) print(line)
hexdump.offset += count hexdump.offset += len(data)
hexdump.last_address = 0 hexdump.last_address = 0

@ -15,7 +15,7 @@ parser.add_argument(
) )
@pwndbg.commands.Command(parser, aliases=["kallsyms"], category=CommandCategory.KERNEL) @pwndbg.commands.Command(parser, aliases=["kallsyms", "ks"], category=CommandCategory.KERNEL)
@pwndbg.commands.OnlyWhenQemuKernel @pwndbg.commands.OnlyWhenQemuKernel
@pwndbg.commands.OnlyWhenPagingEnabled @pwndbg.commands.OnlyWhenPagingEnabled
def klookup(symbol: str, apply: bool) -> None: def klookup(symbol: str, apply: bool) -> None:

@ -1421,47 +1421,6 @@ class GDB(pwndbg.dbg_mod.Debugger):
for line in pre_commands.strip().splitlines(): for line in pre_commands.strip().splitlines():
gdb.execute(line) gdb.execute(line)
# See https://github.com/pwndbg/pwndbg/issues/2890#issuecomment-2813047212
# Note: Remove this in a late 2025 or 2026 release?
for deprecated_cmd in (
"vmmap_add",
"vmmap_clear",
"vmmap_load",
"vmmap_explore",
"vis_heap_chunks",
"heap_config",
"stack_explore",
"auxv_explore",
"log_level",
"find_fake_fast",
"malloc_chunk",
"top_chunk",
"try_free",
"save_ida",
"knft_dump",
"knft_list_chains",
"knft_list_exprs",
"knft_list_flowtables",
"knft_list_objects",
"knft_list_rules",
"knft_list_sets",
"knft_list_tables",
"patch_list",
"patch_revert",
"jemalloc_extent_info",
"jemalloc_find_extent",
"jemalloc_heap",
):
fixed_cmd = deprecated_cmd.replace("_", "-")
gdb.execute(
f"alias -a {deprecated_cmd} = echo Use `{fixed_cmd}` instead (Pwndbg changed `_` to `-` in command names)\\n"
)
for deprecated_cmd, new_cmd in (("pcplist", "buddydump"),):
gdb.execute(
f"alias -a {deprecated_cmd} = echo deprecation warning for old name, use `{new_cmd}` instead\\n"
)
# This may throw an exception, see pwndbg/pwndbg#27 # This may throw an exception, see pwndbg/pwndbg#27
try: try:
gdb.execute("set disassembly-flavor intel") gdb.execute("set disassembly-flavor intel")

@ -0,0 +1,19 @@
from __future__ import annotations
import os
import tempfile
from pwndbg.aglib.file import get
def test_get():
# Test different relative and absolute file path prefixes
cwd = os.getcwd()
test_file_prefixes = ["/", "./", f"../{os.path.basename(cwd)}/", ""]
with tempfile.TemporaryDirectory(dir=cwd) as tempdir:
path = os.path.join(tempdir, "test_file")
with open(path, "w") as f:
f.write("test")
for test_prefix in test_file_prefixes:
test_path = path if test_prefix == "/" else test_prefix + os.path.relpath(path)
assert get(test_path) == b"test"

@ -158,3 +158,39 @@ def test_hexdump_limit_check(start_binary):
# Reset to default for subsequent tests if any # Reset to default for subsequent tests if any
gdb.execute(f"set hexdump-limit-mb {default_limit_mb}") gdb.execute(f"set hexdump-limit-mb {default_limit_mb}")
def test_hexdump_code_py_format(start_binary):
start_binary(BINARY)
sp = pwndbg.aglib.regs.rsp
pwndbg.aglib.memory.write(sp, b"abcdefgh\x01\x02\x03\x04\x05\x06\x07\x08" * 16)
SIZE = 21
out = gdb.execute(f"hexdump -C py $rsp {SIZE}", to_string=True)
expected = (
"data = (\n"
' b"\\x61\\x62\\x63\\x64\\x65\\x66\\x67\\x68\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08"\n'
' b"\\x61\\x62\\x63\\x64\\x65"\n'
")\n"
)
assert out.rstrip("\n") == expected.rstrip("\n")
def test_hexdump_code_c_format(start_binary):
start_binary(BINARY)
sp = pwndbg.aglib.regs.rsp
pwndbg.aglib.memory.write(sp, b"abcdefgh\x01\x02\x03\x04\x05\x06\x07\x08" * 16)
SIZE = 21
out = gdb.execute(f"hexdump -C c $rsp {SIZE}", to_string=True)
expected = (
"static const unsigned char data[] = {\n"
" 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,\n"
" 0x61, 0x62, 0x63, 0x64, 0x65,\n"
"};\n"
)
assert out.rstrip("\n") == expected.rstrip("\n")

Loading…
Cancel
Save