GDB-GNU-Debugger

From aldeid
Jump to navigation Jump to search

Commands

Launch gdb

$ gdb --args executable-name arg1 arg2

Breakpoints

Description Command
Create a sotfware breakpoint

Create breakpoint at address 0x40489c:

(gdb) break *0x40489c

Stop at main:

(gdb) b main  
Create a hardware breakpoint
(gdb) hbreak *0x0804b2a4
Note
If gdb claims that "No hardware breakpoint support in the target", you have to first start the program (e.g. set a sofware breakpoint and run the program first).
Clear a breakpoint (gdb) clear
Clear all breakpoints (gdb) delete
List breakpoints (gdb) info breakpoints

Debugging

Description Command
Run the program (gdb) run
Run with arguments:
(gdb) run arg1 "arg2" ...
(gdb) run $(python -c 'print "A"*200')
Run the program and break at entry point: (gdb) start
Run with arguments and break at entry point: (gdb) start arg1 "arg2" ...
Continue running until just after function in the selected stack frame returns. (gdb) finish
Restart (gdb) kill
Run (gdb) run
Step out
(gdb) step
(gdb) next
(gdb) u (use when no debugging information available)
Step in
(gdb) stepi
(gdb) nexti
Run until next breakpoint (gdb) continue
backtrace (see where a function is called)
gdb-peda$ b alarm
Breakpoint 1 at 0x400550
gdb-peda$ r
[SNIP]
Breakpoint 1, alarm () at ../sysdeps/unix/syscall-template.S:78
78	../sysdeps/unix/syscall-template.S: No such file or directory.
gdb-peda$ bt
#0  alarm () at ../sysdeps/unix/syscall-template.S:78
#1  0x00000000004007cb in set_timer ()
#2  0x0000000000400882 in main ()
#3  0x00007ffff7e18e0b in __libc_start_main (main=0x40085f <main>, argc=0x1, argv=0x7fffffffde98, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffde88)
    at ../csu/libc-start.c:308
#4  0x00000000004005c9 in _start ()

Disassembling

Description Command
Disassemble instructions (gdb) disas 0x40489c,+50
Examine memory: x/FMT ADDRESS.
ADDRESS
expression for the memory address to examine.
FMT
repeat count followed by a format letter and a size letter.
Format letters are
  • o (octal)
  • x (hex)
  • d (decimal)
  • u (unsigned decimal)
  • t (binary)
  • f (float)
  • a (address)
  • i (instruction)
  • c (char)
  • s (string)
  • T (OSType)
  • A (floating point values in hex)
Size letters are
  • b (byte)
  • h (halfword)
  • w (word)
  • g (giant, 8 bytes).

Show 12 instructions:

(gdb) x /12i $pc
=> 0x47431b:	cmp    $0xfffffffffffff000,%rax
   0x474321:	ja     0x474348
   0x474323:	test   %rax,%rax
   0x474326:	js     0x474346
   0x474328:	test   %r8d,%r8d
   0x47432b:	je     0x474346
   0x47432d:	cmp    $0x3,%r8d
   0x474331:	ja     0x474346
   0x474333:	mov    $0xffffffffffffffc0,%rax
   0x47433a:	movl   $0x0,%fs:(%rax)
   0x474341:	mov    -0x48(%rsp),%rax
   0x474346:	repz retq 
Show execution stack (shows how a function is called from the beginning) (gdb) backtrace
print string (print content of flag_buf as string)
$ p/s (char*) flag_buf
$1 = 0x6022a0 "picoCTF{gDb_iS_sUp3r_u53fuL_a6c61d82}"

Registers

Description Command
Show register value

Show value of RSP

(gdb) info reg rsp 

Show all registers:

(gdb) info reg

Format register R3 (ARM) in ASCII:

(gdb) p/c $r3
$10 = 116 't'
Modify value of register (R1 in the example)
(gdb) set $r1=65
Show stack
(gdb) x/32x $esp
0xbffff5d0:	0xbffff5e0	0xbffff842	0xbffff65c	0x0012fa74
0xbffff5e0:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffff5f0:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffff600:	0x90909090	0x90909090	0x31909090	0x01ec83c0
0xbffff610:	0x68240488	0x62697274	0x69642e68	0x2f6e6873
0xbffff620:	0x68666873	0xec836962	0x2404c601	0x50e6892f
0xbffff630:	0x890bb056	0x31e189f3	0xb080cdd2	0xcddb3101
0xbffff640:	0x41414180	0x41414141	0x41414141	0x41414141

Patching

Bytes

The below example shows how to patch the program with NOP instructions (0x90) to erase the call to the set_timer function:

$ gdb ./be-quick-or-be-dead-1 
(gdb) set disassembly-flavor intel
(gdb) b main
Breakpoint 1 at 0x40082b
(gdb) r
Starting program: /data/documents/challenges/picoCTF_2018/reversing/200-be-quick-or-be-dead-1/files/be-quick-or-be-dead-1 

Breakpoint 1, 0x000000000040082b in main ()
(gdb) disassemble 
Dump of assembler code for function main:
   0x0000000000400827 <+0>:	push   rbp
   0x0000000000400828 <+1>:	mov    rbp,rsp
