From d65d5814c5a399ecd0d4a6105729253778bd017f Mon Sep 17 00:00:00 2001 From: Charles Fol Date: Tue, 10 Sep 2024 12:34:03 +0200 Subject: [PATCH] Fix deference-limit changes not being reflected due to an early cast to int() (#2422) * Added types to hexdump()'s parameters * hexdump(): upgraded format strings to f-strings, while fixing the offset when data is empty * hexdump(): offset is now correctly computed and updated accross repeated calls to hexdump. This fixes two bugs: 1. Offset was increased by the number of lines displayed by the hexdump() command, which was incorrect, as some lines may be compressed; 2. When dumping a number of bytes that is not divisible by the number of bytes per line, offset would be incorrectly updated. * Linter * hexdump: fixed type of retrieved config entry hexdump_group_use_big_endian * Fixed test_hexdump_saved_address_and_offset test to account for random stack address * Upgraded the linked-lists.c test program to 6 items in order to test the "deference-limit" setting * Chain: changes to the deference-limit parameter were not reflected in the program due to an early cast to int() * Linter --- pwndbg/chain.py | 4 +- tests/gdb-tests/tests/binaries/linked-lists.c | 5 +- tests/gdb-tests/tests/test_command_plist.py | 77 ++++++++++++++++++- 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/pwndbg/chain.py b/pwndbg/chain.py index aa5f471fd..433c0f3b6 100644 --- a/pwndbg/chain.py +++ b/pwndbg/chain.py @@ -30,7 +30,7 @@ c = ColorConfig( def get( address: int | None, - limit: int = int(LIMIT), + limit: int = LIMIT, offset: int = 0, hard_stop: int | None = None, hard_end: int = 0, @@ -98,7 +98,7 @@ config_contiguous = theme.add_param( def format( value: int | List[int] | None, - limit: int = int(LIMIT), + limit: int = LIMIT, code: bool = True, offset: int = 0, hard_stop: int | None = None, diff --git a/tests/gdb-tests/tests/binaries/linked-lists.c b/tests/gdb-tests/tests/binaries/linked-lists.c index f304b24c5..705cf29e9 100644 --- a/tests/gdb-tests/tests/binaries/linked-lists.c +++ b/tests/gdb-tests/tests/binaries/linked-lists.c @@ -6,7 +6,10 @@ struct node { int value; struct node *next; }; -struct node node_c = { 2, NULL }; +struct node node_f = { 5, NULL }; +struct node node_e = { 4, &node_f }; +struct node node_d = { 3, &node_e }; +struct node node_c = { 2, &node_d }; struct node node_b = { 1, &node_c }; struct node node_a = { 0, &node_b }; diff --git a/tests/gdb-tests/tests/test_command_plist.py b/tests/gdb-tests/tests/test_command_plist.py index c0daddf6f..a0a86ea19 100644 --- a/tests/gdb-tests/tests/test_command_plist.py +++ b/tests/gdb-tests/tests/test_command_plist.py @@ -9,7 +9,7 @@ import tests LINKED_LISTS_BINARY = tests.binaries.get("linked-lists.out") -def startup(start_binary): +def startup(start_binary) -> None: start_binary(LINKED_LISTS_BINARY) gdb.execute("break break_here") @@ -17,6 +17,66 @@ def startup(start_binary): gdb.execute("up") +def test_command_plist_dereference_limit_change_has_impact_on_plist(start_binary): + """ + Tests the plist command with different dereference limits + """ + startup(start_binary) + gdb.execute("set dereference-limit 5") + expected_out = re.compile( + """\ +0[xX][0-9a-fA-F]+ : {\\s* + value = 0,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 1,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 2,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 3,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 4,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 5,\\s* + next = 0x0\\s* +}\ +""" + ) + + result_str = gdb.execute("plist node_a next", to_string=True) + assert expected_out.match(result_str) is not None + + gdb.execute("set dereference-limit 1") + expected_out = re.compile( + """\ +0[xX][0-9a-fA-F]+ : {\\s* + value = 0,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 1,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 2,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\ +""" + ) + + result_str = gdb.execute("plist node_a next", to_string=True) + assert expected_out.match(result_str) is not None + + def test_command_plist_flat_no_flags(start_binary): """ Tests the plist for a non-nested linked list @@ -35,8 +95,21 @@ def test_command_plist_flat_no_flags(start_binary): }\\s* 0[xX][0-9a-fA-F]+ : {\\s* value = 2,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 3,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 4,\\s* + next = 0[xX][0-9a-fA-F]+ \\s* +}\\s* +0[xX][0-9a-fA-F]+ : {\\s* + value = 5,\\s* next = 0x0\\s* -}""" +}\ +""" ) result_str = gdb.execute("plist node_a next", to_string=True)