How to add debug symbols to stripped ELF binaries - debugging

I need to disassemble debian binaries with debug symbols and I am using IDA Pro for this. The problem is: IDA doesn't seem to recognize debug symbols if they are stored in a separate file (in the case of debian packages). However, when compiling a binary and keeping the debug symbols in it, IDA has no problem annotating all functions and variables.
So my question is: is there a way to add the debug symbols back to the stripped binary? The goal would be to create a single binary with debug symbols. Can one for example use gdb to 1) debug the stripped binary; 2) load debug symbols; and 3) produce a binary that contains these symbols.
One method I found here proposed to copy the debug sections from back into the binary. Unfortunately, this worked only partly and some symbols are still missing. I've verified this using gdb.

For gdb use set debug-file-directory
For IDA Pro:
open the debug symbol file in IDA Pro
export database/typeinfo as IDC script
edit IDC script
merge database/typeinfo IDC script manually
comment out DeleteAll()
open the stripped ELF file in IDA Pro
after the analysis is finished, execute the IDC script

Related

Add breakpoints to elf

I am building an OS in assembly and I am using NASM for assembly. I am telling to NASM to create a binary file that I am using to debug with QEMU.
To debug easier I am using gdb with QEMU. I am giving to gdb an .elf object file that I am creating using NASM (with the same input files and just .elf output).
The NASM does not support adding breakpoints in source code and when I want to put a breakpoint I am telling it to gdb. Because I am assembling a lot of times per day the OS using a batch file. The problem is that evry time I am reassembling the OS the debug info are lost so I need to reput the breakpoints.
As you may know an OS have a lot of functions and I want to put a breakpoint at most of them so I cannot continue with this way.
So which the way to put breakpoints at an elf file?
I can for example use the gdb and at command line pass a file as stdin that contains the instructions and then exit?

kgdb refused to be able to access symbols for just one certain driver, nor do those symbols appear in vmlinux

I'm trying to debug a driver.
gdb says...
(gdb) break i2c-hid.c:i2c_hid_suspend
No source file named i2c-hid.c.
Breakpoint 9 (i2c-hid.c:i2c_hid_suspend) pending.
nm vmlinux --- does not find any function names from within that file.
cat /proc/kallsyms --- shows all the functions names contained in that file.
I added this to the Makefile "EXTRA_CFLAGS += -DI2C-HID_DEBUG -g" to no avail.
Does anyone know what I need to do to make gdb able to see the symbols from this file?
I get symbol level debugging for plenty of other drivers.
It looks like i2c-hid.c is not part of vmlinux, which means it is outside of basic kernel. That is why nm vmlinux does not show symbols related to this file.
cat /proc/kallsyms will show those symbols because it shows all the kernel symbols inclunding drivers' symbols which are not part of vmlinux.
I am not sure whether you are using gdb or kgdb, but I think to debug drivers, you need to use kgdb, not gdb.
If you are already using kgdb, then use add-symbol-file command under it. It will help you load symbols which are outside vmlinux. Simple google search will give you lot of information of add-symbol-file.
When debugging Linux kernel, GDB does not automatically load symbols for kernel modules like it would do for user-mode shared libraries. Instead you need to load them manually using the following command:
add-symbol-file <kernel module>.o <core address> -s <sectionX> <addressX> -s <...>
You can find out the core address of the module (and the addresses of all sections) by setting a breakpoint in the do_init_module() function and examining the mod variable once the breakpoint is hit:
print mod->name
print mod->module_core
print *mod->sect_attrs->attrs#mod->sect_attrs->nsections
You can read more about loading kernel module symbols in the Linux kernel symbol overview.

GDB an ELF File Under Win32

I wanted to study ELF relocation mechanism, so I assembled an x86 assembly program using NASM to produce an ELF file, but under Win32. Then I used mingw32's gdb to debug it. It loaded nicely and I could view the program using "list" command. However, I couldn't run it. I got the following messages:
Starting program: c:\Projects\NasmProjects\Test01\Hello.o
Error creating process c:\Projects\NasmProjects\Test01\Hello.o
Is there a way around this?
Is there a way around this?
No.
First, you have assembled a relocatable object file (of type ET_REL). There is no OS that will "run" such files -- OSes that do support executing ELF files, require a fully linked executable (of type ET_EXEC or ET_DYN).
Second, even if you manage to link an ET_EXEC, you still need your OS to know how to load and start executing such a file. Linux and Solaris kernels do know this, AIX and Windows kernels do not.

How to debug command line file with symbolic data

I have a compiled .exe file (compiled with gfortran and -g option) that crashes. I can attach the WinDBG program to it using the WinDBG -I command.
Funny enough it generates a stack overflow:
(38f0.2830): Stack overflow - code c00000fd (!!! second chance !!!)
However, the output says that there is no debugging information in my program. It tries to search for either .dbg or .pdb files but they are not there. I would assume debugging information is included in the executable (coming from a unix-background).
Debug formats are compiler specific, so you need to use a debugger that understands the format produced by your compiler. As by gfortran I assume you mean GNU fortran, this would be the GNU gdb debugger.
I circumvented the problem by starting the program via gdb. In this way, gdb will give an error and you can issue the backtrace command.
It's not perfect, so I'm open for better solutions, but this works for now.

How do I do source level debug of library

I have a following setup. Although my working setup deals with ARM compiler Real View Developer Suite (RVDS) 3.2 on a Windows host, the situation could be generic for any other C compiler on any host.
I build a ARM library (static library - .a file) of C code using RVDS 3.2 compiler toolchain on Windows host. Then I link this library with an application using an ARM-Linux compiler toolchain on a Linux host, to get a ARM executable. Now when I try to debug this generated ARM executable on Linux using gdb, by trying to put a breakpoint in some function which is present in the library that is linked, gdb is not able to put breakpoint there citing source not found. So I manually copied all the source files(*.c) used to create the library in the Linux folder where the executable file is present. Still gdb fails to put a breakpoint.
So now I started thinking:
How can I do source level debugging of this library which I create on Windows using a different compiler chain by launching the executable which is generated by linking this library to an application, in gdb. Is it possible? How can I do it? Is there any compiler option in RVDS compiler toolchain to enable this library source level debug?
Do I need to copy the source files to linux in exactly same folder structure as that is present in windows for those source files?
You could try to see if mimicking the exact same directory structure works. If you're not sure what directory structure the compiler annotated in the debug info in the executable, you can always look at it with dwarfdump (on linux).
First, GDB does not need any source to put breakpoints on functions; so your description of what is actually happening is probably inaccurate. I would start by verifying that the function you want to break on is actually there in the binary:
nm /path/to/app | grep function_desired
Second, to do source level debugging, GDB needs debug info in a format GDB understands. On Linux this generally means DWARF or STABS. It is quite possible that your RVDS compiler does not emit such debug info; if so, source level debugging will not be possible.
Did you build the library with debugging enabled (-g option)? Without that, there would be difficulties identifying lines etc.
I've found that -fPIC will cause this sort of issue, but the only work around I've found is to not use -fPIC when I want to debug.

Resources