[英]Execve invoking
我想通过execve在C程序中调用Shell:
#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
因为您没有发送以NULL结尾的参数列表。 你需要:
char* path[2];
path[0] = "/bin/sh";
path[1] = NULL;
int err = execve(path[0], path, NULL);
execve
的第二个参数定义为以NULL结尾的字符串列表,因此您不能简单地传递path
的地址。 它期望这样的数组,最后一个条目为NULL:
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;
}
尝试以下方法:
execl(path, path, NULL)
如果程序是脚本而不是过程映像文件,则exec系列功能将自动执行shell。 因此,您可以用脚本的路径名替换“ path”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.