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

x86 32-bits / 64-bits Assembleur Discussion :

modifie table des vecteurs


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre régulier

    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Août 2012
    Messages : 70
    Points : 120
    Points
    120
    Par défaut modifie table des vecteurs
    bonjour

    j'utilise linux , et je veux modifie la table de vecteur de mon system d'exploitation ( ne demandez pas pour quoi !! c'est un TP ) apparament même lorsque je désactive le system d'interruption avec (cli ), je ne peux pas accessder à ma table de vecteur . comment faire pour acceder ?
    autre question :
    Quande je reussis à modifier cette table , lorsque je redemmarre mon OS , les tables reviennent à leurs premiere état , ou bien ils restent modifier ??
    merci d'avance

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 617
    Points
    23 617
    Par défaut
    Ôte-moi d'un doute : la table de QUELS vecteurs ?

  3. #3
    Membre régulier

    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Août 2012
    Messages : 70
    Points : 120
    Points
    120
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Ôte-moi d'un doute : la table de QUELS vecteurs ?
    la table des vecteurs d'interruptions

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 617
    Points
    23 617
    Par défaut
    On suppose que tu travailles sur PC (voir les règles du forum Assembleur).

    Apparemment, tu mélanges plusieurs choses. La table des interruptions qui se trouvait en 0000:0000 était valable en mode réel ! Linux fonctionne depuis le départ en mode protégé, comme tous les systèmes d'exploitation modernes. Pour modifier une telle table des interruptions, il faudrait d'abord passer en mode noyau, puis récupérer le vecteur vers l'IDT qui, elle, contient les descripteurs de segment pour chaque interruption, avec les privilèges associés. Est-ce que c'est vraiment ce que tu fais ?

    Est-ce que tu ne serait pas plutôt en train d'utiliser sous Linux un émulateur ou une machine virtuelle qui, elle, ferait fonctionner un environnement en mode réel dans laquelle tu ferais tes exercices ?

    Tu nous donnes si peu d'informations qu'il est difficile de savoir de quoi il en retourne exactement.

    Quande je reussis à modifier cette table , lorsque je redemmarre mon OS , les tables reviennent à leurs premiere état , ou bien ils restent modifier ??
    Ils reviennent à leur état initial bien sûr. Plus précisément, ils se trouvent en mémoire et c'est le système d'exploitation lui-même qui les définit dès le départ. Il les initialise donc à une place pour laquelle il a été configuré. Si ce vecteur pointe la première zone de mémoire disponible pour accueillir un pilote, il peut pointer n'importe où.

  5. #5
    Membre régulier

    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Août 2012
    Messages : 70
    Points : 120
    Points
    120
    Par défaut
    bonsoir
    je suis désolé pour ma mauvaise formulation du sujet , et je vous remercie d'avoir répondu à mes questions .
    Dans l'énnonce de mon TP, ils ont demandé ce qui suit :
    1-je dois écrire un programme qui déclenche une interruption , par exemple : la commande de changement memoire - memoire n'est pas permise par l'assembleur et doit déclencher une interruption , ou bien si je veux acceder à une case mémoire inexistant , l'essentiel c'est que lors que vous executez ce programme vous déclencherez une iterruption.
    2-je dois ecrire et placer dans le system (linux) un programme de traitement et le associe à cette interruption.
    en d'autre mots :
    Le system lorsqu'il traite l'interruption declenché par le premier programme, il doit executer le 2eme programme au lieu d'utiliser le programme qui est défini par system.
    Le programme de traitement affiche un message seulement il n'est pas censé refaire le traitement originale. je peux afficher un message de salutation.

    pour moi :
    1- je dois itegrer les deux programmes . et ne pas lasser le system d'interruption modifie pour beaucoup de temps parce que c'est dangereux.
    Donc juste après modifie system d'interruption, je déclenche l'interruption , je laisse le system faire son travail, et je remet le system d'interrution à l'état initiale.
    2- Après quelleques recherches.
    certain documents, disent que c'est impossible de modifie directement la table de vecteur d'interruption sous le mode protège.
    D'aprés d'autre il suffit de désactive le systeme d'interruption avec la commande (cli en assembleurm) , en suite modifie la table des vecteurs dinterruption , enfin le reactive avec la commande (sti en assembleur) "mais je pense que c'est faux, et ça n'a pas marché avec mes amis".
    3- si j'ai bien compris . sous le mode réel la table de vecteur se trouve à l'addresse 0000:0000 . sa modification est possible . mais je ne sais pas comment utilise linux sous ce mode . d'ailleur je ne suis même pas sure si c'est possible .
    4- vous avez utilisé le terme "mode noyau" , est-ce que c'est le mode réel lui-même ?
    et comment passer à ce mode ?
    5- la table des vecteurs d'interruption prend une position fixe dans la MC, ou bien elle la change après chaque redemarrage.
    6-je sais qu'il existe un table de descripteur d'interruption qui sera consulter à chaque traitement d'interruption en mode protége , mais j'ignore si c'est possible de la touche. je ne sais même comment trouvé sont emplacement dans la mémoire

  6. #6
    Membre régulier

    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Août 2012
    Messages : 70
    Points : 120
    Points
    120
    Par défaut
    j'ai trouve des reponse à mes questions
    je veux maintenent charge la valeur de l'idtr , j'ai essayer avec ce code , mais je n'ai pas reussis , pouvez vous me corriger ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    section .data
            a: TIMES 48 db 1
    section .text
            global _start
    _start:
            sitd  a
    message de erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     error: parser: instruction expected

  7. #7
    Membre régulier

    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Août 2012
    Messages : 70
    Points : 120
    Points
    120
    Par défaut
    j'ai reussi à touve la valeur du registre idtr c'est FF0F00509781
    la taille du tableau est 9781 en hex (les 16 derniers bits de idtr) ce qui corresponde à 38785 , d'apres wikipedia http://fr.wikipedia.org/wiki/Interrupt_Descriptor_Table
    le taille de chauque descripteur est 8 octets, donc 64 bits
    si on divise 38784 par 64, on trouve 606
    mais le nombre des interruptions ne doit pas dépasser 256
    qu"est ce que ça veut dire ?

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 617
    Points
    23 617
    Par défaut
    Hello,

    Citation Envoyé par linux user Voir le message
    mais le nombre des interruptions ne doit pas dépasser 256
    qu"est ce que ça veut dire ?
    Ça veut dire — sans méchanceté aucune — que tu ne comprends visiblement pas ce que tu es en train de faire. Ce n'est pas un tort en soi et tâtonner est souvent une bonne méthode pour trouver rapidement la solution mais là, tu t'attaques d'emblée à quelque chose de très gros et qui n'est visiblement pas ce que souhaites ton prof'. Il serait bon que tu te rapproches de lui et que tu lui demandes des précisions, sinon tu risques le hors-sujet et tu te seras en fin de compte donné beaucoup de mal pour rien.

    Donc, puisque tu as visiblement fait des recherches et malgré les réponses que tu as obtenues, voici quelques explications :

    • Le mode réel et le mode protégé sont deux modes de fonctionnement distinct du micro-processeur. Ces notions sont donc complètement indépendantes du système d'exploitation utilisé et, en particulier, n'ont rien à voir avec le mode noyau en programmation système ;
    • Bien que plusieurs micro-processeurs proposent des mécanismes similaires, ces appellations précises sont propres à la famille des x86 d'Intel et aux processeurs compatibles (notamment les AMD). Ce sont ceux qui équipent les PC ;
    • Le mode réel est le mode original dans lequel fonctionnait le 8086 originel et qui s'apparente à celui de tous les autres processeurs ordinaires : un accès sans restriction particulière à la mémoire entière et de façon linéaire. Le 8086 en particulier, toutefois, utilisait le mécanismes des segments pour pouvoir exploiter un bus d'adresse de 20 bits (soit 1 Mo adressable) à l'aide de registre de 16 bits ordinaires ;
    • Le mode protégé, lui, consiste à définir des segments dont le fonctionnement n'a rien à voir avec celui du mode réel. Il s'agit en fait de définir une table en mémoire, lue électroniquement par le micro-processeur, qui définit une liste de zones contiguës en mémoire et auxquelles on associe un certain niveau de privilège. Un programme qui s'exécute dans une de ces zones ne peut exécuter que les instructions qui correspondent à son niveau de privilège et ne peut également lire ou écrire que dans cette zone. Si le programme essaie de faire un accès hors-zone ou d'exécuter une instruction interdite, le micro-processeur déclenche une exception au lieu d'honorer la demande. Cette exception est dirigée par le système d'exploitation vers une procédure qui, généralement, mettra fin au programme fautif ;


    … et par ailleurs :

    • Une interruption est au départ matérielle (IRQ) : il s'agit de permettre au micro-processeur de sauter automatiquement vers une procédure définie à l'avance dans le cas d'un événement extérieur (par exemple : un appui sur une touche du clavier) ;
    • Une interruption logicielle consiste en une instruction qui met artificiellement le micro-processeur dans un état d'interruption, comme s'il avait reçu une IRQ ;
    • Bien qu'initialement, cette instruction n'ait pas été prévue pour cela en particulier, les interruptions logicielles ont été assez tôt utilisées pour implémenter les appels systèmes, car le code opération est très court (utile quand il y a beaucoup d'appels à faire au cours d'un programme), que cela sauvegarde automatiquement certains registres et inhibe les interruptions pendant qu'on la traite, mais également parce que cela permet de s'affranchir de spécifier une adresse précise. On peut donc facilement faire évoluer le système d'exploitation tout en gardant les programmes compatibles ;
    • La plupart des « petits » micro-processeurs n'ont qu'une seule instruction d'interruption logicielle (éventuellement deux ou trois, comme sur 6809). L'usage veut que lorsqu'on les utilise pour faire des appels système, on passe le numéro de la fonction à appeler dans un registre ;
    • Le x86, lui, propose de passer ce numéro directement dans le code-opération de l'instruction d'interruption. Du coup, c'est comme si on avait 256 interruptions logicielles différentes, numérotées de « INT 00h » à « INT FFh ». C'est pratique d'une part pour utiliser plusieurs systèmes différents utilisant le même procédé et parce que le micro-processeur peut également les utiliser soit pour mapper les vraies interruptions matérielles, soit les exceptions (telles que la division par zéro, par exemple).


    Et de là :

    • En mode réel, la table des vecteurs de ces interruptions devait, par construction, se trouver tout-à-fait au début de la mémoire, donc à partir de 0000:0000 ;
    • En mode protégé, cette table peut se trouver n'importe où en mémoire, mais l'adresse de son point de départ doit être explicitement chargé dans IDT.


    DOS (et MS-DOS en particulier) était fait pour fonctionner sur les premiers PC en mode réel : il apportait donc un ensemble de fonctionnalité permettant de se servir de sa machine mais pas de protection particulière. Mais surtout, il était fait pour fonctionner en mono-tâche et mono-utilisateur. Celui-ci avait donc le contrôle total de sa machine et pouvait notamment inhiber les interruptions si cela lui chantait.

    Il était donc extrêmement facile de remplacer un vecteur d'interruption par un autre pointant vers sa propre routine, laquelle appelait en fin de traitement la routine originale. Ça permettait par exemple de faire des keyloggers ou, plus généralement, d'associer facilement une action à une combinaison de touches, ou de suivre l'horloge, etc. Cette technique s'appelle un hook (« faire un crochet »). D'ailleurs, il existait même un point d'entrée pour le faire de façon « officielle ».

    Il va sans dire qu'il en va complètement différemment aujourd'hui : tripatouiller la table des interruptions aujourd'hui, c'est courir droit au plantage et il est difficile de le faire proprement même pour les développeurs du noyau. Pour ce faire, il te faudrait d'abord acquérir les bons privilèges, ce qui consiste à travailler en mode noyau et donc développer un module *.ko pour pouvoir y placer tes propres routines. Note également que cela n'a rien à voir non plus avec le fait de travailler en root.

    Ensuite, inhiber les interruptions avec cli aurait un impact non négligeable sur la bonne santé du système. Il faudrait penser entre autres à flusher le cache disque avant de procéder et surveiller ensuite tout ce qui dépend du timer et de la date courante.

    Enfin, pour ses appels systèmes, Linux n'utilise qu'un seul point d'entrée : INT 80h. Si tu détournes ce vecteur, tu détournes la totalité des appels systèmes. À toi ensuite de faire le tri. C'est possible, mais pas sans risque, encore une fois.

  9. #9
    Membre régulier

    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Août 2012
    Messages : 70
    Points : 120
    Points
    120
    Par défaut
    j'ai écrit ce code à fin de modifie ma table d'interruption sous windows
    mais il ne fonctionne pas je n'ai pas compris pourquoi ?
    pour compiler j'ai utilisé cette commonde
    nasm -f bin nome.asm -o nome.com
    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
    section .text
    	global _start
     
    _start:
    	;je me l'adresse de l'etiquette "_c" dans ds:dx  
    	; à fin d'utiliser int 21h
     
     
    	; adresse de segment
    	mov cx,cs
    	mov ds,cx
     
    	;offset  
    	mov dx,_c
     
    	; 25 pour dire au system que je veux mettre une nouvelle interruption
    	; 00 le numero d'interruption " division par zero  
    	mov ax,2500h
    	int 21h
     
    	; je declenche un interruption de type division par zero
    	mov cx,0000h
    	mov ax,0000h
    	div cx
     
    	; la fin
    	mov AX,4C00h
    	int 21h
     
     
    _c:
    	mov ah,02h
    	mov dl,'B'
    	int 21h
    	mov AX,4C00h
    	int 21h
    	iret

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 617
    Points
    23 617
    Par défaut
    As-tu lu et compris ce que j'ai écrit ci-dessus ?

    Le code que tu as écrit a l'air correct à première vue mais :

    • Il s'agit de code assembleur 16 bits pour D.O.S. ! Il ne peut fonctionner qu'à travers un émulateur D.O.S. et si ta version de Windows est trop récente, elle refusera purement et simplement de lancer des programmes *.COM. Ce sont des reliquats du système de 1980 ;
    • Ton programme fait une division de 0 par 0 ce qui est un cas indéterminé. A priori, ça devrait déclencher l'exception quand même ;
    • À ma connaissance, les interruptions du BIOS et du D.O.S. ne sont pas garanties pour être réentrantes. Appeler ces interruptions quand tu te trouves déjà en état d'interruption est donc risqué.


    Mais ce qui t'ennuie ici, c'est que :

    • Tu as oublié que les programmes *.COM sont chargés après leur PSP (Program Segment Prefix) de 256 octets. Ils commencent donc à l'adresse 0100h et pas 0000. Or, tu fais référence à « _c » pour donner l'adresse de ta routine mais tu n'as spécifié aucun point de départ. Utilise « ORG 100h » en tête de programme et ça devrait rentrer dans l'ordre. Ça fonctionne avec DosBox.


    Évidemment, la modification ne sera valable qu'en environnement D.O.S. et pendant la durée d'exécution de ton programme. Cela n'impactera en aucun cas les autres programmes Windows.

    À noter enfin que ton programme D.O.S n'est pas fait pour être un T.S.R. (Terminate and Stay Resident). La mémoire qu'il occupe va donc être libérée mais le vecteur d'interruption que tu as modifié va continuer à la pointer. Du coup, dès qu'un autre programme serait chargé et tenterait d'effectuer une division par zéro, tout ton système planterait.

  11. #11
    Membre régulier

    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Août 2012
    Messages : 70
    Points : 120
    Points
    120
    Par défaut
    j'ai ajouté la commande ORG 100h, et ça marche trés bien , même sur ma machine ( windows 7 32bits , Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz)
    reste un probleme :
    dans mon programme de traitement d'interruption je veux modifie compteur ordinal de programme interropu, c-à-d je veux executer l'instruction qui vient aprés l'interruption apres iret et ne pas revenire à l'instruction qui a generer l'interruption.

    je veux assurer si ces informations sont corrects :
    1-aprés l'interrutpion et avant le programme de traitement , la valeur des Flag , CS et IP seront stocker dans la pile automatiquement dans la pile, dans cette ordre.
    2- le context de programme n'est pas sauvegarder automatiquement , donc il faut le sauve garder manuellement en utilisant pusha en debut de programme de traitement, et popa à sa fin.
    3-il faut entourer pusha, et popa avec cli et sti pour ne pas perdre le context de programme interropu , dans le cas où une autre interrution vient .


    encore une question :
    Connessez vous un Bon debugger des fichiers .COM ? j'ai essayer avec le GDB mais il n'a pas reconnu ce fichier

Discussions similaires

  1. Tables des vecteurs
    Par sheridan08 dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 23/03/2010, 13h00
  2. Parcourir la table des matieres pour la modifier
    Par stehga dans le forum Word
    Réponses: 7
    Dernier message: 29/08/2008, 00h05
  3. Réponses: 13
    Dernier message: 26/06/2006, 12h10
  4. Réponses: 2
    Dernier message: 10/02/2006, 16h09
  5. Modifier la profondeur de la table des matières
    Par Bouboubou dans le forum Mise en forme
    Réponses: 6
    Dernier message: 16/12/2005, 13h19

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