Jak użyć programu C do uruchomienia polecenia na terminalu?


11

Chcę stworzyć program w języku C, który pozwoliłby mi uruchomić polecenie w terminalu.

Zrobiłem program w skrypcie powłoki, który dałby mi ip każdej strony internetowej, która jest otwarta w mojej przeglądarce. Ten skrypt powłoki jest wykonywany przez wpisanie tego polecenia w terminalu:

sudo tcpdump -n dst port 80 -i eth

Mój profesor kazał mi stworzyć program w języku C, który otworzyłby terminal i wprowadził to polecenie, a następnie działałby mój skrypt powłoki.

Powiedz mi, jak stworzyć taki program.

Odpowiedzi:


8

możesz użyć funkcji system () dostępnej w stdlib.h do uruchamiania poleceń.

OPIS

system () wykonuje polecenie określone w ciągu poprzez wywołanie ciągu / bin / sh -c i powraca po zakończeniu polecenia. Podczas wykonywania polecenia SIGCHLD zostanie zablokowany, a SIGINT i SIGQUIT zostaną zignorowane.

Możesz przeczytać więcej na ten temat tutaj http://linux.about.com/library/cmd/blcmdl3_system.htm


Jest to z pewnością jeden sposób, ale prawdopodobnie nie chcesz uruchamiać poleceń z programu ac, zamiast tego większość programów Linuksa ma bibliotekę, która może bezpośrednio kodować programy. Na przykład ssh może używać libssh . Zwykle istnieje bardzo ograniczony powód, aby uruchamiać polecenia systemowe z kodu. Jeśli często to robisz, prawie na pewno robisz coś złego.
coteyr

Zrobiłem program w C w ten sposób
Tehseen Malik,

4

Witaj, napiszę dla ciebie przykładowy kod, wyjaśnię go i mam nadzieję, że to ci pomoże. prototyp funkcji jest podobny do:

int system (const char * cmd);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CMN_LEN 100

int main(int argc, char *argv[])
{
    char cmd[MAX_CMN_LEN] = "", **p;

    if (argc < 2) /*no command specified*/
    {
        fprintf(stderr, "Usage: ./program_name terminal_command ...");
        exit(EXIT_FAILURE);
    }
    else
    {
        strcat(cmd, argv[1]);
        for (p = &argv[2]; *p; p++)
        {
            strcat(cmd, " ");
            strcat(cmd, *p);
        }
        system(cmd);
    }

    return 0;
}

1). otwórz terminal i skompiluj program

2). uruchom go (na przykład w Ubuntu) ./nazwa_programu nazwa_programu -wszystko - cokolwiek

przykład: ./a.out locale -a

ten przykład wyświetla wszystkie ustawienia narodowe obsługiwane przez mój kompilator, którym jest gcc.

więcej informacji:

p to poniter do wskaźnika na char (jak argv jest) p = & argv [2], wskazuje na dowolny ciąg i cat wszystko-wszystko na mój ciąg cmd wychodzę z pętli, gdy * p wskazuje na NULL spójrz na to: -> użyję tego symbolu, aby powiedzieć punkty (nie mylić go z operatorem wyboru prawej strzałki).

argv [0] -> nazwa_programu

argv [1] -> nazwa_ polecenia (w tym przykładzie nazwa polecenia będzie ustawieniem regionalnym, ale zamiast tego wprowadź polecenie, które chcesz sprawdzić)

argv [2] -> -anything (w tym przykładzie -a, czyli wszystkie ustawienia narodowe)

argv [3] -> NULL (w tym przykładzie powoduje to zamknięcie pętli)

ok, to wszystko, tak myślę.


Upewnij się, że nie używasz tego jako pliku wykonywalnego setuid, ponieważ ma oczywisty exploit przepełnienia bufora.
Martin

0

Zakładam, że chodzi tu o użycie pliku binarnego z setuid-root do zastąpienia sudo, a nie tylko o wykonanie dowolnego polecenia, więc dołączę inne części rozwiązania.

Ze względów bezpieczeństwa unikamy system (), ponieważ można go przejąć.

Po kompilacji zainstaluj wynikowy plik binarny jako setuid-root.

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

int main (int argc, char ** argv) {
    if (argc> 2) {fputs ("too many args \ n", stderr); zwróć EX_USAGE; }
    if (argc> 1 && argv [1] [0] == '-') {fputs („bez opcji dozwolone \ n”, stderr); zwróć EX_USAGE; }
    if (geteuid ()! = 0) {fputs ("niepoprawnie zainstalowany jako root setuid \ n", stderr); zwróć EX_UNAVAILABLE; }
    if (setuid (0) 1) p [6] = argv [1];

    / * Jeśli wszystko pójdzie dobrze, execv nie zwróci
     * (ponieważ ten program zostanie zastąpiony przez tcpdump) * /
    execv (p0, p);
    / * jeśli tutaj dotrzemy, to wykonanie polecenia execv nie powiodło się * /

    perror (p0);
    zwraca EX_OSFILE;
}

jeśli zapisałeś to jako foo.ci chcesz zainstalować jako /usr/local/sbin/foo, uruchom:

zrób foo && install -o root -m 4511 foo / usr / local / sbin / foo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.