2009-12-23 59 views
1

我想的execve调用在C程序一个shell:的execve调用

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

main() 
{ 
     char* path = "/bin/sh"; 
     int err = execve(path, &path, NULL); 
     printf("%d\n", err); 
     printf("%s\n", strerror(errno)); 
     printf("%x, %x\n", path, &path); 
} 

但是输出是:

-1 
Bad address 
80485c0, bf816f4c 

回答

10

因为你是不是发送NULL结束的参数列表。 您需要:

char* path[2]; 
path[0] = "/bin/sh"; 
path[1] = NULL; 
int err = execve(path[0], path, NULL); 
0

试试这个:如果程序是一个脚本,而不是一个进程镜像文件

execl(path, path, NULL) 

的功能exec类会自动执行shell。所以你可以用脚本的路径名代替“path”。

5

execve的第二个参数被定义为以NULL结尾的字符串列表,因此您不能简单地传递path的地址。该公司预计像这样的数组,最后进入被空:

arg[0] = "/bin/ls" 
arg[1] = "-l" 
arg[2] = "/usr/include/std*" 
arg[3] = NULL 

这是一个坏的指针失败的原因是execve就一直在看每一个字下面path找到论据,并且把每个字作为指针,直到它到达第一个0字。由于path独自一人在堆栈上,它将试图解释堆栈后发生在内存中的任何垃圾,超出path作为字符串指针。

解决方案很简单:您需要构造一个参数数组并添加一个NULL终结符(因为它的长度可变)。固定的例子如下(有几个警告照顾):

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    char* path[] = { "/bin/sh", NULL }; 

    int err = execve(path[0], path, NULL); 

    printf("%d\n", err); 
    printf("%s\n", strerror(errno)); 
    printf("%p, %p\n", path, &path); 

    return 0; 
}