Partage
  • Partager sur Facebook
  • Partager sur Twitter

Sécurité langage C

Problème des adresses

Sujet résolu
    11 février 2019 à 21:55:13

    Salut à tous !

    J'ai un petit problème,

    j'arrive pas à trouver la bonne réponse pour cette question:

    "Quelle entier vous devez donner comme choix au programme pour que ptrs[s] lise la
    valeur de la variable locale p ? Vous devez effectuer des calculs et prendre en compte la taille en
    octets des éléments du tableau ptrs (pointeurs de fonction). Vous avez obtenu la bonne réponse
    si le message affiché est Achievement unlocked!. La réponse doit être un entier positif"

    ça me rend fou vraiment fou,
    sachant que  j'ai obtenu avec gdb les adresses suivantes :

    ptrs   : 0x565580a8 :1448444072
    ptrs[0]: 0x565580a8 :1448444072
    ptrs[1]: 0x565580ac :1448444076
    ptrs[2]: 0x565580b0 :1448444080
                       +4
                       +4
                       +4
                       +4
                       +4
                       .
                       .
                       . ------------>au total 711627655 ajout de 4 , donc ptrs[2 + 711627655]  (ça marche pas : seg fault)
                       .
                       .
                       .
                       .
                       .
                       .
    p      : 0xffffcecc :4294954700

    voici le code

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <time.h>
    
    /** Macros */
    
    #define DATA_SIZE 128
    
    /** Types */
    
    typedef struct _WisdomList {
      struct  _WisdomList *next;
      char    data[DATA_SIZE];
    } WisdomList;
    
    typedef void (*fptr)(void);
    
    /** Initialized global: list of wisdoms */
    
    struct _WisdomList  *head = NULL;
    
    /** Initialized globals: messages */
    
    char greeting[] = "Hello there\n1 Receive wisdom\n2 Add wisdom\nq Quit\nSelection >";
    char prompt[] = "Enter file name with some wisdom\n";
    char pat[] = "Achievement unlocked!\n";
    char secret[] = "secret key";
    
    /** Functions: not to use, reveal secrets */
    
    void write_secret(void) {
      size_t r = fwrite(secret, sizeof(char), sizeof(secret), stdout);
      if (r == 0)
        perror("write secret");
      return;
    }
    
    void pat_on_back(void) {
      size_t r = fwrite(pat, sizeof(char), sizeof(pat), stdout);
      if (r == 0)
        perror("unlocked");
      return;
    }
    
    /** Functions: operations on the list of wisdoms */
    
    void get_wisdom(void) {
      char   buf[] = "no wisdom\n";
      size_t r;
      if(head == NULL) {
        r = fwrite(buf, sizeof(char), sizeof(buf), stdout);
        if (r == 0)
          perror("get_wisdom (none)");
      }
      else {
        WisdomList  *l = head;
        while(l != NULL) {
          r = fwrite(l->data, sizeof(char), strlen(l->data), stdout);
          if (r == 0)
            perror("get_wisdom (list)");
          r = fwrite("\n", sizeof(char), 1, stdout);
          l = l->next;
        }
      }
      return;
    }
    
    void put_wisdom(void) {
      char     wis[DATA_SIZE] = {0};
      size_t   r;
      char*    p;
    
      r = fwrite(prompt, sizeof(char), sizeof(prompt), stdout);
      if(r == 0) {
        perror("put_wisdom (prompt)");
        return;
      }
      fflush(stdout);
    
      fflush(stdin);
      p = fgets(wis, sizeof(wis), stdin);
      if (p == NULL) {
        perror("put_wisdom (read file name)");
        return;
      }
      r = strlen(wis);
      if (wis[r-1] == '\n') {
        wis[r-1] = '\0';
      }
    
      FILE* f = fopen(wis, "r");
      if (f == NULL) {
        perror("put_wisdom (open file)");
        return;
      } 
      p = fgets(wis, 1024, f);
      if (p == NULL) {
        perror("put_wisdom (read wisdom)");
        fclose(f);
        return;
      }
      fclose(f);
      r = strlen(wis);
      if (r >= DATA_SIZE) {
        wis[DATA_SIZE-1] = '\0';
      }
      else if (wis[r-1] == '\n') {
        wis[r-1] = '\0';
      }
    
      WisdomList  *l = malloc(sizeof(WisdomList));
    
      if(l != NULL) {
        memset(l, 0, sizeof(WisdomList));
        strcpy(l->data, wis);
        if(head == NULL) {
          head = l;
        } else {
          WisdomList  *v = head;
          while(v->next != NULL) {
            v = v->next;
          }
          v->next = l;
        }
      }
    
      return;
    }
    
    /** Initialized global: list of operations on wisdoms */
    
    fptr   ptrs[3] = { NULL, get_wisdom, put_wisdom };
    
    /** Main */
    
    int main(void) {
      char   buf[1024] = {0};
      size_t r; char* rs;
      fptr   p = pat_on_back;
    
      while(1) {
        r = fwrite(greeting, sizeof(char), sizeof(greeting), stdout);
        if(r == 0) {
          perror("greetings");
          return EXIT_FAILURE;
        }
        fflush(stdout);
    
        fflush(stdin);
        rs = fgets(buf, sizeof(buf), stdin);
        if(rs != NULL) {
          long int s = atol(buf);
          if (s == 0)
    	return EXIT_SUCCESS;
          fptr tmp = ptrs[s];
          tmp();
        } else {
          perror("read");
          return EXIT_FAILURE;
        }
      }
    
      return EXIT_SUCCESS;
    }
    


    Merci d'avance.

    -
    Edité par moxxa 12 février 2019 à 0:15:44

    • Partager sur Facebook
    • Partager sur Twitter
      12 février 2019 à 9:20:03

      Salut

      moxxa a écrit:

      sachant que  j'ai obtenu avec gdb les adresses suivantes :
                         . ------------>au total 711627655 ajout de 4 , donc ptrs[2 + 711627655]  (ça marche pas : seg fault)

      D'une exécution à l'autre, les adresses changent. Inutile d'utiliser GDB, fais une simple soustraction de pointeurs:

      ptrdiff_t diff = &p - &ptrs[2];




      -
      Edité par Marc Mongenet 14 février 2019 à 11:00:20

      • Partager sur Facebook
      • Partager sur Twitter
        13 février 2019 à 20:54:41

        Merci beaucoup pour votre réponse, 

        mais le problème que :

        ptrs[diff]

        n'accède pas au contenue de la variable

        p

        en utilisant gdb, je bien conclu que

        ptrs[711627657] 

        est censé d’accéder au contenu de la variable p, mais ça me donne toujours une erreur de segmentation, mais le problème que en utilisant gdb les adresses de la variable "p" et  de "ptrs[711627657]"  sont identique ,

        Merci d'avance pour toute réponse,

        • Partager sur Facebook
        • Partager sur Twitter
          14 février 2019 à 11:02:12

          Bonjour, pourrais-tu poster le code avec diff qui plante?
          • Partager sur Facebook
          • Partager sur Twitter
            14 février 2019 à 11:58:45

            en effet

            ptrdiff_t diff = &p - &ptrs[2];

            ça marche parfaitement,
            au début j'ai pas compris le type ptrdiff du coup j'ai le remplacé par un long,

            Merci beaucoup :)



            • Partager sur Facebook
            • Partager sur Twitter

            Sécurité langage C

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown