As you may have noticed, I’m preparing to become an OSCP. In addition to brushing up on assembly, I’ll also be stepping through the debugger.
Let’s review gdb and go over some tips to make sure the course work becomes smooth sailing. This is primarily an introduction to general use of gdb, but there are a few tips and tricks as well.
Introducing gdb
Installing gdb
BackTrack doesn’t come with gdb; I don’t understand why, but it’s a Debian distro, so this will install it:
# apt-get install gdb
Loading a program into gdb
# gdb ./VariableDemo
Debugging symbols
While plenty of gdb features will work on any executable, many of the really useful features require that the executable was assembled with debugging symbols enabled.
A note about 32-bit vs 64-bit
My machine is 64-bit so the example output displayed here is all 64-bit. You’ll notice that the registers are %rax, %rbx, etc. instead of %eax, %ebx, etc. This is because the registers are 64-bit instead of 32-bit, but is generally unimportant in regards to the examples.
Example assembly program
The examples shown here were produced using the following assembly language program:
# Demo program using variables in assembly .data HelloWorld: .ascii "Hello World!" ByteLocation: .byte 10 Int32: .int 2 Int16: .short 3 Float: .float 10.23 IntegerArray: .int 10,20,30,40,50 .bss .comm LargeBuffer, 10000 .text .globl _start _start: nop # call exit(0) movl $1, %eax movl $0, %ebx int $0x80
Listing the program code
From the current position in the source file (context of what is being executed)
At the (gdb) command prompt:
list
If the program is not running, this will list the first 10 lines of code. If the program is running, this will list the 10 lines surrounding the last line that was executed (in other words, you will see the context in which the program is executing at that time). This is useful when you’re stepping through a program. Press [enter] to continue perusing the next 10 lines of code.
Example
(gdb) list 1 # Demo program using variables in assembly 2 3 .data 4 5 HelloWorld: 6 .ascii "Hello World!" 7 8 ByteLocation: 9 .byte 10 10
A specific line
At the (gdb) command prompt:
list 20
This will list the 10 lines of code surrounding line 20. In other words, you will see lines 15 through 24. Press [enter] to continue perusing the next 10 lines of code.
Example
(gdb) list 20 15 Float: 16 .float 10.23 17 18 IntegerArray: 19 .int 10,20,30,40,50 20 21 .bss 22 .comm LargeBuffer, 10000 23 24 .text
Setting a break point
By line number
At the (gdb) command prompt:
break 10
Example
(gdb) break 10 Breakpoint 1 at 0x4000b0: file VariableDemo.s, line 10.
This will set a break point at line 10.
By function name
At the (gdb) command prompt:
break *_start+1
This will set a break point at the first line of the _start function. The asterisk followed by the method name tells gdb that we are referring to the memory location of that method.
Example
(gdb) break *_start+1 Breakpoint 1 at 0x4000b1: file VariableDemo.s, line 32.
Running the program
At the (gdb) command prompt:
run
The program will execute until it hits a breakpoint, an input operation, an error, or until the program exits.
Example
(gdb) run Starting program: /root/assembly/VariableDemo Breakpoint 1, _start () at VariableDemo.s:32 32 movl $1, %eax
Stepping through the program
At the (gdb) command prompt:
step
The program will execute until it reaches the next source line; the next source line will also be displayed on screen. If you step again the source line displayed on screen will execute. You can also just use s for short instead of step.
Example
(gdb) step 33 movl $0, %ebx
Continuing execution after a breakpoint
At the (gdb) command prompt:
continue
The program will continue executing until it reaches a breakpoint, an input operation, an error, or until the program exits. You can also just use c for short instead of continue.
Example
(gdb) continue Continuing. Program exited normally.
Listing variables
At the (gdb) command prompt:
info variables
Print the variables defined by the program.
Example
(gdb) info variables All defined variables: Non-debugging symbols: 0x00000000006000c0 HelloWorld 0x00000000006000cc ByteLocation 0x00000000006000cd Int32 0x00000000006000d1 Int16 0x00000000006000d3 Float 0x00000000006000d7 IntegerArray 0x00000000006000f0 LargeBuffer
Listing registers
At the (gdb) command prompt:
info registers
Print the registers defined by the program.
Example
(gdb) info registers rax 0x0 0 rbx 0x0 0 rcx 0x0 0 rdx 0x0 0 rsi 0x0 0 rdi 0x0 0 rbp 0x0 0x0 rsp 0x7fffffffe4b0 0x7fffffffe4b0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x200 512 r12 0x0 0 r13 0x0 0 r14 0x0 0 r15 0x0 0 rip 0x4000b1 0x4000b1 <_start+1> eflags 0x202 [ IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0
Understanding how to examine memory
When examining memory locations you use the x command. The x command requires the format to print the data and the location of the data to print.
At the (gdb) command prompt:
x/FMT ADDRESS
The format includes the data size, data type, and number of objects to print.
Valid Data Types
o(octal)
x(hex)
d(decimal)
u(unsigned decimal)
t(binary)
f(float)
a(address)
i(instruction)
c(char)
s(string)
Valid Data Sizes
b(byte)
h(halfword, 2 bytes, int16)
w(word, 4 bytes, int32)
g(giant, 8 bytes, int64)
Examining memory
By memory location
At the (gdb) command prompt:
x/12cb 0x00000000006000c0
Examine the 12 bytes at memory location 0x00000000006000c0. Print the bytes as characters.
Example
(gdb) x/12cb 0x00000000006000c0 0x6000c0 : 72 'H' 101 'e' 108 'l' 108 'l' 111 'o' 32 ' ' 87 'W' 111 'o' 0x6000c8 : 114 'r' 108 'l' 100 'd' 33 '!'
By label name
At the (gdb) command prompt:
x/5dw &IntegerArray
Examine the 5 words at the memory location of label IntegerArray. Print the words as decimals (ints).
Example
(gdb) x/5dw &IntegerArray 0x6000d7 : 10 20 30 40 0x6000e7 : 50
Getting help
At the (gdb) command prompt:
help x
If you forgot how to examine memory, this would return helpful information for the x
Example
(gdb) help x Examine memory: x/FMT ADDRESS. ADDRESS is an expression for the memory address to examine. FMT is a 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) and s(string). Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes). The specified number of objects of the specified size are printed according to the format. Defaults for format and size letters are those previously used. Default count is 1. Default address is following last thing printed with this command or "print".
More to Come
That’s it for the basics of gdb. As I continue to pick up tips I’ll cover more topics, so expect to see more soon!