SETTING BREAKPOINTS: NORMAL

METHOD 1: VIA SYMBOLIC NAME (NON STRIPPED SYMBOLS)

This sets a breakpoint using the function’s symbolic name. GDB looks up main in the program’s symbol table and places the breakpoint at the start of that function. The advantage of this symbolic method is that it automatically resolves the correct address even when function addresses change between runs (e.g., due to PIE or ASLR). The limitation is that it requires symbol information—if the binary is stripped of symbols, GDB cannot resolve main by name.

gef>  b _start
 Breakpoint 1 at 0x401000
 
gef>  r
 Starting program: ./helloWorld 

 Breakpoint 1, 0x0000000000401000 in _start ()
 [ Legend: Modified register | Code | Heap | Stack | String ]
 ───────────────────────────────────────────────────────────────────────────────────── registers ────
 $rax   : 0x0               
 $rbx   : 0x0               
 $rcx   : 0x0               
 $rdx   : 0x0               
 $rsp   : 0x00007fffffffe310  →  0x0000000000000001
 $rbp   : 0x0               
 $rsi   : 0x0               
 $rdi   : 0x0               
 $rip   : 0x0000000000401000  →  <_start+0> mov eax, 0x1
 ...SNIP...
 ───────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffe310│+0x0000: 0x0000000000000001	 ← $rsp
 0x00007fffffffe318│+0x0008: 0x00007fffffffe5a0  →  "./helloWorld"
 ...SNIP...
 ─────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
      0x400ffa                  add    BYTE PTR [rax], al
      0x400ffc                  add    BYTE PTR [rax], al
      0x400ffe                  add    BYTE PTR [rax], al
  →   0x401000 <_start+0>       mov    eax, 0x1
      0x401005 <_start+5>       mov    edi, 0x1
      0x40100a <_start+10>      movabs rsi, 0x402000
      0x401014 <_start+20>      mov    edx, 0x12
      0x401019 <_start+25>      syscall 
      0x40101b <_start+27>      mov    eax, 0x3c
 ─────────────────────────────────────────────────────────────────────────────────────── threads ────
 [#0] Id 1, Name: "helloWorld", stopped 0x401000 in _start (), reason: BREAKPOINT
 ───────────────────────────────────────────────────────────────────────────────────────── trace ────
 [#0] 0x401000 → _start()
 ────────────────────────────────────────────────────────────────────────────────────────────────────
 
 * from here another breakpoint can be set
    - e.g., if another breakpoint is required at "_start+10", use either
      b *_start+10 or b *0x40100a 

METHOD 2: VIA EXPRESSION METHOD (STRIPPED SYMBOLS)

This sets a breakpoint by evaluating an expression into a memory address and placing the breakpoint at that exact address. In this case, main is treated as the address of the function, and the * tells GDB to break at the instruction located there. Unlike the symbolic method, this approach does not rely on symbol resolution at runtime once the address is known, and it allows breakpoints to be set at arbitrary offsets (e.g., break *main+20 to stop partway into the function). However, because it uses a raw address, breakpoints may not remain valid across runs when ASLR or PIE causes addresses to shift, unless they are still tied to a symbol expression.

//step 1: identify all the program functions
root@dev:~$ gdb ./{executableFilename.out}
gef> info func
 ALL defined functions:
 
 File lab03.c
 11:    int f1();
 26:    void f2();
 21:    int f3(int, int, int);
 5:     void getNameLen();
 35:    int main();
 
 Non-debugging symbols:
 0x00001000    _init
 0x00001080    _cxa_finalize@plt
 0x00001090    printf@plt
 ...

 * this displays user-defined functions, etc
    - note that most malware doesn't have debug symbols turned on
 * func is short for functions
    
//step 2: set breakpoints - setting breakpoints on ALL identified functions
gef> break *main
 Breakpoint 1 at 0x132f: file lab03.c, line 35
gef> break *f1
 Breakpoint 2 at 0x126d: file lab03.c, line 11
gef> break *f2
 Breakpoint 3 at 0x12ed: file lab03.c, line 26
gef> break *f3
 Breakpoint 4 at 0x12b4: file lab03.c, line 21
gef> break *getNameLen
 Breakpoint 5 at 0x120d: file lab03.c, line 5
 
 * 

gef> info breakpoint
 Num Type       Disp Enb  Address     What
 1   breakpoint keep y    0x0000132f  in main at lab03.c:35
 2   breakpoint keep y    0x0000126d  in f1 at lab03.c:11
 3   breakpoint keep y    0x000012ed  in f2 at lab03.c:26
 4   breakpoint keep y    0x000012b4  in f3 at lab03.c:21
 5   breakpoint keep y    0x0000120d  in getNameLen at lab03.c:5

 * display breakpoints that are enabled

Last updated