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 :

exécution de "blocs" d'instruction créés dynamiquement


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut exécution de "blocs" d'instruction créés dynamiquement
    Salut,


    J'ai un léger problème pour réussir à exécuter des blocks d'instructions que j'ai créé dynamiquement

    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
    void blockExecute() {
    	size_t size = &&block_end - &&block_begin;
    	void* buf = malloc(size);
    	if (buf == NULL) {
    		puts("allocation du buffer impossible");
    		fflush(stdout);
    		exit(-1);
    	}
    	void* block = memcpy(buf, &&block_begin, size);
     
    	puts("début de l'exécution");
    	fflush(stdout);
    	goto *block;
     
    block_begin:
    	puts("coucou");
    block_end: return;
     
    }
     
    int main(int argc, char** argv) {
    	blockExecute();
    	return 0;
    }

    et ça me sort ceci :
    gorgonite@GorgonMobile$ make BasicBlocks.exe
    gcc -O0 -Wall BasicBlocks.c -o BasicBlocks.exe
    gorgonite@GorgonMobile$ ./BasicBlocks.exe
    début de l'exécution
    Erreur de segmentation (core dumped)

    si quelqu'un voit comment s'y prendre... ça m'intéresserait
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  2. #2
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Je te conseille de rajouter quelques printf histoire de vérifier si les adresses que tu souhaites utiliser et donc la taille de mémoire que tu souhaites allouer sont corrects.
    De plus je me demande si tu ne devrais pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void* buf = malloc(size+1); // au lieu de size seuleument
    Bon courage

  3. #3
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Je crois que c'est dû au fait que les pages mémoires ont des droits spécifiques. Par exemple, tu ne peux exécuter que les pages qui ont le droit d'exécution (le segment CODE). Là, tu essayes d'exécuter dans le tas, et on a pas le droit.
    Ceci dépend des systèmes.


    De plus, le retour ne doit pas très bien se faire. Tu fais puts, et après, ça part en vrille car il n'y a pas de retour. Tu as essayé d'utiliser GDB pour voir d'où venait l'erreur exactement ?

  4. #4
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    Citation Envoyé par millie
    Je crois que c'est dû au fait que les pages mémoires ont des droits spécifiques. Par exemple, tu ne peux exécuter que les pages qui ont le droit d'exécution (le segment CODE). Là, tu essayes d'exécuter dans le tas, et on a pas le droit.
    Ceci dépend des systèmes.

    justement sur les x86, cette sécurité n'est pas implantée.... car le controle en exécution des pages mémoire ne se fait pas au même niveau que sur les autres architectures ; c'est entre autre pour cela que les shell code sont redoutables
    (enfin, si j'ai bien compris )


    Citation Envoyé par millie
    De plus, le retour ne doit pas très bien se faire. Tu fais puts, et après, ça part en vrille car il n'y a pas de retour. Tu as essayé d'utiliser GDB pour voir d'où venait l'erreur exactement ?
    ben je mets le retour...


    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
    void blockExecute() {
    	size_t size = &&block_end - &&block_begin;
    	void* buf = malloc(size+1);
    	if (buf == NULL) {
    		puts("allocation du buffer impossible");
    		fflush(stdout);
    		exit(-1);
    	}
    	void* block = memcpy(buf, &&block_begin, size);
    	printf("adresse du bloc %p\tlongueur %d\n",&&block_begin,(int) size);
    	printf("adresse du buffer %p\n",block);
     
    	puts("début de l'exécution");
    	fflush(stdout);
    	goto *block;
     
    block_begin:
    	puts("coucou");
    	return;
    block_end: return;
     
    }

    au passage, j'ai fait les printf conseillés par TheGzD

    gorgonite@GorgonMobile$ ./BasicBlocks.exe
    adresse du bloc 0x804855c longueur 14
    adresse du buffer 0x804a430
    début de l'exécution
    Erreur de segmentation (core dumped)
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    J'ai un peu plus regardé, histoire de voir si les bonnes zones étaient bien copiées.

    J'ai également fait tourner le programme sur un SPARC, j'ai également l'erreur de segmentation. Je pense qu'il y a tout de même une protection sur l'exécution de page virtuelle qui se trouve dans le tas, même sous x86.


    Voilà le dernier code modifié :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
     
    void handler(int i)
    {
     fprintf(stderr, "Oula, je n'ai pas segfaulté\n");
    }
     
    void blockExecute()
    {
      ssize_t size = &&block_end - &&block_begin;
      fprintf(stderr, "Size : %d\n", (int) size);
      void* buf = malloc(size);
      if (buf == NULL)
      {
        puts("allocation du buffer impossible");
        fflush(stdout);
        exit(-1);
      }
     
     
      void* block = memcpy(buf, &&block_begin, size);
     
      char * chaine = block;
      char * chaineA = &&block_begin;
      fprintf(stderr," Chaine   : %10s\n", chaine);
      fprintf(stderr," Chaine A : %10s\n", chaineA);
      void * blockNormal = &&block_begin;
     
      fprintf(stderr, "début de l'exécution");
      goto *buf;
     
      return;
    block_begin:
      fprintf(stderr, "Ici");
      goto block_end;
    block_end:
     return;
    }
     
    int main(void)
    {
      signal(SIGSEGV, handler);
      blockExecute();
      return 0;
    }
    Au passage, je te conseille d'utiliser fprintf(stderr, ""); au lieu de printf (stderr n'est pas bufferisé)

  6. #6
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    perso, quand je laisse les puts, je me prends une infinité de
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    et je retombe sur le même message d'erreur quand je passe tout en fprintf(stderr,...)

    et toi ?
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  7. #7
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    T'as vu, il n'a pas seg faulté

    Sous linux, j'ai pareil (ce qui est normal, il doit chercher à exécuter, il dit qu'il peut pas, mais il avance, et donc ça boucle comme ça).

    Sous Windows, le programme se finit quand même pas un signal que je n'ai pas déterminé (il affiche tout de même un : Oula je n'ai pas segfaulté avant de finir)

    Sous Solaris/Sparc, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Oula, je n'ai pas segfaulté
    Segmentation Fault (core dumped)
    Ce qui est ultra bizarre... A moins qu'il y ait un autre signal qui n'est pas SIGSEGV et qui affiche ça...

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Meme sans protection, il y a pas mal de chance que le compilateur utilise des sauts relatifs plutot que des sauts absolus comme tu l'esperes, sans parler des effets des optimiseurs.

    Quel est le probleme que tu essaies de resoudre?

    (gnu lightening? je ne sais pas dans quel etat c'est)

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par gorgonite
    J'ai un léger problème pour réussir à exécuter des blocks d'instructions que j'ai créé dynamiquement
    Il n'y a aucun moyen portable de faire ce que tu veux.
    • Rien ne dit que des étiquettes de goto aient des adresses valides
    • Tu copies du code en mémoire de données. Rien ne dit que cette mémoire ait les droits d'exécution, ni que ces adresses (code) soient valides dans l'espace traité par la copie (données)...

    Bref, le comportement est indéterminé.

    Que veux-tu faire exactement ? Peut être que la méthode n'est pas la bonne...

  10. #10
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Que veux-tu faire exactement ? Peut être que la méthode n'est pas la bonne...

    je veux passer à l'étape de preparation sequences en suivant le modèle décrit dans le papier de Gagnon & Hendren http://www.sable.mcgill.ca/publicati...per-2003-2.pdf

    la création et l'exécution de ses basic blocks est une étape essentielle.

    ils l'ont implanté la sablevm, donc ça doit marcher en x86

    (je ne veux pas recopier le code qu'ils ont, je veux comprendre comment faire cela pour l'appliquer à ma machine virtuelle )
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

+ Répondre à la discussion
Cette discussion est résolue.

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