繁体   English   中英

执行调用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM