I happen to come across an on-line exploit development class recently. It is/was a class hosted by the
Community City College of San Francisco, but due to some logistical issues the professor is hosting as a ‘pirate class’ — available to everyone for free.
After the first couple weeks, I’m having a blast in it. It covers some basic ASM (for 32bit Intel processors) and basic C and teaches the GDB 101 stuff.
I’m starting to dust off many old cobwebs from an ex-developer from decades ago.
Wow, has it really been that long?
It took me longer than I wanted, but I was eventually able to remember how to read stack memory.
For example, when debugging, it’s helpful to know the memory address where the stack starts, ends and the memory address of the next instruction (the eip register).
(gdb) info reg
eax 0x41 65
ecx 0xfbad2288 -72539512
edx 0x41 65
ebx 0x80481b0 134513072
esp 0xffffd5f0 0xffffd5f0
ebp 0xffffd638 0xffffd638
esi 0x80eb00c 135180300
edi 0x49656e69 1231384169
eip 0x80489ba 0x80489ba <activate+101>
eflags 0x202 [ IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
Above, you’ll see the output from GDB when you ask it to print the register information. You’ll notice things like eax, ecx, edx and ebx, all general purpose registers that are being used.
For this post, however, take a look at esp and ebp. Esp is the pointer to the current stack frame. And esb is the base pointer. The way I think of it (and I hope I’m not wrong about it) is that the stack memory begins at esp and ends at ebp.
To display the memory of the stack, we can tell gdb to to print (arbitrarily) thirty hexadecimal 32-bit WORDs — starting at at the start of the frame:
(gdb) x/30x $esp
0xffffd5f0: 0x080eb200 0x4141000a 0x41414141 0x41414141
0xffffd600: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffd610: 0x41414141 0x41414141 0x00000041 0x080481b0
0xffffd620: 0x080eb00c 0x49656e69 0x0000001a 0x00000041
0xffffd630: 0x080bc70c 0x49656e69 0xffffd648 0x080489f4
0xffffd640: 0x080eb070 0xffffd660 0x00000000 0x08048c6e
0xffffd650: 0x080eb00c 0x49656e69 0x00000000 0x08048c6e
0xffffd660: 0x00000001 0xffffd714
What we see above is that the memory is printed started from 0xffffd5f0, which happens be the same as $esp when we looked at ‘info reg’. To make a Each line starts another ‘bank’ (in my head) of memory. The first row lists the four memory address: 0xffffd5f0, 0xffffd5f4, 0xffffd5f8 and 0xffffd5fc.
Following along to $ebp, the memory referenced at location 0xffffd638 would be “0xffffd648”.