HowTo: Writing into process memory with GDB.

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:
{% highlight c %}

include <stdio.h>

include <unistd.h>

void inject() { printf("injected.\n"); }

int main()
{
int i = 0x10;
int *x = &i;
printf("%d\n", i);
return write(0, "Hello, sailor!\n", 100);
}
{% endhighlight %}

Run GDB and display 16 4-Byte Blocks on the stack.

$ gdb foo
gdb> break main
gdb> run
gdb> x /16xw $esp  

{% highlight bash %}
0xbfb4c894: 0xbfb4c8b0 0xbfb4c928 0xb76bcbd6 0x08048410
0xbfb4c8a4: 0x00000000 0xbfb4c928 0xb76bcbd6 0x00000001
0xbfb4c8b4: 0xbfb4c954 0xbfb4c95c 0xb7818858 0xbfb4c910
0xbfb4c8c4: 0xffffffff 0xb7834ff4 0x08048229 0x00000001
{% endhighlight %}
Setting memory in gdb:

Setting a memory address:

gdb> set {int}0xbfb4c8a4 = 0x01010101

{% highlight bash %}
0xbfb4c894: 0xbfb4c8b0 0xbfb4c928 0xb76bcbd6 0x08048410
0xbfb4c8a4: 0x01010101 0xbfb4c928 0xb76bcbd6 0x00000001
{% endhighlight %}
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

{% highlight bash %}
0xbfb4c894: 0xbfb4c8b0 0xbfb4c928 0xb76bcbd6 0x08048410
0xbfb4c8a4: 0x01010101 0x02020202 0x03030303 0x00000001
{% endhighlight %}
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:
{% highlight bash %}
$ objdump -D foo | grep inject
08048424 :
{% endhighlight %}

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.