Use this .gdbinit. Make sure you save it as your ~/.gdbinit file in $HOME. This adds functionality: you can see the stack, data, registers and code and how they change on each cmd entered into gdb. For best results use 80x24 sized windows (It acts like a motion picture in that size.)
Given a trivial program:
Run GDB and display 16 4-Byte Blocks on the stack.
$ gdb foo
gdb> break main
gdb> run
gdb> x /16xw $esp
Setting memory in gdb:
Setting a memory address:
gdb> set {int}0xbfb4c8a4 = 0x01010101
Addresses can be accessed by offsets, for example to access the next 4 bytes:
gdb> set {int}0xbfb4c8a8 = 0x02020202 gdb> set {int}0xbfb4c8ac = 0x03030303 gdb> x /16xw $esp
Setting variables in gdb:
gdb> print i
$1 = 0x10
we can set variables to whatever we want:
gdb> set variable i = 0x40 gdb> print i $2 = 0x40
You can also do this with pointers:
gdb> set variable *x=ee gdb> print i $6 = 0xee gdb> print *x $7 = 0xee
You can do this with registers as well: Find the address of inject function:
You can then set $eip to change the code path.
gdb> print $eip $1 = (void (*)()) 0x8048456 gdb> set $eip=0x8048424 gdb> n 0x08048425 4 void inject() { printf("injected.\n"); } gdb> n injected.