C — Выполнение команд Bash с помощью Execvp

Я хочу написать программу 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, где я ошибся?


person elmazzun    schedule 03.01.2013    source источник
comment
Что происходит с name[0] = /bin/sh; имя[1] = эхо; имя[2] = Привет, мир; имя[3]=НОЛЬ?   -  person mpez0    schedule 03.01.2013


Ответы (3)


Ты делаешь это неправильно.

Первый индекс массива — это имя программы, как объяснено в документации:

Функции execv(), execvp() и execvpe() предоставляют массив указателей на строки с завершающим нулем, представляющие список аргументов, доступных для новой программы. Первый аргумент по соглашению должен указывать на имя файла, связанного с исполняемым файлом. Массив указателей должен заканчиваться указателем NULL.

Кроме того, bash не ожидает такого аргумента в произвольной форме, вам нужно сообщить ему, что вы собираетесь передавать команды, используя параметр -c:

Итак, вам нужно:

name[0] = "sh";
name[1] = "-c";
name[2] = "echo hello world";
name[3] = NULL;
person unwind    schedule 03.01.2013
comment
Как насчет выполнения более одной команды, например echo 'hello world', затем ls - person Rahul; 09.12.2016

Чтобы передать скрипт в bash в командной строке, вы должны добавить параметр «-c» и передать весь скрипт в виде одной строки, т.е.

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

void main() {
    char *name[] = {
        "/bin/bash",
        "-c",
        "echo 'Hello World'",
        NULL
    };
    execvp(name[0], name);
}
person datenwolf    schedule 03.01.2013

Здесь много проблем: семейство функций exec() не выполняется. несколько программ — эти функции выполняют одну программу и заменяют текущий процесс в памяти новой программой. Массив строк, заканчивающийся нулевым указателем, который вы передаете execvp, должен содержать аргументы командной строки для программы, выполняемой execvp.

Если вы хотите выполнить несколько программ, вам нужно перебрать каждую строку и выполнить программы одну за другой. Но вы не можете использовать execvp, потому что это немедленно заменяет текущий исполняемый процесс (вашу программу C) процессом, выполняемым через оболочку, а это означает, что остальная часть вашей программы C никогда не будет выполнена. Вам нужно научиться использовать fork() в сочетании с execvp, поэтому вы можете выполнять дочерние процессы. Сначала вы вызываете fork() для создания дочернего процесса, а затем из дочернего процесса вызываете execvp. Fork + Exec — распространенная стратегия в средах UNIX для запуска других процессов из родительского процесса.

person Charles Salvia    schedule 03.01.2013
comment
Итак, если мой текстовый файл похож на предыдущий: echo Hello World mkdir goofy ls и содержит 3 строки, я разветвлю 3 дочерних процесса и запущу execvp в каждом из них. Верно? - person elmazzun; 03.01.2013