Nuova piccola applicazione

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Nuova piccola applicazione

Messaggio 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)

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: Nuova piccola applicazione

Messaggio 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

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Nuova piccola applicazione

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggio 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 ???

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: Nuova piccola applicazione

Messaggio 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_.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Nuova piccola applicazione

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggio 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.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Nuova piccola applicazione

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

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

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Nuova piccola applicazione

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggio 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.

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: Nuova piccola applicazione

Messaggio 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.

Avatar utente
j0kers
Linux 2.x
Linux 2.x
Messaggi: 418
Iscritto il: dom 22 lug 2007, 1:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggio da j0kers »

Oppure

Codice: Seleziona tutto

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

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Nuova piccola applicazione

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Nuova piccola applicazione

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Rispondi