Introduction

Debugging symbols

<aside> 👉 Basics

</aside>

#Generate gdb specific debug symbols only otherwise gcc will fall back to OS native format
gcc -ggdb <code>

#Copy all debug symbols of a binary to another file
objcopy --only-keep-debug <binary> <fileName>

#strip a binary with its debug symbols
strip --strip-debug <binary>
strip --strig-debug --strip-unneeded <binary>

#Attach debug symbols to a binary
objcopy --add-gnu-debuglink=<debugFile> <binary>

#Load a symbol file within gdb
gdb> symbol-file <debugFile>

Untitled

Different types of symbols

Lowercase is used to denote that the symbol is local, and uppercase is used to denote that it is an external symbol.

Type Description
A Absolute symbol
B In the BSS section
D In the DATA section
N Debugging symbol
T In the TEXT section
U Undefined symbol

Breakpoint

Breakpoint is a technique used to pause the program during its execution based on a certain criteria, and this allows us to inspect the internals of a binary in its active state instruction by instruction by instruction.

#Setting breakpoints
gdb> break <symbolName>

Basic gdb usage

Checking all the functions

Shows only globally defined functions by default, but we can temporarily change scope and view others too using info scope <symbol>

gef➤  info functions
All defined functions:

File 1.c:
void main(void);
void random_function(void);

Non-debugging symbols:
0x00000378  _init
0x000003b0  puts@plt
0x000003c0  __libc_start_main@plt

Check all the variables defined

Shows only static and global variables by default

gef➤  info variables
All defined variables:

File 1.c:
const int aGlobalVariables;

Non-debugging symbols:
0x00000698  _fp_hw
0x0000069c  _IO_stdin_used
0x000006e4  __GNU_EH_FRAME_HDR
0x00000868  __FRAME_END__
0x00001ed4  __frame_dummy_init_array_entry

Checking where the symbols have been read from

gef➤  info sources
Source files for which symbols have been read in:

/home/ia32/Desktop/gdb-megaprimer/1.c, /usr/lib/gcc/i686-linux-gnu/7/include/stddef.h, /usr/include/i386-linux-gnu/bits/types.h, /usr/include/i386-linux-gnu/bits/libio.h, /usr/include/stdio.h, /usr/include/i386-linux-gnu/bits/sys_errlist.h

Source files for which symbols will be read in on demand:

gef➤

bnla bla

Cool features

Cheat-sheet

#Attaching gdb to a target program
gdb /bin/bash 

#Reduce the verbosity
gdb /bin/bash -q 

#Set a breakpoint
gdb> break <functionName>
gdb> break main
#As soon as we hit the breakpoint, we can inspect various things such as the registers in use, the value they contain etc.
gdb> run
gdb> run <commandLineArguments> 

#inspect the registers
gdb> info registers
gdb> info all-registers
#check the contents of a specific register
gdb> display /x $eax

#disassemble code
gdb> set disassembly-flavor intel
gdb> disassemble $eip

#Check the memory segment diagram
gdb> info proc mappings

#Check all the defined variables
gdb> info variables

#Step through the code one instruction at a time
gdb> stepi

#Check all the symbols
gdb> info functions

#Find the entry point in the program
bash: readelf -h <binary>

#examine a specific memory address and print its contents as a string
gdb> x/s <memAddress>

#Execute any shell command from within gdb
gdb> shell <command>