#define _GNU_SOURCE /* for RTLD_NEXT */ #include #include #include #include /* get address of various functions compile: gcc stack_rop.c -o stack_rop -z noexecstack -fno-stack-protector -ldl Don't forget the -ldl flag at the end! run: ./stack_rop */ // For the purpose of experiment void bar() { static int i = 0; printf("The function bar() is invoked %d times!\n", ++i); } int foo(char *str) { char buffer[100]; unsigned int *ebp; // Copy ebp into framep asm("movl %%ebp, %0" : "=r" (ebp)); /* print out information for experiment purpose */ printf("buffer[] address: 0x%.8x\n", (unsigned)buffer); printf("ebp address: 0x%.8x\n", (unsigned)ebp); printf("ebp - buffer is: %i\n", (unsigned)ebp - (unsigned)buffer); printf("system addr: %p\n",dlsym(RTLD_NEXT, "system")); printf("exit addr: %p\n",dlsym(RTLD_NEXT, "exit")); printf("bar function address: 0x%.8x\n",(unsigned)bar); /* The following statement has a buffer overflow problem */ strcpy(buffer, str); return 1; } // For the purpose of experiment void baz(int x) { printf("The value of baz()'s argument: 0x%.8X\n", x); } int main(int argc, char **argv) { char str[2000]; FILE *badfile; char *shell = (char *)getenv("MYSHELL"); if(shell){ printf("The '%s' string's address: 0x%.8x\n", shell, (unsigned int)shell); } badfile = fopen("badfile", "r"); fread(str, sizeof(char), 2000, badfile); foo(str); printf("Returned Properly\n"); return 1; }