=> 0x000000000040082b <+4>:	sub    rsp,0x10
   0x000000000040082f <+8>:	mov    DWORD PTR [rbp-0x4],edi
   0x0000000000400832 <+11>:	mov    QWORD PTR [rbp-0x10],rsi
   0x0000000000400836 <+15>:	mov    eax,0x0
   0x000000000040083b <+20>:	call   0x4007e9 <header>
   0x0000000000400840 <+25>:	mov    eax,0x0
   0x0000000000400845 <+30>:	call   0x400742 <set_timer>
   0x000000000040084a <+35>:	mov    eax,0x0
   0x000000000040084f <+40>:	call   0x400796 <get_key>
   0x0000000000400854 <+45>:	mov    eax,0x0
   0x0000000000400859 <+50>:	call   0x4007c1 <print_flag>
   0x000000000040085e <+55>:	mov    eax,0x0
   0x0000000000400863 <+60>:	leave  
   0x0000000000400864 <+61>:	ret    
End of assembler dump.
(gdb) set *(char*)0x400845 = 0x90
(gdb) set *(char*)0x400846 = 0x90
(gdb) set *(char*)0x400847 = 0x90
(gdb) set *(char*)0x400848 = 0x90
(gdb) set *(char*)0x400849 = 0x90
(gdb) disassemble 
Dump of assembler code for function main:
   0x0000000000400827 <+0>:	push   rbp
   0x0000000000400828 <+1>:	mov    rbp,rsp
=> 0x000000000040082b <+4>:	sub    rsp,0x10
   0x000000000040082f <+8>:	mov    DWORD PTR [rbp-0x4],edi
   0x0000000000400832 <+11>:	mov    QWORD PTR [rbp-0x10],rsi
   0x0000000000400836 <+15>:	mov    eax,0x0
   0x000000000040083b <+20>:	call   0x4007e9 <header>
   0x0000000000400840 <+25>:	mov    eax,0x0
   0x0000000000400845 <+30>:	nop
   0x0000000000400846 <+31>:	nop
   0x0000000000400847 <+32>:	nop
   0x0000000000400848 <+33>:	nop
   0x0000000000400849 <+34>:	nop
   0x000000000040084a <+35>:	mov    eax,0x0
   0x000000000040084f <+40>:	call   0x400796 <get_key>
   0x0000000000400854 <+45>:	mov    eax,0x0
   0x0000000000400859 <+50>:	call   0x4007c1 <print_flag>
   0x000000000040085e <+55>:	mov    eax,0x0
   0x0000000000400863 <+60>:	leave  
   0x0000000000400864 <+61>:	ret    
End of assembler dump.
(gdb) c
Continuing.
Be Quick Or Be Dead 1
=====================

Calculating key...
Done calculating key
Printing flag:
picoCTF{why_bother_doing_unnecessary_computation_29ff5e84}
[Inferior 1 (process 11770) exited normally]
(gdb) q

Value

If you want to set a value, you can do as follows:

(gdb) b print_flag
(gdb) c
(gdb) set {int}0x6010c0 = 0xd73ec32d
(gdb) set {int}0x6010c4 = 0xf51f7eb6

Check that the key was set and continue:

(gdb) x 0x6010c0
 0x6010c0 <key>: 0xf51f7eb6d73ec32d
(gdb) c
Continuing.
Printing flag:
picoCTF{the_fibonacci_sequence_can_be_done_fast_73e2451e}

Misc

Description Command
Show arguments
(gdb) show args
Show file information (e.g. entry point)
(gdb) info files

Example:

(gdb) info files
Symbols from "/data/01f47d58806a8264cd4b2b97b9dabb4a".
Local exec file:
	`/data/01f47d58806a8264cd4b2b97b9dabb4a', file type elf32-i386.
	Entry point: 0x8048380
	0x08048154 - 0x08048167 is .interp
	0x08048168 - 0x08048188 is .note.ABI-tag
	0x08048188 - 0x080481ac is .note.gnu.build-id
	0x080481ac - 0x080481cc is .gnu.hash
	0x080481cc - 0x0804823c is .dynsym
	0x0804823c - 0x08048291 is .dynstr
	0x08048292 - 0x080482a0 is .gnu.version
	0x080482a0 - 0x080482c0 is .gnu.version_r
	0x080482c0 - 0x080482c8 is .rel.dyn
	0x080482c8 - 0x080482f0 is .rel.plt
	0x080482f0 - 0x0804831e is .init
	0x08048320 - 0x08048380 is .plt
	0x08048380 - 0x080485ec is .text
	0x080485ec - 0x08048606 is .fini
	0x08048620 - 0x080486cb is .rodata
	0x080486cb - 0x080486e8 is text
	0x080486e8 - 0x0804871c is .eh_frame_hdr
	0x0804871c - 0x080487dc is .eh_frame
	0x08049f14 - 0x08049f1c is .ctors
	0x08049f1c - 0x08049f24 is .dtors
	0x08049f24 - 0x08049f28 is .jcr
	0x08049f28 - 0x08049ff0 is .dynamic
	0x08049ff0 - 0x08049ff4 is .got
	0x08049ff4 - 0x0804a014 is .got.plt
	0x0804a014 - 0x0804a01c is .data
	0x0804a020 - 0x0804a060 is .bss
Change disassembly style to intel
(gdb) set disassembly-flavor intel
Show Assembly panel
(gdb) layout asm
Show registers panel
(gdb) layout regs
Quit
(gdb) quit

Customization

pwndbg

peda