我想编写一个程序Shellcode.c,它在输入中接受一个文本文件,其中包含由换行符分隔的bash命令,并执行文本文件中的每个命令:例如,文本文件将包含:
echo Hello World
mkdir goofy
ls
Run Code Online (Sandbox Code Playgroud)
我试过这个(只是开始练习一个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);
}
Run Code Online (Sandbox Code Playgroud)
作为回报,我得到了
echo: Can't open Hello World
Run Code Online (Sandbox Code Playgroud)
我坚持使用execvp函数,我哪里出错了?
unw*_*ind 19
你这样做是错的.
第一个数组索引是程序的名称,如文档中所述:
execv(),execvp()和execvpe()函数提供指向以null结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表.按照惯例,第一个参数应指向与正在执行的文件关联的文件名.指针数组必须由NULL指针终止.
另外,bash不希望像这样的自由格式参数,你需要告诉它你将使用-c选项传递命令:
所以,你需要:
name[0] = "sh";
name[1] = "-c";
name[2] = "echo hello world";
name[3] = NULL;
Run Code Online (Sandbox Code Playgroud)
要在命令行上传递脚本bash,必须添加选项'-c'并将整个脚本作为单个字符串传递,即
#include <stdio.h>
#include <unistd.h>
void main() {
char *name[] = {
"/bin/bash",
"-c",
"echo 'Hello World'",
NULL
};
execvp(name[0], name);
}
Run Code Online (Sandbox Code Playgroud)
这里有许多问题:exec()函数族不执行多个程序 - 这些函数执行单个程序,并用新程序替换当前运行的内存进程.传递给空字符串的字符串数组execvp应该包含执行程序的命令行参数execvp.
如果要执行多个程序,则需要遍历每一行并逐个执行程序.但是你无法使用,execvp因为它会立即将当前正在执行的进程(你的C程序)替换为通过shell执行的进程,这意味着你的C程序的其余部分永远不会被执行.您需要学习如何fork()结合使用,execvp以便您可以执行子进程.您首先调用fork()创建子进程,然后从您调用的子进程调用execvp. Fork + Exec是 UNIX环境中的一种常见策略,用于从父进程启动其他进程.