Pagina 1 di 4

Nuova piccola applicazione

Inviato: sab giu 12, 2010 14:37
da j0kers
Salve ragazzi ecco una piccola applicazione in C che sfrutta il comando "ps"
per nascondere processi che non vogliamo visualizzare. Una volta applicazioni
simili venivano usate per nascondere backdoors o trojan agli amministratori.
Legge i processi da nascondere in un file chiamato "proc" presente nella
directory dell'applicazione.
Passiamo subito al codice:

Codice: Seleziona tutto

/* Nasconde i processi presenti nel file locale "proc".
 * Dopo che l'utente lancia il comando "ps" per
 * visualizzare i processi attivi, esso legge nel
 * file "proc" se ci sono elementi da nascondere
 * e li nasconde usando il comando bash "grep -v".
 * Versione di prova beta 0.1.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50


void main(int argc, char **argv[]){
   // Variabili
   FILE *fp=fopen("proc","r");   // Puntatore al file
   char buffer[MAX];           // Buffer di lettura dal file
   char lettura_file[MAX];     // Contiene il valore del file
   char comando_stringa[MAX];  // Contiene il valore " | grep -e "
   char comando_finale[MAX];    // Contiene il comando finale da eseguire
    int cont=0;

    // Inizializzo la stringa
   comando_stringa[0]='\0';
   strncat(comando_stringa," | grep ",8);
    // Leggo dal file una riga
    // di MAX caratteri e la salvo in buffer.
   while(fgets(buffer,MAX,fp)!=NULL){
        // Ciclo per resettare la stringa altrimenti
        // lettura_file attuale conterrà anche i caratteri
        // della lettura precedente.
        for(cont=0;cont<MAX;cont++)
            lettura_file[cont]='\0';
        // buffer contiene anche il carattere di fine stringa "\n"
        // che a noi non serve quindi copio buffer - 1 in lettura_file
        strncpy(lettura_file,buffer,strlen(buffer)-1);
        strncat(comando_stringa," -e ",4);
        // Procedo con la concatenazione delle stringhe
        strncat(comando_stringa,lettura_file,strlen(lettura_file));
   }
    comando_finale[0]='\0';
    if(argc==2){
        strncat(comando_finale,"/bin/ps ",8);
        strncat(comando_finale,argv[1],strlen(argv[1]));
        strncat(comando_finale,comando_stringa,strlen(comando_stringa));
        strncat(comando_finale," -e ps -v\n",11);
    }else{
        strncat(comando_finale,"/bin/ps",7);
        strncat(comando_finale,comando_stringa,strlen(comando_stringa));
        strncat(comando_finale," -e ps -v\n",11);
    }
    system(comando_finale);
//    printf("Comando: %s",comando_finale);
    return;
}

Sicuramente non è perfettissima, infatti ho dovuto mettere questo ciclo

Codice: Seleziona tutto

        for(cont=0;cont<MAX;cont++)
            lettura_file[cont]='\0';

altrimenti se ad esempio nel file proc erano presenti queste righe

Codice: Seleziona tutto

cairo
conky
code

l'ultima lettura "code" mi usciva "codey" mi prendeva anche il carattere della penultima lettura.
Se avete qualche altra idea per sostituire quel for sarei grato di modificarlo.
Piccola applicazione per smanettare un pò con la programmazione C.
Grazie a tutti anticipatamente accetto qualsiasi consiglio 8)

Re: Nuova piccola applicazione

Inviato: sab giu 12, 2010 16:08
da Mario Vanoni
#define MAX 50
metti un quadrato di 2, 96/128/256 o meglio subito 1024,
se il programma evolve non ti trovi errori strani in futuro,
con le macchine odierne non e` piu` un lusso.

Non usare vocali accentate nei commenti,
e nemmeno casomai in error messages,
illegibili per chi usa macchine US-ASCII pure.

Compila denunciando 3 errori;

Codice: Seleziona tutto

root@va2:~# gcc -O -s -static -o ps2 test.c
test.c: In function 'main':
test.c:44: warning: passing argument 1 of 'strlen' from incompatible pointer type
test.c:44: warning: passing argument 2 of '__builtin_strncat' from incompatible pointer type
test.c:14: warning: return type of 'main' is not 'int'
root@va2:~#

poi da un Segmentation fault
echo $? dice 139

Re: Nuova piccola applicazione

Inviato: sab giu 12, 2010 16:21
da targzeta
Scusa, non voglio sembrare arrogante anche perchè io poi non sono tutto sto programmatore, ma chiunque ne capisce un minimo non può fare altro che inorridire davanti a questo codice :lol:. Un buon manuale di C potrebbe aiutare in questi casi....se letto tutto ovviamente 8)

Emanuele

Re: Nuova piccola applicazione

Inviato: sab giu 12, 2010 18:31
da j0kers
Behh sono esercizi semplici di programmazione.Ho sempre programmato in basic (vb6 o gambas) mi sto avvicinando da poco alle sintasi del c.
comunque quei messaggi sono dei warning non errori.
poi da un Segmentation fault
echo $? dice 139


questa non l'ho capita...Va in fault ???

Re: Nuova piccola applicazione

Inviato: sab giu 12, 2010 20:40
da Mario Vanoni
j0kers ha scritto:Behh sono esercizi semplici di programmazione.Ho sempre programmato in basic (vb6 o gambas) mi sto avvicinando da poco alle sintasi del c.
comunque quei messaggi sono dei warning non errori.
poi da un Segmentation fault
echo $? dice 139


questa non l'ho capita...Va in fault ???

I warnings _sono_ errori gravi di programmazione,
un programma pulito _non_ ne ha!

Dichiari void main(... e finisci con un return;
come dice bene Emanuele "Un buon manuale di C potrebbe aiutare in questi casi....se letto tutto ovviamente"

Segmentation fault significa che il programma non e` eseguibile, morto alla chiamata,
qui non importa quale compilatore usi, il programma e` _marcio_.

Re: Nuova piccola applicazione

Inviato: sab giu 12, 2010 21:18
da targzeta
Bene, visto che fortunatamente il mio primo intervento non l'hai preso male (ti chiedo scusa se sono sembrato arrogantello) e visto che ho un po' di tempo ti dico due cose:
  • j0kers ha scritto:...

    Codice: Seleziona tutto

    FILE *fp=fopen("proc","r");   // Puntatore al file
    è se il file non esiste?
  • j0kers ha scritto:...

    Codice: Seleziona tutto

     for(cont=0;cont<MAX;cont++)
                lettura_file[cont]='\0';

    // buffer contiene anche il carattere di fine stringa "\n"
    ...
    strncpy(lettura_file,buffer,strlen(buffer)-1);
    strncat(comando_stringa," -e ",4);[/code]
    se devi copiare/concatenare una stringa intera non ti servono le "strn" ma le "str" (quindi strcpy() e strcat()). Inoltre il carattere di fine sringa NON è il '\n' ma il '\0'. E ancora, non serve azzerare il buffer (tra l'altro per questo guarda memset(3)) ti basta mettere il '\0' alla fine .
  • Ti prendi tre buffer quando per quello che vuoi fare te ne basta solo uno (e con molto meno codice), il segfault ce l'hai perchè tutti i buffer sono lunghi 50 byte ma tu ne riempi due senza mai controllare il buffer overflow. Senza contare che come ho già detto non fai nessun controllo sulla fopen() e quindi se il flie non esiste dovresti avere un segfault alla prima fgets() (ma non ne sono convinto).

Emanuele

Re: Nuova piccola applicazione

Inviato: sab giu 12, 2010 23:48
da j0kers
Allora rispondo un pò a tutti:

Per Mario Vanoni: se i warning fossero errori gravissimi il sorgente non verrebbe compilato
inoltre il programma non va in segmentation fault (almeno a me funziona).

Per spina: non ho fatto caso ai commenti e per quanto riguarda l'fopen ho risolto poco dopo. Per quanto riguarda le stringhe
tu come gestiresti una cosa del genere: ps -aef | grep -e 1 -e 2 -e 3 -e ... -v
Dove 1 2 e 3 sono letti da un file e il parametro -aef è dato come argomento
Il tutto usando un solo buffer.

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 9:46
da targzeta

Codice: Seleziona tutto

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

int
main()
{
  char *cmds[]=
    {
      "cairo\n",
      "conky\n",
      "code\n"
    };
  int i, buff_size = 64;
  char *buff;

  if ( (buff = malloc(buff_size)) == NULL )
    return -1;

  strcpy(buff, "ps -aef | grep -v");

  for ( i=0; i < 3; i++ )
    {
      while ( strlen(buff) + strlen(cmds[i]) + 4 >= buff_size )
          if ( (buff = realloc(buff, buff_size *= 2)) == NULL )
            return -1;

      strcat(buff, " -e ");
      strcat(buff, cmds[i]);

      buff[strlen(buff) - 1] = '\0';
    }

  printf("%s", buff);

  return 0;
}
basta adattarla a leggere dal file invece che dall'array 8)

Emanuele

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 10:04
da j0kers
Tu hai messo staticamente

Codice: Seleziona tutto

  char *cmds[]=
    {
      "cairo\n",
      "conky\n",
      "code\n"
    };

e se voglio nascondere altri processi ? Cambio ogni volta sorgente? Oppure se voglio passare a ps
parametri diversi da "-aef" ?
comunque vi posto la versione 0.2 decisamente migliorata, e non da errori di warnings.

Codice: Seleziona tutto

/*  Semplice applicazione che nasconde i processi attivi
    visibili con il comando ps.
    Funzionamento:
        Legge i processi dal file "proc" presente nella
        directory dell'applicazione e li nasconde al
        comando ps.
    Esempio:
        Se il file "proc" contiene questi processi:

            conky
            cairo
            firefox

        quando verrà eseguito il comando ps per visualizzare
        i processi attivi, questi non verranno visualizzati.

    Versione beta 0.2
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1024

int main(int argc, char *argv[]){
   // Variabili
   FILE *fp;                          // Puntatore al file.
   char buffer[MAX];                   // Buffer di lettura dal file.
   char lettura_file[MAX];             // Contiene il valore letto dal file.
   char comando[MAX]={"/bin/ps "};     // Contiene il comando da eseguire.

    // Controllo gli argomenti passati se sono piu di 1
    // lancia direttamente il comando ps.
    if(argc==2){
        strcat(comando,argv[1]);
        strcat(comando," | grep -e ps -e grep");
    }else
        strcat(comando,"| grep -e ps -e grep");
    // Apro il file in lettura e controllo se esso esiste.
    fp=fopen("proc","r");
    if(fp==0)
        printf("Errore apertura file!\n");
    // Leggo dal buffer i valori del file e li copio in
    // lettura_file senza il carattere di nuova linea
   while(fgets(buffer,MAX,fp)!=NULL){
       // Resetto la stringa lettura_file
       memset(lettura_file,'\0',MAX);
       // Concateno il comando
        strcat(comando," -e ");
        strncpy(lettura_file,buffer,strlen(buffer)-1);
        strcat(comando,lettura_file);
   }
   strcat(comando," -v");
   // Lancio il comando
   system(comando);
    return 0;
}

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 10:27
da targzeta
j0kers ha scritto:...e se voglio nascondere altri processi ? Cambio ogni volta sorgente?
Cos'è che non ti è chiaro di:
spina ha scritto:basta adattarla a leggere dal file invece che dall'array


j0kers ha scritto:...Oppure se voglio passare a ps parametri diversi da "-aef" ?
Se non sai adattare il mio codice per gestire anche queste semplici situazioni allora è anche peggio di quello che pensavo.

j0kers ha scritto:...comunque vi posto la versione 0.2 ...
che è brutta più o meno come l'altra solo con qualche warning in meno, fatto sta che ti va in segfault ugualmente.
Puoi anche inventarti cento soluzioni più o meno bacate e funzionanti, ma fai prima a leggerti un buon manuale di C....ovviamente per intero.

Non voglio fare il maestro delle palle mie, però se posti qualcosa su internet questa vi ci resta e se qualcuno non fa notare che ci sono forti errori di programmazione/progettazione magari può anche venir presa per buona.

Spero che mi capisci,
Emanuele

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 13:04
da j0kers
Certo capisco il tuo discorso. Pensavo di aver postato qualcosa di carino, ma alla fine non è stato così.
comunque sulla mia macchina non va in fault.

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 14:20
da Mario Vanoni
j0kers ha scritto:Certo capisco il tuo discorso. Pensavo di aver postato qualcosa di carino, ma alla fine non è stato così.
comunque sulla mia macchina non va in fault.

Codice: Seleziona tutto

root@va2:~# ps2
Errore apertura file!
Segmentation fault
root@va2:~# echo $?
139
root@va2:~#

Tipico errore di "non programmazione" programmato!

Codice: Seleziona tutto

    fp=fopen("proc","r");
    if(fp==0)
        printf("Errore apertura file!\n");

a) errori vanno _sempre_ su stderr
b) il programma _deve_ terminare se riscontra un errore

Codice: Seleziona tutto

    fp=fopen("proc","r");
    if(fp==0)
    {
        fprintf(stderr, "Errore apertura file!\n");
        exit(EXIT_FAILURE);
    }

io risparmio spazio e tempo dall'epoca di AT&T UNIX SVR2 con

Codice: Seleziona tutto

    fp=fopen("proc","r");
    if(fp==0)
        exit(fprintf(stderr, "Errore apertura file!\n"));

In caso di errore il programma ritorna sicuramente non zero.

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 14:34
da j0kers
Oppure

Codice: Seleziona tutto

if( (fp=fopen("proc","r"))==NULL)
      exit(fprintf(stderr, "Errore apertura file!\n"));

Giusto ?

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 14:36
da targzeta
j0kers ha scritto:...comunque sulla mia macchina non va in fault.
Beh, se funziona solo sulla tua macchina non è comunque il massimo no? I problemi a mio avviso sono concettuali, ecco perchè ti ho suggerito la lettura di un libro, non certo perchè voglio fare lo sborone. Comunque ti avevo già scritto il perchè dei segfault:
spina ha scritto:...il segfault ce l'hai perchè tutti i buffer sono lunghi 50 byte ma tu ne riempi due senza mai controllare il buffer overflow. Senza contare che come ho già detto non fai nessun controllo sulla fopen() e quindi se il flie non esiste dovresti avere un segfault alla prima fgets() (ma non ne sono convinto)

Ergo:
  • controlla sembre il buffer overflow (se l'array è grande 50 non ci puoi scrivere 51, perchè nonostante possa funzionare c'è comunque un errore).
  • controlla sempre l'esito di una chiamata di sistema, notificare l'assenza del file non serve se non gestisci la situazione.
E ti avevo anche scritto:
spina ha scritto:...non serve azzerare il buffer (tra l'altro per questo guarda memset(3)) ti basta mettere il '\0' alla fine.
Ergo non azzerare il buffer, semplicemente mettici un '/0' alla fine.

Emanuele

Re: Nuova piccola applicazione

Inviato: dom giu 13, 2010 14:41
da targzeta
j0kers ha scritto:Oppure

Codice: Seleziona tutto

if( (fp=fopen("proc","r"))==NULL)
      exit(fprintf(stderr, "Errore apertura file!\n"));

Giusto ?
Questo codice secondo me è meglio di quello scritto da Mario perchè anche se NULL vale 0 la fopen ritorna NULL e non 0. Io comunque non trovo corretto l'exit sulla fprintf() perchè un comando dovrebbe uscire con un codice di errore specifico mentre qui si esce con il numero di caratteri stampati dalla fprintf()...ma queste sono solo sottigliezze, di certo non ti avrei detto per questi dettagli.

Emanuele