Fix #1610: symbol.get with duplicated symbols (#1611)

* Fix #1610: symbol.get with duplicated symbols

See https://github.com/pwndbg/pwndbg/issues/1610

* fix ubuntu 18.04 build

* fix ubuntu 18.04 build
This commit is contained in:
Disconnect3d 2023-03-07 05:00:09 +01:00 committed by GitHub
parent 9ac6e679e5
commit 86b512979c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 0 deletions

View File

@ -84,6 +84,10 @@ def get(address: int, gdb_only=False) -> str:
res = pwndbg.ida.Name(address) or pwndbg.ida.GetFuncOffset(address)
return res or ""
# If there are newlines, which means that there are multiple symbols for the address
# then use the first one (see also #1610)
result = result[: result.index("\n")]
# See https://github.com/bminor/binutils-gdb/blob/d1702fea87aa62dff7de465464097dba63cc8c0f/gdb/printcmd.c#L1594-L1624
# The most often encountered formats looks like this:
# "main in section .text of /bin/bash"

View File

@ -28,3 +28,43 @@ def test_symbol_get(start_binary):
assert get_next_ptr() == "A::foo(int, int)"
assert get_next_ptr() == "A::call_foo()"
def test_symbol_duplicated_symbols_issue_1610():
"""
Test for the bug from https://github.com/pwndbg/pwndbg/issues/1610
"""
gdb.execute(f"file {MANGLING_BINARY}")
main_addr = int(gdb.parse_and_eval("(unsigned long long)main"))
# Sanity checks
assert gdb.execute("info symbol main", to_string=True) == "main in section .text\n"
assert pwndbg.gdblib.symbol.get(main_addr) == "main"
# This causes some confusion, see below :)
# Note: {addr} argument is needed for old GDB (e.g. on Ubuntu 18.04)
addr = _get_section_addr(".text")
gdb.execute(f"add-symbol-file {MANGLING_BINARY} {addr}")
# Sanity check - yeah, there are two symbols
out = gdb.execute("info symbol main", to_string=True).split("\n")
assert len(out) == 3
assert out[0] == out[1]
assert out[0].startswith("main in section .text of ")
assert out[2] == ""
# Make sure to clear cache!
pwndbg.gdblib.symbol.get.clear()
# Real test assert - this should not crash!
assert pwndbg.gdblib.symbol.get(main_addr) == "main"
def _get_section_addr(sect):
result = gdb.execute("maintenance info sections", to_string=True).split("\n")
text_line = next(line for line in result if f": {sect} " in line)
return int(text_line.split(" at ")[1].split(":")[0], 16)