首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Execve调用

Execve调用
EN

Stack Overflow用户
提问于 2009-12-24 05:56:35
回答 3查看 5.9K关注 0票数 1

我想通过execve在C程序中调用一个shell:

代码语言:javascript
复制
#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);
}

但是,输出结果是:

代码语言:javascript
复制
-1
Bad address
80485c0, bf816f4c
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-12-24 06:00:32

因为您不会发送以NULL结尾的参数列表。您需要:

代码语言:javascript
复制
char* path[2];
path[0] = "/bin/sh";
path[1] = NULL;
int err = execve(path[0], path, NULL);
票数 10
EN

Stack Overflow用户

发布于 2009-12-24 06:24:21

execve的第二个参数被定义为一个以NULL结尾的字符串列表,因此不能简单地传递path的地址。它需要一个这样的数组,最后一项为NULL:

代码语言:javascript
复制
arg[0] = "/bin/ls"
arg[1] = "-l"
arg[2] = "/usr/include/std*"
arg[3] = NULL

它失败的原因是指针错误,因为execve会查看path后面的每个单词来查找参数,并将每个单词视为指针,直到到达第一个0单词。由于path在堆栈上是独一无二的,因此它会尝试将堆栈之后内存中发生的任何垃圾解释为path以外的字符串指针。

解决方案很简单:您需要构造一个参数数组并添加一个NULL结束符(因为它的长度是可变的)。修复后的示例如下(注意了一些警告):

代码语言:javascript
复制
#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;
}
票数 5
EN

Stack Overflow用户

发布于 2009-12-24 06:08:08

试着这样做:

代码语言:javascript
复制
execl(path, path, NULL)

如果程序是脚本而不是进程映像文件,exec函数系列将自动执行shell。因此,您可以将"path“替换为脚本的路径名。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1955539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档