Reputation: 1086
I want to write a program Shellcode.c that accepts in input a text file, which contains bash commands separeted by newline, and executes every commands in the text file: for example, the text file will contain:
echo Hello World
mkdir goofy
ls
I tried this one (just to begin practicing with one of the exec functions):
#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);
}
I get, in return,
echo: Can't open Hello World
I'm stuck with the execvp function, where did I go wrong?
Upvotes: 8
Views: 35697
Reputation: 53289
Many problems here: The exec()
family of functions do not execute multiple programs - these functions execute a single program, and replace the currently running process in memory with the new program. The null-pointer-terminated array of strings you pass to execvp
is supposed to contain the command-line arguments to the program executed by execvp
.
If you want to execute multiple programs, you'll need to loop over each line and execute the programs one by one. But you can't use execvp
because that immediately replaces the currently executing process (your C program) with the process executed via the shell, meaning that the rest of your C program will never be executed. You need to learn how to use fork()
combined with execvp
so you can execute child processes. You first call fork()
to create a child process, and then from the child process you call execvp
. Fork + Exec is a common strategy in UNIX environments to launch other processes from a parent process.
Upvotes: 8
Reputation: 162164
To pass a script to bash on the command line you must add the option '-c' and pass the whole script as a single string, i.e.
#include <stdio.h>
#include <unistd.h>
void main() {
char *name[] = {
"/bin/bash",
"-c",
"echo 'Hello World'",
NULL
};
execvp(name[0], name);
}
Upvotes: 9
Reputation: 399703
You're doing it wrong.
The first array index is the name of the program, as explained in the docs:
The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.
Also, bash doesn't expect free-form argument like that, you need to tell it you're going to pass commands using the -c
option:
So, you need:
name[0] = "sh";
name[1] = "-c";
name[2] = "echo hello world";
name[3] = NULL;
Upvotes: 19