8

我想编写一个程序 Shellcode.c,它接受输入一个文本文件,其中包含由换行符分隔的 bash 命令,并执行文本文件中的每个命令:例如,文本文件将包含:

echo Hello World
mkdir goofy   
ls

我试过这个(只是为了开始练习其中一个 exec 函数):

#include <stdio.h>
#include <unistd.h>

void main() {
    char *name[3];

    name[0] = "echo";
    name[1] = "Hello World";
    name[2] = NULL;
    execvp("/bin/sh", name);
}

我得到,作为回报,

echo: Can't open Hello World

我被 execvp 函数卡住了,我哪里出错了?

4

3 回答 3

19

你这样做是错的。

第一个数组索引是程序的名称,如文档中所述

execv()、execvp() 和 execvpe() 函数提供了一个指向以 null 结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应该指向与正在执行的文件关联的文件名。指针数组必须以 NULL 指针终止。

此外,bash 并不期望像这样的自由格式参数,您需要告诉它您将使用以下-c选项传递命令:

所以,你需要:

name[0] = "sh";
name[1] = "-c";
name[2] = "echo hello world";
name[3] = NULL;
于 2013-01-03T14:43:28.583 回答
9

要在命令行上将脚本传递给 bash,您必须添加选项“-c”并将整个脚本作为单个字符串传递,即

#include <stdio.h>
#include <unistd.h>

void main() {
    char *name[] = {
        "/bin/bash",
        "-c",
        "echo 'Hello World'",
        NULL
    };
    execvp(name[0], name);
}
于 2013-01-03T14:44:04.597 回答
8

这里有很多问题:exec()函数族不执行多个程序 - 这些函数执行单个程序,并用新程序替换内存中当前正在运行的进程。您传递给的以空指针结尾的字符串数组应该execvp包含由. execvp

如果要执行多个程序,则需要遍历每一行并逐个执行程序。但是您不能使用execvp,因为它会立即将当前正在执行的进程(您的 C 程序)替换为通过 shell 执行的进程,这意味着您的 C 程序的其余部分将永远不会被执行。您需要学习如何fork()结合使用,execvp以便执行子进程。你首先调用fork()创建一个子进程,然后从你调用的子进程中调用execvpFork + Exec 是UNIX 环境中从父进程启动其他进程的常用策略。

于 2013-01-03T14:43:02.973 回答