feat(commands/hexdump): Add configurable size limit (#2803)

* feat(commands/hexdump): Add configurable size limit check

* feat(commands/hexdump): Add configurable size limit check

* test(commands/hexdump): Add tests for hexdump size limit
pull/2810/head
Gaurav Verma 9 months ago committed by GitHub
parent bfdffbc1a3
commit a82e152f94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -10,6 +10,7 @@ import pwndbg.commands
import pwndbg.hexdump
from pwndbg.color import message
from pwndbg.commands import CommandCategory
from pwndbg.lib.config import PARAM_ZUINTEGER
pwndbg.config.add_param("hexdump-width", 16, "line width of hexdump command")
pwndbg.config.add_param("hexdump-bytes", 64, "number of bytes printed by hexdump command")
@ -25,6 +26,16 @@ pwndbg.config.add_param(
help_docstring="When `on`, use big-endian within each group of bytes. Only applies to raw bytes, not the ASCII part. "
"See also hexdump-highlight-group-lsb.",
)
pwndbg.config.add_param(
"hexdump-limit-mb",
10,
"the maximum size in megabytes (MB) `hexdump` will read",
help_docstring="""Set the maximum size in megabytes (MB) that the `hexdump` command will attempt to read at once.
Prevents GDB crashes due to excessive memory allocation requests.
Set to 0 for unlimited (use with caution).""",
param_class=PARAM_ZUINTEGER,
scope="memory",
)
def address_or_module_name(s) -> int:
@ -76,6 +87,20 @@ def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None:
address = new_address
count = max(int(count), 0)
# Get the configured limit in MB
limit_mb = int(pwndbg.config.hexdump_limit_mb)
# Check if the limit is enabled (non-zero) and if the request count exceeds it
if limit_mb > 0:
limit_bytes = limit_mb * 1024 * 1024
if count > limit_bytes:
# Raise an error with the informative message
raise ValueError(
f"Hexdump count ({count}) exceeds the current limit of {limit_mb} MB.\n"
f"Use 'set hexdump-limit-mb <new_limit_in_mb>' to increase the limit (or set to 0 for unlimited)."
)
width = int(pwndbg.config.hexdump_width)
group_width = int(pwndbg.config.hexdump_group_width)

@ -1,6 +1,7 @@
from __future__ import annotations
import gdb
import pytest
from pwnlib.util.cyclic import cyclic
import pwndbg
@ -103,3 +104,56 @@ def test_hexdump_saved_address_and_offset(start_binary):
assert out1 == out2
assert pwndbg.commands.hexdump.hexdump.last_address == sp + SIZE
assert pwndbg.commands.hexdump.hexdump.offset == SIZE
def test_hexdump_limit_check(start_binary):
"""
Tests that the hexdump command respects the hexdump-limit-mb settings.
"""
start_binary(BINARY)
sp = pwndbg.aglib.regs.rsp
# Default limit is 10 MB
default_limit_mb = 10
limit_bytes = default_limit_mb * 1024 * 1024
count_over_limit = limit_bytes + 1
count_within_limit = limit_bytes // 2 # Using a value clearly within the limit
# 1. Test that count over the default limit raises PwndbgError
print(f"Testing count over default limit ({count_over_limit} bytes)")
with pytest.raises(gdb.error, match="exceeds the current limit"):
gdb.execute(f"hexdump {sp} {count_over_limit}", to_string=True)
print(" -> Correctly raised error.")
# 2. Test that count within the default limit works
print(f"Testing count within default limit ({count_within_limit} bytes)")
# We don't expect an error here. Just executing it is the test.
# We could assert on the output, but simply not crashing/erroring is the main goal.
try:
gdb.execute(f"hexdump {sp} {count_within_limit}", to_string=True)
except Exception as e:
pytest.fail(f"Hexdump failed unexpectedly with count within limit: {e}")
print(" -> Correctly executed.")
# 3. Test increasing the limit allows larger dumps
new_limit_mb = 15
count_over_default_under_new = (default_limit_mb + 1) * 1024 * 1024
print(f"Setting limit to {new_limit_mb} MB and testing count {count_over_default_under_new}")
gdb.execute(f"set hexdump-limit-mb {new_limit_mb}")
try:
gdb.execute(f"hexdump {sp} {count_over_default_under_new}", to_string=True)
except Exception as e:
pytest.fail(f"Hexdump failed unexpectedly after increasing limit: {e}")
print(" -> Correctly executed after increasing limit.")
# 4. Test disabling the limit (set to 0) allows larger dumps
print(f"Setting limit to 0 and testing count {count_over_default_under_new}")
gdb.execute("set hexdump-limit-mb 0")
try:
gdb.execute(f"hexdump {sp} {count_over_default_under_new}", to_string=True)
except Exception as e:
pytest.fail(f"Hexdump failed unexpectedly after disabling limit: {e}")
print(" -> Correctly executed after disabling limit.")
# Reset to default for subsequent tests if any
gdb.execute(f"set hexdump-limit-mb {default_limit_mb}")

Loading…
Cancel
Save