I’m trying, for educational purposes, to run a program which uses a buffer overflow to overwrite a function pointer address. I have determined the location of the function pointer I want to overwrite using nm. I then want to pass the address of the new function pointer to argv. I’m trying to use
perl -e ‘print “aa\xc0\x0c\x00\x00\x01\x00\x00\x00\”‘| ./a.out
where \xc0\x0c\x00\x00\x01\x00\x00\x00\ is little endian for the address of the new function pointer and aa is just to fill the char buffer. The problem is this doesn’t seem to pipe the output to a.out as argc is always 1. I also tried
perl -e ‘print “aa\xc0\x0c\x00\x00\x01\x00\x00\x00\n”‘ > a.bin
cat a.bin – | ./a.out
and argc is still 1.
I attached a copy of my program for easier following.
Also is there an easier way to pass formatted bytes directly to a c program instead of using perl, without changing the current structure of my program?
so can I do ./a.out and have it run?
Thanks
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct user_s{
char name[2];
void (*print_name)();
}user;
user a;
void print_name1(){
printf("hello\n");
}
void print_name2(){
printf("hi\n");
}
void usage(char * msg){
printf("usage: %s <name>\n", msg);
}
void fill_name (char * name_to_fill, char *filler){
int i, len;
len = strlen(filler);
printf("length of filler is %d\n", len);
for (i = 0 ; i < len; i ++){
*(name_to_fill + i) = *(filler+i);
}
}
int main(int argc, char * argv[]){
printf("argc = %d",argc);
if (argc != 2){
usage(argv[0]);
return 0;
}
a.print_name = print_name1;
a.print_name();
fill_name(a.name, argv[1]);
a.print_name();
return 1;
}
You’re confusing command-line arguments with stdin. Your command:
perl -e 'print "aa\xc0\x0c\x00\x00\x01\x00\x00\x00\"'| ./a.outwill write to the program’s stdin. If you want to do the same thing as a command-line argument, try:
perl -e 'print "aa\xc0\x0c\x00\x00\x01\x00\x00\x00\"'| xargs ./a.outsee: http://ss64.com/bash/xargs.html