Documents to read

Start

In GDB, we could use command listed below to start a program:

  • run (or r for short) to start a program, with no breakpoint.
  • start to start a program, with a breakpoint set on main.
  • starti to start a program, with a breakpoint set on _start.
  • attach <PID> to attach to a program which is already running.
  • core <PATH> to analyze the coredump of an already run program.
  • continue (or c for short): continue to run the program if it’s paused.

Inspecting Registers

  • info registers (or info reg for short): see the values for all your registers.
  • print $rdi: print out the value inside the register rdi.

Examining Memory

You can examine the contents of memory using the x/<n><u><f> <addr> parameterized command. In this format:

  • <u> is the unit size to display. Valid sizes are:
    • b (1 byte), h (2 byte), w (4 bytes), and g (8 bytes)
  • <f> is the format to display it in. Valid formats are:
    • d (decimal), x (hexadecimal), s (string) and i (instruction).

You can also disassemble main, or disas main for short, to print all of the instructions of main.

Setting Breakpoint

You could use break *<addr> or b *<addr> for short, to set a break point at the specified address.

To stepping through a program, you could use the following commands:

  • stepi <n> (si <n>): To step forward one instruction.
  • nexti <n> (ni <n>): To step forward one instruction, while stepping over any function calls.
  • finish: To finish the currently executing function.

While stepping through a program. you may find it useful to have some values displayed to you at all times.
display/<n><u><f> <var> does this for you.

GDB Scripting

You can write your commands to some file, for example x.gdb, and then launch gdb using the flag -x <PATH_TO_SCRIPT>. This file will execute all of the commands after gdb launches.

Alternatively, you can execute individual commands with -ex '<COMMAND>'.

Finally, you can get some commands be always executed for any gdb session by putting them in ~/.gdbinit, like set disassembly-flavor intel.

Some example:

1
2
3
4
5
6
7
start
break *main+42
commands
x/gx $rbp-0x32
continue
end
continue
1
2
3
4
5
6
7
8
9
start
break *main+42
commands
silent
set $local_variable = *(unsigned long long*)($rbp-0x32)
printf "Current value: %llx\n", $local_variable
continue
end
continue

Here the silent indicates that we want gdb to not report that we have hit a breakpoint, to make the output a bit cleaner.
Then we use set to define a variable within gdb session, whose value is our local variable.

1
2
3
4
5
6
7
8
9
catch syscall read
commands
silent
if ($rdi == 42)
set $rdi = 0
end
continue
end
continue