Repository 32bit  Forum
Repository 64bit  Wiki

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.

Nuova piccola applicazione

Messaggioda j0kers » sab giu 12, 2010 13:37

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)
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda Mario Vanoni » sab giu 12, 2010 15:08

#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
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: Nuova piccola applicazione

Messaggioda targzeta » sab giu 12, 2010 15:21

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6142
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Nuova piccola applicazione

Messaggioda j0kers » sab giu 12, 2010 17:31

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 ???
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda Mario Vanoni » sab giu 12, 2010 19:40

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_.
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: Nuova piccola applicazione

Messaggioda targzeta » sab giu 12, 2010 20:18

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6142
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Nuova piccola applicazione

Messaggioda j0kers » sab giu 12, 2010 22:48

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
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda targzeta » dom giu 13, 2010 8:46

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6142
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Nuova piccola applicazione

Messaggioda j0kers » dom giu 13, 2010 9:04

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
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda targzeta » dom giu 13, 2010 9:27

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6142
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Nuova piccola applicazione

Messaggioda j0kers » dom giu 13, 2010 12:04

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.
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda Mario Vanoni » dom giu 13, 2010 13:20

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.
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: Nuova piccola applicazione

Messaggioda j0kers » dom giu 13, 2010 13:34

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

Giusto ?
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda targzeta » dom giu 13, 2010 13:36

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6142
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Nuova piccola applicazione

Messaggioda targzeta » dom giu 13, 2010 13:41

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6142
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Prossimo

Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite