IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Chaine de caractère corrompue par un malloc


Sujet :

C

  1. #1
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut Chaine de caractère corrompue par un malloc
    Bonsoir,

    Après avoir déclaré une chaine de caractère (la réservation mémoire, la mise à zéro et l'affectation fonctionnent sans problème, je peux l'afficher sans soucis), je fais un malloc pour une seconde chaine, mais cela semble corrompre ma chaine initiale:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     char *param1;
     char *param2
     
     param1 = (char*)malloc(1+nbadresse * sizeof(void*));
     memset(param1, 0, 1+nbadresse*sizeof(void*));
     
     //J'initialise la chaine ici
     //....
     
     printf("0 -> %s\n", param1); //Pas de soucis
     
     param2 = (char*)malloc(nb+strlen(code)+1);
     printf("1 -> %s\n", param1); //Ma chaine finis par un caractère différent et est coupée...
    D'où cela peut-il venir?
    Comment corriger ce problème?

    Merci d'avance

    @+
    Seeme

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par seeme Voir le message
    Après avoir déclaré une chaine de caractère (la réservation mémoire, la mise à zéro et l'affectation fonctionnent sans problème, je peux l'afficher sans soucis), je fais un malloc pour une seconde chaine, mais cela semble corrompre ma chaine initiale:
    1 - un malloc() ne peut pas corrompre une chaine de caractères (ou alors il y a eu un comportement indéfini avat son appel).
    2 - ton code est incomplet.
    3 - ceci fonctionne sans problèmes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main (void)
    {
       int nbadresse = 30;
       int nbNOP = 4;
     
       char shellcode[] = "hello world";
       char *param1;
       char *param2;
     
       param1 = malloc (1 + nbadresse * sizeof (void *));
       memset (param1, 0, 1 + nbadresse * sizeof (void *));
     
       strcpy (param1, "J'initialise la chaine ici");
     
       printf ("0 -> %s\n", param1); //Pas de soucis
     
       param2 = malloc (nbNOP + strlen (shellcode) + 1);
       printf ("1 -> %s\n", param1);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    0 -> J'initialise la chaine ici
    1 -> J'initialise la chaine ici
     
    Process returned 0 (0x0)   execution time : 0.021 s
    Press any key to continue.
    Mais comme j'ai du inventer ce qui manque; j'ai peut être pas commis tes erreurs...

    ceci est très louche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       param1 = malloc (1 + nbadresse * sizeof (void *));

  3. #3
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Voilà le code un peu plus complet (je ne peut pas mettre la totallité du code ici)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/wait.h>
     
    int main(int argc, char **argv) {
     
      int nb; // nombre
      char *param1; // param1 contient n fois l'adresse de retour
      char *param2;
     
      int adresse = 0;
      int nbadresse = 0;
      int i;
     
      char *prog = NULL; // nom du programme
     
      if (argc != 5) {
     
        printf("utilisation : ...");
        exit(1);
      }
     
      prog = argv[1];
     
     
      adresse = (int)strtol(argv[2],NULL,16);
      nbadresse = atoi(argv[3]);
      nb = atoi(argv[4]);
     
     
     
      // alloue param1, de taille 1+(nbadresse*taille d'une adresse)
      // met à zero tous les octets de param1 (cf. man memset)
     
     
      param1 = (char*)malloc(1+nbadresse * sizeof(void*));
      memset(param1, 0, 1+nbadresse*sizeof(void*));
     
      // rempli param1 avec nbadresse fois adresse
      /*
      for(i=0;i<nbadresse;i++) {
      	param1[i] = adresse;
      }
      */
     
    	i = 0;
           int nb;
     for(i=0; i<(8*nbadresse); i+=8){
      for(nb = 0; nb < 8; nb+=2){
        param1[i+nb] = argv[2][9-nb-1];
        param1[i+nb+1] = argv[2][9-nb];
     } 
    }
     
    printf("0 -> %s\n", param1);
    printf("1 -> %s\n", param1);
     
      // alloue param2, de taille 1+nb+taille du code
      // met à zero tous les octets de param2 (cf. man memset)
      /*
      param2 = malloc(1+nb+sizeof(code));
      memset(param2, 0, 1+nb+sizeof(code));
      */
     
      param2 = (char*)malloc(nb+strlen(code)+1);
    printf("2 -> %s\n", param1);
      memset(param2, 0, 1+nb+strlen(code+1));
     
     
     
      for(i=0;i<nb;i++) {
      	param2[i] = 'a';
      }
     
      memcpy(param2 + nb, code, strlen(code));
     
     
    printf("3 -> %s\n", param1);
     
      int  end = 0;
      int try = 1;
     
      int pid;
      int status;
     
     //....Ici on fork
      exit(0);
    }

    Le coup du char* vient de la source du prof, à l'origine, il utilisais un for comme ceci ensuite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int* ptr = (int*) param1;
      for(i=0;i<nbadresse;i++) {
      	ptr[i] = adresse;
      }
    Et ça ne posait pas de problème

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par seeme Voir le message
    Voilà le code un peu plus complet (je ne peut pas mettre la totallité du code ici)
    Déjà, ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
      prog = argv[1];
     
     
      adresse = (int)strtol(argv[2],NULL,16);
      nbadresse = atoi(argv[3]);
      nbNOP = atoi(argv[4]);
    C'est faux. Le nom du programme est en [0]

    Tous tes arguments de la ligne de commande sont décalés...

    Ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    utilisation : ...
    Process returned 1 (0x1)   execution time : 0.025 s
    Press any key to continue.
    ça n'aide pas beaucoup pour passer des arguments corrects...

  5. #5
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    prog correspond bien à argv[1], il ne désigne pas le nom du programme courant (argv[0]), mais le nom d'un autre programme (utilisé par un fork plus loin dans le programme.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par seeme Voir le message
    prog correspond bien à argv[1], il ne désigne pas le nom du programme courant (argv[0]), mais le nom d'un autre programme (utilisé par un fork plus loin dans le programme.
    OK. Donne un exemple de ligne de commande valide.

  7. #7
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./monprog cible 0xbff00104 3 10000

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par seeme Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./monprog cible 0xbff00104 3 10000
    OK. Après corrections mineures il reste ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    -------------- Build: Debug in hello ---------------
     
    Compiling: main.c
    Linking console executable: bin\Debug\hello.exe
    C:\dev\hello\main.c: In function `main':
    C:\dev\hello\main.c:69: error: `shellcode' undeclared (first use in this function)
    C:\dev\hello\main.c:69: error: (Each undeclared identifier is reported only once
    C:\dev\hello\main.c:69: error: for each function it appears in.)
    Process terminated with status 1 (0 minutes, 0 seconds)
    3 errors, 0 warnings
    Ensuite, il a un tas de code commenté. Je le retire ?

  9. #9
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Ce qui est commenté doit le rester normalement (le programme peut fonctionner d'une autre manière en fait).

    Mon output:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    seeme@mercury:~/Programation/Failles$ ./exploit concat 0xbff00104 3 10000
    0 -> 0401f0bf0401f0bf0401f0bf
    1 -> 0401f0bf0401f0bf0401f0bf
    2 -> 0401f0bf0401f0bf0401I'
    3 -> 0401f0bf0401f0bf0401I'
    Fils: 0401f0bf0401f0bf0401I'

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/11/2012, 03h11
  2. Réponses: 3
    Dernier message: 26/03/2012, 11h32
  3. [Chaines de caractères] commençant par un nombre
    Par sempire dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 13/05/2009, 18h30
  4. Réponses: 4
    Dernier message: 10/09/2008, 13h53
  5. Requete avec chaine de caractère commence par
    Par jazzes_dean dans le forum Langage SQL
    Réponses: 7
    Dernier message: 02/08/2004, 13h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo