Question

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?

Was it helpful?

Solution

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;

OTHER TIPS

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top