教育目的で、バッファオーバーフローを使用して関数ポインタアドレスを上書きするプログラムを実行しようとしています。nmを使用して上書きする関数ポインタの場所を決定しました。次に、新しい関数ポインタのアドレスをargvに渡します。使おうとしています
perl -e'print "aa \ xc0 \ x0c \ x00 \ x00 \ x01 \ x00 \ x00 \ x00 \"' | ./a.out
ここで、\ xc0 \ x0c \ x00 \ x00 \ x01 \ x00 \ x00 \ x00 \は、新しい関数ポインターのアドレスのリトルエンディアンであり、aaはcharバッファーを埋めるためだけのものです。問題は、argcが常に1であるため、これが出力をa.outにパイプしていないように見えることです。私も試しました
perl -e'print "aa \ xc0 \ x0c \ x00 \ x00 \ x01 \ x00 \ x00 \ x00 \ n"> a.bin cat a.bin-| ./a.out
argcはまだ1です。
簡単にフォローできるように、プログラムのコピーを添付しました。また、プログラムの現在の構造を変更せずに、perlを使用する代わりにフォーマットされたバイトをacプログラムに直接渡す簡単な方法はありますか?
./a.outを実行して実行することはできますか?
ありがとう
#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;
}