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 :

Code à la volée


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut Code à la volée
    Bonjour,

    basiquement je voudrait exécuter un appel de fonction que je créerai via une concaténation de chaine de caractére.

    Pour l'instant j'ai vu ca :

    "en C, l'idée intuitive serait de créer un tableau d'octets qui représentent le code binaire d'une fonction, puis de créer un pointeur de fonction, et de lui affecter (avec un "cast") l'adresse du tableau. Ensuite un appel du pointeur de fonction suffit à exécuter la nouvelle routine..."

    Donc pour moi ca ressemble à ca en gros, mais à l'appel il fait Missing prototype sur le pointeur de fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char code[255] = "printf(\"%s\",\"lala\");";
    void(*b)()=NULL;
    BYTE *bb;
     
    *bb=(BYTE)code;
    b=(void(*)())&bb;
     
    b();
    Merci d'avance.

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Le code s'exécute dans un segment de mémoire dédié (text segment).
    Là, tu veux exécuter du code dans le "data segment".
    Tu t'exposes à un "segmentation violation" lors de l'exécution.

    Enfin, c'est ce que je me dis à priori. Peut-être ai-je tort ?

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    non mais en l'occurence le problème n'est pas là.


    Quand on met un texte comme ça, on obtient...... un texte.....

    Essaie de faire un dump de ton binaire, et tu verras que tu obtiens la chaîne telle quelle.

    Quand on dit qu'on peut éventuellement faire ça, c'est prendre les bytes COMPILES et y faire référence..

    Mais là on rentre dans le domaine du "patchage", et là c'est plus vraiment du C. ça se fait, mais c'est entièrement dépendant de la plateforme.

    Sinon, il faudrait faire un tableau de pointeurs, et stocker l'ADRESSE de printf, etc.....

  4. #4
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par EnigmuS
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char code[255] = "printf(\"%s\",\"lala\");";
    void(*b)()=NULL;
    BYTE *bb;
     
    *bb=(BYTE)code;
    b=(void(*)())&bb;
     
    b();
    Une première erreur: vous déréférencez bb alors que bb n'a pas été initialisée; donc vous allez stocker une valeur n'importe où en mémoire. Ensuite, un appel à printf() une fois compilé ne ressemble plus du tout à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf(\"%s\",\"lala\");
    donc ça ne risque pas de fonctionner.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Je ne parlais pas de l'implémentation de l'idée par Enigmus, qui elle est bien-sûr incorrecte mais de l'idée en question: "Créer un tableau d'octets qui représente le code binaire d'une fonction". Il s'agit d'injecter du code compilé en mémoire.

    Il faudrait pouvoir écrire ce code dans le "text segment" mais ce segment est (heureusement) protégé en écriture sur la plupart des systèmes.

    Cela doit être possible en agissant à un très bas niveau vis à vis de l'OS. Pas avec un programme classique.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut
    Ok,

    pour ce qui est d'un tableau de pointeur sur fonction le problème c'est que le traitement que je veux faire n'est pas un printf mais un appel à une DLL dont je crééerai la signature en concatenant les differents E/S (y me faudrait un pointeur sur chaque DLL et c'est pas envisageable avec un tableau de pointeur).

    sinon tu parles des bytes compilés et j ai bien compris pourquoi au niveau de la representation du code executé mais qu'est ce que le patchage et comment l'implémenter en C?

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par EnigmuS
    qu'est ce que le patchage
    c'est remplacer ou insérer du code binaire dans du code binaire.

    Exemple : mise à jour d'un OS ou d'un programme très gros sans écraser l'ensemble.

    Très très très très très très délicat.... Et 100% dépendant de la plateforme..

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut
    Merci,

    bein pour ce qui est de la plateforme elle est fixe c'est windows pour le fait que ce soit tres tres delicat je te crois sur parole lol mais j'ai 4 mois pour le faire donc voila

    le patchage nécessite des outils de développement spéciaux ou pas ?

    sinon une autre solution à mon probléme serait de récupérait la signature d'une fonction de DLL dynamiquement lol car le problème pour moi est là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    PtrDLL = (int (CVIFUNC *) (char[][FCT_LG_MAX_PARAM], int*, char[][FCT_LG_MAX_PARAM], char*)) GetProcAddress (hDLL[iDLL].hDLL , (LPCSTR)"DiagMult_INI_ReadVariable");
     
    // Execution des fonctions des  DLLs
    (*PtrDLL) (tab, nn, tabres, erreur);
    On voit que GetProcAddress recoit un prototype (tableau de chaine avec entrées, le nombre de parametre et un tableau de chaine avec les sorties) fixe y me faudrait le prototype réel pour m'affranchir de cette DLL interface et il faudrait aussi crée l'appel dynamiquement.

    Y faut que je dise à mon maitre de stage que c'estimpossible alors ?

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    du tout mais je crois que tu n'as pas vraiment compris le problème, et nous non plus par conséquence

    Précises ta pensée sur ce que tu veux faire, sur le VRAI problème initial, et là on pourra peut-être t'aider....

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut
    oups

    le vrai probléme se trouve là http://www.developpez.net/forums/sho...d.php?t=310696

    mais je sais pas si c'est compréhensible donc je la refais calmement dans le cadre d'un programme de test fonctionnels on lance des tests (qui sont statiques avec des valeurs en E/S et les renseignements des DLL appelés dans un .ini).

    Le probleme aujourd'hui on a une DLL interface par DLL, ces DLL interfaces ont toutes le meme prototype voir plus haut l'appel et elles sont chargées de convertir les chaines en entrée en paramétres appelable pour la DLL qu'elle interface.

    Mon sujet c'est qu'il n'y ai plus de Dll interface alors j'arrive facilement à convertir dynamiquement les E/S mais l'appel à la DLL réel concerné je vois pas car meme avec toutes les infos possibles, il faut construire sa signature dynamiquement.

  11. #11
    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 EnigmuS
    basiquement je voudrait exécuter un appel de fonction que je créerai via une concaténation de chaine de caractére.

    Pour l'instant j'ai vu ca :

    "en C, l'idée intuitive serait de créer un tableau d'octets qui représentent le code binaire d'une fonction, puis de créer un pointeur de fonction, et de lui affecter (avec un "cast") l'adresse du tableau. Ensuite un appel du pointeur de fonction suffit à exécuter la nouvelle routine..."
    Comportement indéfini. Un segment de donnée n'est pas forcément exécutable. Une adresse d'objet n'est pas forcément compatible avec un pointeur de fonction.

    Quand à écrire du code machine en binaire directement, ben faut pas être manchot...

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut
    Il n'y a donc pas de solutions quand on veux écrire du code à la volée en C ?

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En C standard, impossible.

    En programmation système, il est possible de générer du code machine pour un processeur donné (exemple : code x86 32 bits), puis acquérir les droits d'exécution sur la zone mémoire où l'on a généré le code en question.

    Une autre solution peut être de générer directement un fichier bibliothèque dynamique (.so, .dll) et charger dynamiquement ledit fichier avec dlopen() ou LoadLibrary().
    Ou si le compilateur est installé, on peut simplement appeler le compilateur en question pour lui faire générer la DLL.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    pas à notre connaissance, à moins que ce soit éventuellement comme on a dit plus haut (mais ce sera du code fixe, pas avec des paramètres). Et je ne pense même pas que ça marche, car quand tu dis "faut la charger", bin c'est sûr... Tu ne peux pas faire tourner quelque chose qui est sur le DD. Donc il faut bien que ce soit en mémoire quelque part. Donc, même si tu arrivais à trouver l'adresse physique de ce que tu veux sur le disque, il te faudrait de toutes façons le charger en mémoire, ainsi que les variables locales à la DLL .

    Mais c'est bien tout le principe d'une DLL. Je ne vois pas quel est le problème. La seule autre solution pour éviter le chargement est de l'avoir recopié dans le code.....

  15. #15
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Ce que tu veux faire est plus complique que ce que tu crois. Une piste potentielle pour aider:
    ftp://ftp.gnu.org/gnu/lightning/lightning-1.2.tar.gz

  16. #16
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Un segment de donnée n'est pas forcément exécutable. Une adresse d'objet n'est pas forcément compatible avec un pointeur de fonction.
    Sous windows (c'est son cas) il est relativement facile de récuperer une plage mémoire et d'en fixer le type (écriture et execution possible).
    Mais on est d'accord, il reste le gros du travail (compilation, spécificité du processeur et environnement, ...).

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut
    Citation Envoyé par Ulmo
    Sous windows (c'est son cas) il est relativement facile de récuperer une plage mémoire et d'en fixer le type (écriture et execution possible).
    Mais on est d'accord, il reste le gros du travail (compilation, spécificité du processeur et environnement, ...).
    Pour résumé il faudrait que je fasse un pointeur sur fonction sur du BYTE compilé qui serait placé dans une zone exécutable de la mémoire ?

    Si oui?
    -Comment récupere t-on une plage mémoire de se type sous Windows?
    -Comment récupérer une instruction spécifique en BYTE compilé?

    Pour finir merci pour toutes vos reponses sur les deux sujets et de partager votre experience.

  18. #18
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par EnigmuS
    -Comment récupere t-on une plage mémoire de se type sous Windows?
    A vue de nez, ça se fait bien avec VirtualAlloc. Cherche sur MSDN.
    -Comment récupérer une instruction spécifique en BYTE compilé?
    Je ne comprend pas. Tu te demandes comment traduire du C en code machine ? De l'assembleur en code machine ? Autre chose ?

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42

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

Discussions similaires

  1. Rechercher et remplacer code à la volée ?
    Par Mister Paul dans le forum Général JavaScript
    Réponses: 27
    Dernier message: 09/02/2012, 21h58
  2. Changer le code source "à la volée"
    Par kadabram dans le forum ASP
    Réponses: 9
    Dernier message: 31/07/2007, 22h42
  3. création code à la volée
    Par kakashi99 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/05/2007, 14h43
  4. Réponses: 3
    Dernier message: 24/08/2005, 14h45
  5. [JpGraph] code barre à la volée?
    Par toan dans le forum Bibliothèques et frameworks
    Réponses: 6
    Dernier message: 11/10/2004, 09h15

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