From da8ef8aa7324b506c79931ae9bb1dfcf3a879c0c Mon Sep 17 00:00:00 2001 From: Disconnect3d Date: Wed, 4 Jan 2023 02:11:20 +0100 Subject: [PATCH] Fix #855: Rust binaries debugging (#1495) * Fix #855: Rust binaries debugging This fixes #855 by using a workaround when we set language to C, fetch symbols and set language back to Rust or auto. Note that I also extended the list of symbols we fetched as... it seems that the C language that is being set during some events may not have e.g. `short` but may have a `short int` symbol. This is kinda weird, but this is how it is. Idk if that's a GDB bug or what. ``` ipdb> gdb.execute('show language') The current source language is "auto; currently c". ipdb> gdb.lookup_type('short') *** gdb.error: No type named short. ipdb> gdb.lookup_type('int') ipdb> gdb.lookup_type('short int') ipdb> gdb.lookup_type('long int') ``` * fix code review issues --- pwndbg/gdblib/typeinfo.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/pwndbg/gdblib/typeinfo.py b/pwndbg/gdblib/typeinfo.py index 3dd6c778b..dce092c40 100644 --- a/pwndbg/gdblib/typeinfo.py +++ b/pwndbg/gdblib/typeinfo.py @@ -25,11 +25,22 @@ def lookup_types(*types): def update(): + # Workaround for Rust stuff, see https://github.com/pwndbg/pwndbg/issues/855 + lang = gdb.execute("show language", to_string=True) + if "rust" not in lang: + restore_lang = None + else: + gdb.execute("set language c") + if '"auto;' in lang: + restore_lang = "auto" + else: + restore_lang = "rust" + module.char = gdb.lookup_type("char") module.ulong = lookup_types("unsigned long", "uint", "u32", "uint32") module.long = lookup_types("long", "int", "i32", "int32") module.uchar = lookup_types("unsigned char", "ubyte", "u8", "uint8") - module.ushort = lookup_types("unsigned short", "ushort", "u16", "uint16") + module.ushort = lookup_types("unsigned short", "ushort", "u16", "uint16", "uint16_t") module.uint = lookup_types("unsigned int", "uint", "u32", "uint32") module.void = lookup_types("void", "()") @@ -45,9 +56,9 @@ def update(): } module.int8 = lookup_types("char", "i8", "int8") - module.int16 = lookup_types("short", "i16", "int16") + module.int16 = lookup_types("short", "short int", "i16", "int16") module.int32 = lookup_types("int", "i32", "int32") - module.int64 = lookup_types("long long", "long", "i64", "int64") + module.int64 = lookup_types("long long", "long long int", "long", "i64", "int64") module.signed = {1: module.int8, 2: module.int16, 4: module.int32, 8: module.int64} module.pvoid = void.pointer() @@ -68,6 +79,10 @@ def update(): raise Exception("Pointer size not supported") module.null = gdb.Value(0).cast(void) + # Rust workaround part 2 + if restore_lang: + gdb.execute("set language %s" % restore_lang) + # TODO: Remove this global initialization, or move it somewhere else # Call it once so we load all of the types