简体   繁体   English

执行调用

[英]Execve invoking

I want to invoke a shell in C program by execve: 我想通过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);
}

However the output is: 但是输出是:

-1
Bad address
80485c0, bf816f4c

Because you aren't sending a NULL terminated list of arguments. 因为您没有发送以NULL结尾的参数列表。 You need: 你需要:

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

The second argument to execve is defined as being a NULL-terminated list of strings, so you can't simply pass the address of path . execve的第二个参数定义为以NULL结尾的字符串列表,因此您不能简单地传递path的地址。 It expects an array like this, with the final entry being NULL: 它期望这样的数组,最后一个条目为NULL:

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

The reason it was failing with a bad pointer is that execve would have been looking at each word following path to find the arguments, and treating each word as a pointer until it got to the first 0 word. 由于指针错误而失败的原因是, execve会一直在path后查找每个单词以查找参数,并将每个单词视为指针,直到到达第一个0单词为止。 Since path was alone on the stack, it would have been trying to interpret whatever garbage happened to be in memory after the stack beyond path as a string pointer. 由于path在堆栈上是一个单独的变量,因此它将一直试图将path之后的堆栈之后出现在内存中的任何垃圾解释为字符串指针。

The solution is simple: you need to construct an array of parameters and add a NULL terminator (since it is of variable length). 解决方案很简单:您需要构造一个参数数组并添加一个NULL终止符(因为它的长度可变)。 The fixed example is below (with a few warnings taken care of): 下面是固定的示例(注意了一些警告):

#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;
}

Try this instead: 尝试以下方法:

execl(path, path, NULL)

The exec family of functions will automatically execute a shell if the program is a script rather than a process image file. 如果程序是脚本而不是过程映像文件,则exec系列功能将自动执行shell。 So you might be able to replace "path" with the pathname of the script. 因此,您可以用脚本的路径名替换“ path”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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