Reputation: 103
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;
}
Upvotes: 0
Views: 246
Reputation:
With bash you can just do:
./a.out $'aa\xc0\x0c\x00\x00\x01\x00\x00\x00'
Upvotes: 1
Reputation: 4457
Like John says, you're confusing arguments with stdin. To pass the output of a program as an argument you can use command substitution by wrapping it in $(command)
, so for your example you should do
./a.out $(perl -e 'print "aa\xc0\x0c\x00\x00\x01\x00\x00\x00\"')
Upvotes: 1
Reputation: 486
You're confusing command-line arguments with stdin. Your command:
perl -e 'print "aa\xc0\x0c\x00\x00\x01\x00\x00\x00\"'| ./a.out
will 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.out
see: http://ss64.com/bash/xargs.html
Upvotes: 2