将shell参数传递给mac osx上的c程序

时间:2012-08-03 21:54:24

标签: c macos shell

出于教育目的,我正在尝试运行一个使用缓冲区溢出来覆盖函数指针地址的程序。我已确定要使用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缓冲区。问题是这似乎没有将输出传递给a.out,因为argc总是1.我也试过

perl -e'print“aa \ xc0 \ x0c \ x00 \ x00 \ x01 \ x00 \ x00 \ x00 \ n”'> a.bin 猫a.bin - | ./a.out

和argc仍然是1。

我附上了我的程序副本,以便于查看。 还有一种更简单的方法可以将格式化的字节直接传递给c程序而不是使用perl,而无需更改程序的当前结构吗?

我可以这样做./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;
}

3 个答案:

答案 0 :(得分:2)

您将命令行参数与stdin混淆。你的命令:

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

将写入程序的标准输入。如果要执行与命令行参数相同的操作,请尝试:

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

请参阅:http://ss64.com/bash/xargs.html

答案 1 :(得分:1)

就像约翰所说的那样,你对stdin的论点感到困惑。要将程序的输出作为参数传递,您可以通过将命令替换包含在$(command)中来使用命令替换,因此对于您的示例,您应该执行

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

答案 2 :(得分:1)

使用bash,您可以这样做:

./a.out $'aa\xc0\x0c\x00\x00\x01\x00\x00\x00'