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 :

Accès bas niveau


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 57
    Points : 44
    Points
    44
    Par défaut Accès bas niveau
    Bonjour,

    Je travaille actuellement sur un projet qui vise à analyser le comportement d'un système lors d'accès direct au hardware.

    Je n'ai donc pas d'OS mais juste un noyau qui se charge et exécute le code C que j'ai créé.

    Mon problème, je suis assez nul en C et j'aimerais savoir s'il y a des moyens simple des faire ces tâches:

    - Savoir si mon code tourne bien en mode privilégié (kernel)
    - Tester quelles sont les plages d'adresses mémoire accessibles par mon code (Test d'écriture/lecture ?)

    Alors je ne sais pas s'il existe des fonctions systèmes en C qui me permettrait de faire ça ou alors plutôt me rediriger sur du code assembleur, bien que plus complexe, avec la fonction asm() ?

    Merci d'avance de l'aide que vous m'apporterez !

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Décris bien l'environnement dans lequel tu es. Ce noyau dont tu parles par exemple, d'où vient-il ? C'est lui qui décide du niveau de privilège accordé à chaque programme lancé. S'il ne le fait pas, le programme s'exécutera avec le niveau de privilège que lui-même (le noyau) utilise. Pour connaître le mode dans lequel tu es, il suffit de lire la valeur d'un flag spécifique du processeur, donc la réponse dépendra du processeur. Pour la mémoire adressable, c'est également géré par le noyau. De façon générale, il n'y a par contre pas d'instruction machine permettant de l'obtenir car pour le processeur, toute la mémoire est adressable. C'est au noyau qu'il faut demander. Sans information supplémentaire sur ton environnement, on ne peut rien te dire de plus.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Oui donc l'environnement est un peu particulier.

    Le noyau que j'utilise est issu du projet SOS (http://sos.enix.org/fr/PagePrincipale) qui propose par une série d'articles et exercices de créer son propre OS.

    Le truc c'est que je fais tourné ça sur une machine virtuelle sous ESXi de VMWare.

    Ce que j'aimerais faire, c'est testé via le code C que j'ai créé quels sont les accès possible de cette VM au niveau mémoire et processeur physique ! Vérifier par exemple que cette VM n'a accès qu'au 64Mo qui lui sont attribués et donc pas au reste des 4Go que ma machine physique possède.

    Si je suis bien par exemple en ring0, il m'est peut être possible d'avoir accès à des zones mémoires qui ne devrait pas l'être ? Dans la doc intel, j'ai trouvé une instruction assembleur "SYSENTER" qui me permet de rentré dans un mode ring0 mais je ne vois pas comment faire ça en C avec asm() ?

    Enfin voilà je sais pas si mon problème est plus clair ?

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Ton OS est en train de s'exécuter sur une machine virtuelle, avec un processeur virtuel et une mémoire virtuelle. Il n'a pas accès au processeur physique. Par exemple, si ta machine physique est dotée d'un processeur IA64, qui radicalement différent des processeurs AMD64, mais que ta machine virtuelle émule un processeur AMD64, ton OS ne verra que le processeur virtuel (AMD64). Il n'aura aucune connaissance du processeur physique (IA64). Donc que tu sois en ring0 ou en ring3 dans ta machine virtuelle, ça reste dans la machine virtuelle et ça ne change rien du tout au niveau du processeur physique. Pour la mémoire, la seule mémoire à laquelle tu pourras accéder c'est ce que voit ton processeur virtuel. Quoi que tu fasses, tu n'auras jamais un accès direct à la mémoire physique depuis une machine virtuelle.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Je ne crois pas que tout ce que tu dises soit correct... Je suis d'accord sur le fait que la VM ne voit que le matériel virtuel mais quand ton processeur virtuel doit exécuté une instruction, elle est bien transmise au processeur physique. Donc dans un sens tu y a quand même accès d'une certaine manière. C'est pareil pour la RAM. L'hyperviseur attribue une partie de la RAM physique à ta VM.

    Si je souhaite faire cette démarche c'est pour justement vérifier qu'il n'y a aucun moyen surtout au niveau RAM de sortir de l'espace qui est attribué à une VM.

  6. #6
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Je suis d'accord sur le fait que la VM ne voit que le matériel virtuel
    Non, c'est l'OS que tu exécutes dans la machine virtuelle qui ne voit que la machine virtuelle. Il ne verra jamais le processeur physique, sois-en certain.

    mais quand ton processeur virtuel doit exécuté une instruction, elle est bien transmise au processeur physique.
    Même pas. Si ton OS dans la machine virtuelle veut mettre 1 dans le "registre EAX" par exemple, 1 sera effectivement mis dans le registre EAX virtuel. Mais il est très probable que l'action réelle effectuée par le logiciel de virtualisation à ce moment c'est stocker ce 1 quelque part dans une mémoire servant à représenter le registre EAX virtuel.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Si jamais ça intéresse quelqu'un, j'ai trouvé comment on est censé faire pour voir dans quel ring on se trouve.

    Il faut aller lire le registre FLAGS (32 ou 64 bits selon l'architecture) et de prendre les bits 12-13 de ce registre.

    J'ai trouvé ce code C++ qui permet de récupérer le registre dans une variable

    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
     
    #include <iostream>
     
    int main(void)
    {
            unsigned long long var_RFLAGS = 0;
     
            __asm{
                    PUSHFQ; // pousse les 64 bits de RFLAGS sur la pile
                    POP var_RFLAGS; // met RFLAGS dans la variable var_RFLAGS
            }
     
            std::cout << std::hex << "Valeur du registre RFLAGS : 0x" << var_RFLAGS;
     
            return 0;
    }
    Maintenant j'aurais aimé essayer d'adapter pour du C. Est ce que quelqu'un voit comment faire ?

    J'ai tenté

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    unsigned long long var_FLAGS = 0;
     
    asm(" pushf;"); 				// pousse le registre FLAGS sur la pile
    asm(" pop var_FLAGS;"); 	        // met FLAGS dans la variable var_FLAGS
    Mais j'obtiens l'erreur suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    main.c:(.text+0x33b): undefined reference to `var_FLAGS'

  8. #8
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Citation Envoyé par Cedrun Voir le message
    Si je souhaite faire cette démarche c'est pour justement vérifier qu'il n'y a aucun moyen surtout au niveau RAM de sortir de l'espace qui est attribué à une VM.
    Si la VM est mal foutue, tu pourras sns doute sortir.
    Mais bon là tu pars pour tester la VM, pas le système qui tourne dedans
    Et du coup, la question portera plus sur quel est le système qui fait tourner ta VM, quelles sont les droits de cette VM dans ce système, etc. En gros, tu vas te mettre à tester si un processus peut aller en écraser un autre en mémoire, ou accéder à des choses auquel il n'est pas censé avoir accès.
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Oui c'est tout à fait ce que je souhaite réalisé...

    Tester si depuis la VM qui tourne sur VMware ESXi on a accès à des endroits où on ne devrait normalement pas pouvoir aller !

  10. #10
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Cedrun Voir le message
    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
    #include <iostream>
     
    int main(void)
    {
            unsigned long long var_RFLAGS = 0;
     
            __asm{
                    PUSHFQ; // pousse les 64 bits de RFLAGS sur la pile
                    POP var_RFLAGS; // met RFLAGS dans la variable var_RFLAGS
            }
     
            std::cout << std::hex << "Valeur du registre RFLAGS : 0x" << var_RFLAGS;
     
            return 0;
    }
    Maintenant j'aurais aimé essayer d'adapter pour du C. Est ce que quelqu'un voit comment faire ?
    Bah :
    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
    #include <stdio.h>
     
    int main(void)
    {
            unsigned long long var_RFLAGS = 0;
     
            __asm{
                    PUSHFQ; // pousse les 64 bits de RFLAGS sur la pile
                    POP var_RFLAGS; // met RFLAGS dans la variable var_RFLAGS
            }
     
            printf("Valeur du registre RFLAGS : %#X", var_RFLAGS);
     
            return 0;
    }
    C'est plus court en C non ?

    Citation Envoyé par Cedrun Voir le message
    J'ai tenté

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    unsigned long long var_FLAGS = 0;
     
    asm(" pushf;"); 				// pousse le registre FLAGS sur la pile
    asm(" pop var_FLAGS;"); 	        // met FLAGS dans la variable var_FLAGS
    Mais j'obtiens l'erreur suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    main.c:(.text+0x33b): undefined reference to `var_FLAGS'
    Ca, c'est la syntaxe de gcc. La première, c'est presque tous les autres compilateurs utilisent. Tu dois remplacer asm(" pop var_FLAGS;"); par asm(" pop %0;" : "g" (var_FLAGS)); si je ne me trompe pas (je ne suis pas sûr de ce que je dis car je n'utilise pas gcc, mais l'idée est là). Tu peux aussi mettre toutes les intructions dans un seul asm. asm est en fait une sorte de fonction printf qui envoie sa sortie vers l'assembleur.

    Enfin, sache que les mots-clés "asm", qu'il s'agisse de __asm { ... } ou de asm("...") ou de n'importe quelle autre forme, ne sont pas des mots-clés standard, ni du C, ni du C++. Ce sont simplement des ajouts spécifiques de certains compilateurs, et ils s'utilisent aussi bien en C qu'en C++, selon les langages supportés par le compilateur.

    Citation Envoyé par Cedrun Voir le message
    Oui c'est tout à fait ce que je souhaite réalisé...

    Tester si depuis la VM qui tourne sur VMware ESXi on a accès à des endroits où on ne devrait normalement pas pouvoir aller !
    Ah ... chercher un bug dans VMWare. Désolé je ne l'avais pas compris comme cela.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Merci pour toutes ces infos utiles !

    Je vais continuer et si je trouve quelque chose d'intéressant je le posterai ici...

Discussions similaires

  1. Réponses: 11
    Dernier message: 28/07/2009, 10h10
  2. [Système] Accès aux éléments de bas niveau
    Par mithrendil dans le forum Langage
    Réponses: 2
    Dernier message: 22/07/2008, 17h37
  3. Formatage bas niveau
    Par wareq dans le forum Composants
    Réponses: 5
    Dernier message: 09/05/2005, 16h00
  4. formatage de bas niveau ??
    Par vbcasimir dans le forum Windows XP
    Réponses: 11
    Dernier message: 06/05/2005, 18h45
  5. Programmation bas niveau de la carte vidéo !!
    Par Invité dans le forum Assembleur
    Réponses: 3
    Dernier message: 03/03/2005, 11h05

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