From 1c609eba1571b6a3fcb91ef9ade0ba3e06cacdc8 Mon Sep 17 00:00:00 2001 From: Disconnect3d Date: Sat, 3 Dec 2022 20:10:55 +0700 Subject: [PATCH] Fix #1399: cymbol command on old GDB (#1409) The cymbol command did not work on old GDB versions like 8.2 because they require the ADDR argument to be passed into the `add-symbol-file` command unlike newer GDB versions in which the argument is optional. This can be seen below. ``` pwndbg> help add-symbol-file Load symbols from FILE, assuming FILE has been dynamically loaded. Usage: add-symbol-file FILE ADDR [-readnow | -readnever | -s SECT-NAME SECT-ADDR]... ADDR is the starting address of the file's text. Each '-s' argument provides a section name and address, and should be specified if the data and bss segments are not contiguous with the text. SECT-NAME is a section name to be loaded at SECT-ADDR. The '-readnow' option will cause GDB to read the entire symbol file immediately. This makes the command slower, but may make future operations faster. The '-readnever' option will prevent GDB from reading the symbol file's symbolic debug information. pwndbg> version Gdb: 8.1.1 Python: 3.6.9 (default, Jun 29 2022, 11:45:57) [GCC 8.4.0] Pwndbg: 1.1.1 build: c5d8800 Capstone: 4.0.1024 Unicorn: 2.0.7 ``` vs ``` pwndbg> help add-symbol-file Load symbols from FILE, assuming FILE has been dynamically loaded. Usage: add-symbol-file FILE [-readnow | -readnever] [-o OFF] [ADDR] [-s SECT-NAME SECT-ADDR]... ADDR is the starting address of the file's text. Each '-s' argument provides a section name and address, and should be specified if the data and bss segments are not contiguous with the text. SECT-NAME is a section name to be loaded at SECT-ADDR. OFF is an optional offset which is added to the default load addresses of all sections for which no other address was specified. The '-readnow' option will cause GDB to read the entire symbol file immediately. This makes the command slower, but may make future operations faster. The '-readnever' option will prevent GDB from reading the symbol file's symbolic debug information. pwndbg> version Gdb: 12.1 Python: 3.10.6 (main, Nov 2 2022, 18:53:38) [GCC 11.3.0] Pwndbg: 1.1.1 build: c5d8800 Capstone: 4.0.1024 Unicorn: 2.0.0 pwndbg> ``` --- pwndbg/commands/cymbol.py | 5 ++++- tests/gdb-tests/tests/test_cymbol.py | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pwndbg/commands/cymbol.py b/pwndbg/commands/cymbol.py index fa98a8571..20fa776e3 100644 --- a/pwndbg/commands/cymbol.py +++ b/pwndbg/commands/cymbol.py @@ -181,7 +181,10 @@ def load_custom_structure(custom_structure_name, custom_structure_path): pwndbg_debug_symbols_output_file = generate_debug_symbols(custom_structure_path) if not pwndbg_debug_symbols_output_file: return # generate_debug_symbols prints on failures - gdb.execute(f"add-symbol-file {pwndbg_debug_symbols_output_file}", to_string=True) + # Old GDB versions (e.g. 8.2) requires addr argument in add-symbol-file + # we set that address to which to load the symbols to 0 since it doesn't matter here + # (because we are only loading types information) + gdb.execute(f"add-symbol-file {pwndbg_debug_symbols_output_file} 0", to_string=True) loaded_symbols[custom_structure_name] = pwndbg_debug_symbols_output_file print(message.success("Symbols are loaded!")) diff --git a/tests/gdb-tests/tests/test_cymbol.py b/tests/gdb-tests/tests/test_cymbol.py index 77659bc96..0187ad7ca 100644 --- a/tests/gdb-tests/tests/test_cymbol.py +++ b/tests/gdb-tests/tests/test_cymbol.py @@ -51,9 +51,12 @@ def test_cymbol(start_binary): assert pwndbg.commands.cymbol.loaded_symbols.get("example") is not None # Test whether the returned type is what we expect (on x86-64). assert ( - "example_t\n +0x0000 a : int\n +0x0004 b : char [16]\n +0x0018 c : char *\n +0x0020 d : void *" - in pwndbg.gdblib.dt.dt("example_t").strip() - ) + "example_t\n" + " +0x0000 a : int\n" + " +0x0004 b : char [16]\n" + " +0x0018 c : char *\n" + " +0x0020 d : void *" + ) == pwndbg.gdblib.dt.dt("example_t").strip() # Test whether unload_loaded_symbol() works properly. pwndbg.commands.cymbol.unload_loaded_symbol("example")