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 :

Pointeur de fonction


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 22
    Par défaut Pointeur de fonction
    Bonsoir à tous !
    J'étudie un peu les buffer overflow et j'en profite pour essayer de m'habituer encore un peu plus au C. Mais voila il est tard, et je craque :
    (le shellcode ne fait qu'un sleep de 99999999 ms)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <iostream>
     
    char shellcode[] = "\x68\xFF\xE0\xF5\x05\xB8\xE6\x1B\xE6\x77\xFF\xD0";
     
    void (*opcode)();
    int main() {
        opcode = &shellcode;
        opcode();
        return 1;
    }
    J'obtiens l'erreur de compilation : cannot convert `char (*)[13]' to `void (*)()' in assignment

    Vous l'aurez compris, j'essaye tout simplement de pointer la fonction vers l'adresse du shellcode... sans succès et pourtant.

    Merci

  2. #2
    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
    1. C'est sale, ça, mais je suppose que tu le sais.
    2. Tu peux essayer avec reinterpret_cast<>, sinon tu devras faire ce qu'on appelle un union_cast (passer par un union ayant un champ de type char* et un champ du type de pointeur de fonction).
    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.

  3. #3
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 22
    Par défaut
    Merci pour ta réponse. J'ai donc cherché du côté des *_cast, et n'y parvenant pas avec reinterpret_cast j'ai utilisé static_cast :
    opcode = static_cast<void>(&shellcode);

    Ca convertit bien en void mais j'ai toujours ce soucis :
    impossible de convertir de 'void' en 'void (__cdecl *)(void)'

    Et..... j'ai un peu du mal à saisir ce que représente "void (__cdecl *)(void)" :/


    (Pour union_cast j'ai rien trouvé :s)
    Hé puis oui c'est sale mais bon la le but c'est pas vraiment de faire un beau programme, juste bidouiller =)

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    J'y connais rien en shellcode, mais ça semble douteux comme façon de l'appeler. Il ne faudrait pas plutôt passer par la fonction system et passer ton shellcode à l'interpréteur de commande de l'OS ?

  5. #5
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 22
    Par défaut
    En fait dans les BO (buffer overflow), la première étape est de rediriger le flux d'instructions vers le code malsain. Bon la le flux est rediriger très simplement, je met cette partie de côté pour l'instant.
    Donc la j'essayais juste de rediriger le pointeur de fonction vers un shellcode.

    Enfin c'est pas grand chose, mais j'essaye de recréer manuellement le déroulement d'un BO pour bien comprendre tout ca.

    Bon et puis maintenant que j'y suis tant qu'à faire j'essaye de comprendre le problème de la compilation au cas ou jretomberais dessus plus tard

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    C, c'est le forum d'à côté.

    J'obtiens l'erreur de compilation : cannot convert `char (*)[13]' to `void (*)()' in assignment
    Normal, ce ne sont pas des types compatibles.
    Après, tu peux toujours essayer de convaincre le système de types que le pointeur vers le début de ton tableau est en fait un pointeur de fonction. Ce qui se fait avec un cast.
    Les casts C++ t'empêchent de trop faire n'importe quoi donc tu ne pourras pas simplement faire cette manipulation avec (en fait je crois que c'est possible en faisant ça en plusieurs étapes, voire le fameux problème de conversion void* vers fonction de dlsym).

    Essaie donc avec un cast C.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    opcode = (void(*)())shellcode;

  7. #7
    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 leyou
    J'étudie un peu les buffer overflow et j'en profite pour essayer de m'habituer encore un peu plus au C.
    Y'a du boulot...

    C et C++ sont 2 langages différents. <iostream>, c'est pas du C.

  8. #8
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Et comme cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main(void)
    {
        void (*func) ();
        (long) func = &shellcode;
        func();
        return 0;
    }

  9. #9
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 528
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 528
    Par défaut
    Citation Envoyé par leyou
    Bonsoir à tous !
    J'étudie un peu les buffer overflow et j'en profite pour essayer de m'habituer encore un peu plus au C. Mais voila il est tard, et je craque :
    C'est stupide comme code tu essaie de faire pointer un traitement informatique vers des données !
    C'est digne de la taverne !
    Un conseil : achetes un bon livre sur l'assembleur x86 tu pigeras sans doute mieux.

    Citation Envoyé par leyou
    Vous l'aurez compris, j'essaye tout simplement de pointer la fonction vers l'adresse du shellcode... sans succès et pourtant.
    Merci
    Le pointeur sur une adresse de code exécutable c'est un entier 32bits ( vu qu'il ny pas presque plus d'OS 16 bits comme win3.1 ).
    En assembleur c'est un CALL , JMP ou autre or le compilateur CALL <adresse de variable> il ne connait pas !
    Est-tu sérieux dans ce que tu fais ?

  10. #10
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par Mat.M
    C'est stupide comme code tu essaie de faire pointer un traitement informatique vers des données !
    C'est digne de la taverne !
    Un conseil : achetes un bon livre sur l'assembleur x86 tu pigeras sans doute mieux.
    Aussi stupide que ce code ?

    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
     
    char shellcode[]=
    "\x31\xc0\x31\xdb\x31\xd2\x50"
    "\x68\x72\x0a\x00\x00\x68\x75\x6e"
    "\x6e\x65\x68\x53\x6b\x79\x72\x89\xe1\xb2"
    "\x0a\xb0\x04\xcd\x80\x31\xc0\x31\xdb\xb0"
    "\x01\xcd\x80";
     
     
    int main()
    {
            void (*routine) ();
            (long) routine = &shellcode;
            routine();
            return 0;
    }

  11. #11
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 528
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 528
    Par défaut
    Mr Skyrunner bon j'accepte le fait de pouvoir me tromper et je reconnais avoir fait des erreurs par le passé.

    Mais ou je m'y prends mal ou bien il y a quelque chose qui ne tourne pas rond
    J'ai fait un copier coller sous VC++ (6.0 sans SP ) exactement du code donné
    et j'obtiens:

    ( projet mode console )
    --------------------Configuration: test - Win32 Debug--------------------
    Compiling...
    test.cpp
    C:\projet\test\test.cpp(12) : error C2440: '=' : cannot convert from 'char (*)[39]' to 'long'
    This conversion requires a reinterpret_cast, a C-style cast or function-style cast
    Error executing cl.exe.

    test.obj - 1 error(s), 0 warning(s)
    Peut-être alors que sous d'autres compilos cela peut fonctionner auquel cas je reconnais avoir fait une erreur alors

  12. #12
    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 Mat.M
    Compiling...
    test.cpp
    C'est du C alors extension.c et non .cpp please... Tu te trompes de compilateur...

  13. #13
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Citation Envoyé par Skyrunner

    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
     
    char shellcode[]=
    "\x31\xc0\x31\xdb\x31\xd2\x50"
    "\x68\x72\x0a\x00\x00\x68\x75\x6e"
    "\x6e\x65\x68\x53\x6b\x79\x72\x89\xe1\xb2"
    "\x0a\xb0\x04\xcd\x80\x31\xc0\x31\xdb\xb0"
    "\x01\xcd\x80";
     
     
    int main()
    {
            void (*routine) ();
            (long) routine = &shellcode;
            routine();
            return 0;
    }
    Tu ne devrais pas plutot caster en void* ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    routine = (void *) shellcode;

  14. #14
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par hegros
    Tu ne devrais pas plutot caster en void* ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    routine = (void *) shellcode;
    Je dirais plutôt comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    routine = (void (*)(void))shellcode;

  15. #15
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Citation Envoyé par crocodilex
    Je dirais plutôt comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    routine = (void (*)(void))shellcode;
    tant qu'a faire je ferais :

    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
     
    char shellcode[]=
    "\x31\xc0\x31\xdb\x31\xd2\x50"
    "\x68\x72\x0a\x00\x00\x68\x75\x6e"
    "\x6e\x65\x68\x53\x6b\x79\x72\x89\xe1\xb2"
    "\x0a\xb0\x04\xcd\x80\x31\xc0\x31\xdb\xb0"
    "\x01\xcd\x80";
     
    typedef void (*routine) ();
     
    int main() {
         routine ptr =(routine)shellcode;
         ptr();
        return 0;
    }

  16. #16
    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 hegros
    Tu ne devrais pas plutot caster en void* ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    routine = (void *) shellcode;
    (void*) c'est pour les pointeurs sur objet. Ici, on veut un pointeur sur code.

    Mais de toutes façons, la manoeuvre n'est pas portable pour des raisons évidentes...

  17. #17
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Sinon il fait quoi ce shellcode et fonctionne sous quel systéme et archi

  18. #18
    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 Skyrunner
    Aussi stupide que ce code ?
    Ou que c'est pas beau !
    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 shellcode[] =
       "\x31\xc0\x31\xdb\x31\xd2\x50"
       "\x68\x72\x0a\x00\x00\x68\x75\x6e"
       "\x6e\x65\x68\x53\x6b\x79\x72\x89\xe1\xb2"
       "\x0a\xb0\x04\xcd\x80\x31\xc0\x31\xdb\xb0" 
       "\x01\xcd\x80";
     
    typedef void routine_f (void);
    int main (void)
    {
       ((routine_f *) shellcode)();
       return 0;
    }

  19. #19
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ou que c'est pas beau !
    C'était pas fait pour l'être, mais il est vrai qu'avec le tien c'est déjà mieux

    @Mat.M

    Arf c'est fait pour fonctionner sous Linux, désolé.

    skyrunner@auron:~/shellcode$ cat test.c
    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 shellcode[] =
    "\x31\xc0\x31\xdb\x31\xd2\x50"
    "\x68\x72\x0a\x00\x00\x68\x75\x6e"
    "\x6e\x65\x68\x53\x6b\x79\x72\x89\xe1\xb2"
    "\x0a\xb0\x04\xcd\x80\x31\xc0\x31\xdb\xb0"
    "\x01\xcd\x80";
     
    typedef void routine_f (void);
    int main (void)
    {
            ((routine_f *) shellcode)();
            return 0;
    }
    skyrunner@auron:~/shellcode$ gcc test.c -o test
    skyrunner@auron:~/shellcode$ ./test
    Skyrunner
    skyrunner@auron:~/shellcode$

  20. #20
    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 Skyrunner
    Arf c'est fait pour fonctionner sous Linux, désolé.
    Sous Windows XP : Trap. (Normal, on tente d'éxécuter du code en zone data).

    Windows plus sûr que GNU/Linux ?

Discussions similaires

  1. opengl et pointeur de fonction
    Par Oldhar dans le forum C
    Réponses: 5
    Dernier message: 06/11/2003, 23h56
  2. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37
  3. Matrice de pointeurs de fonctions
    Par sebduth dans le forum C
    Réponses: 15
    Dernier message: 18/07/2003, 14h03
  4. [Kylix] Pointeur de fonctions
    Par _dack_ dans le forum EDI
    Réponses: 1
    Dernier message: 03/07/2003, 10h17
  5. pointeur de fonction
    Par kardath dans le forum C
    Réponses: 4
    Dernier message: 28/12/2002, 14h39

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