2009
08.21

Voici le dernier article que je consacrerais à mon os (à prioris), je vous donnerais alors les sources du projet en fin d’article ; au cours de celui-ci nous allons nous intéressez à la gestion de la mémoire virtuel en mettant en place de l’identy-mapping et une autre règle pour gérer une tache utilisateur.

C’est vraiment la partie la plus technique que j’ai rencontré, car beaucoup de mécanisme ont été mis en place il faut donc les configurer convenablement afin que le système ne soit pas perturber par l’ajout d’une ou plusieurs features. De plus, il faut vraiment acquérir quelques réflexes comme  la lecture massive de documentation, avec bien évidemment la bible d’intel ; je vous l’accorde c’est pas le plus facile :]. Voilà pour le blabla d’introduction, attachez vos ceintures, et plongeons dans les entrailles de la pagination.

I] La pagination.

La pagination est une fonctionnalités proposé par le processeur ; celle-ci permet de faire manipuler au processeur des adresses virtuels et de la mémoire virtuel. Sur un système 32bits, grâce à cette feature nous disposons de 4go de mémoire ; et cela indépendamment du matériel informatique dont vous disposez. Le secret de la technique est pourtant simple, il suffit de mettre en place des « traductions » d’adresses ; l’unité de segmentation ici rentre en jeu car elle nous permet d’avoir une adresse virtuel (offset+base) et cette adresse virtuel grâce à l’unité de pagination sera transformé en adresse virtuel afin de pointer le contenu en mémoire physique.

memory_protected_principles

Pour illustrez cela, il suffit de regarder deux processus sous windows ; en effet pour 90% d’entres eux ils sont chargé en mémoire à l’adresse 0x00400000 (spécifié dans le champs ImageBase du pe) et bien l’astuce derrière cela est tout simplement  le fait que l’adresse virtuel 0x00400000 va pointer sur une adresse physique différente. Tous l’espace d’adressage virtuel du processus peut être inter changé très facilement.

Maintenant que vous savez plus ou moins de quoi je vous parle, nous pouvons dégagez les avantages de la pagination :

  • Faire abstraction de la mémoire disponible sur la machine
  • Permettre de basculer l’espace d’adressage virtuel très facilement
  • Cloisonner un processus dans un espace virtuel
  • Facilite la gestion de la mémoire pour un système multi-tâche
  • Faire apparaitre un espace mémoire virtuel comme contigüe

Enfin bref, il y a vraiment tout un tas d’avantage à l’activer :). Maintenant entrons un peu plus dans les détails, pour activer la pagination il faut activer le bit n°31 du cr0 (cr0.PG), et l’adresse du répertoire de table de page se trouve dans le registre de contrôle cr3  :

//On set la pagination en modifiant le bit n°31 (debut à 0) à 1 (cr0.PG)
asm volatile
(
"movl %cr0, %eax\n"
"or $0x80000000, %eax\n"
"movl %eax, %cr0\n"
);

Une fois se mode activé, la mémoire virtuel est découpé en page de taille de 4Ko/2Mo/4Mo selon la configuration des différents registres de contrôles :

SizePage

En ce qui nous concerne, les pages seront de 4k. Dans ce projet la pagination n’apportera « rien » à l’os ; comprendre ici que si j’ai choisis d’ajouter quelques règles de pagination, c’est tout simplement pour voir comment on gère tout cela. A présent parlons de comment retrouver l’adresse physique « pointé » par une adresse virtuel dans notre implémentation ; nous utilisons donc 2indirections (PDE=>PTE)

paginationPour expliquer très succinctement le principe, nous avons un répertoire de table de page, qui contient des pointeurs vers des tables de pages ; le repertoire de table de page contient 1024 entrées, tout comme les tables de pages donc : 1024*(1024*4K) = 4GO on est bien capable d’adresser 4go de mémoire :].

Voici la définition des structures des entrées dans le repertoire de page, ou dans les tables de pages :

PDE_PTEJ’ai choisis de mettre en place 3 règles de pagination, nous pouvons les voir grâce a bochs :

 info tab
cr3: 0x00020000
0x00000000-0x003fffff  -> 0x00000000-0x003fffff
0x40000000-0x403fffff  -> 0x00400000-0x007fffff
0x50000000-0x50000fff -> 0x00800000-0x00800fff

Sur le côté gauche il s’agit des adresses virtuelles, et sur le côté droit des adresses physiques.

Je pense que j’en ai finis avec la pagination ; je suis d’accord avec vous c’est plus une présentation qu’une explication, mais le principe est tellement bien documenté qu’il est inutile d’aller paraphraser ce que qui a déjà été écris :). Mais à présent j’ai plutôt envie de vous parler de mon petit challenge ; en effet au fur et à mesure du développement j’avais derrière la tête de monter une petite épreuve plus ou moins bien réussis (et oui l’os est on ne peux plus light) je vais donc vous proposez votre mission :)).

J’ai laisser un petit stack-overflow se glisser dans mon (unique) tâche userland, votre but va être de l’exploiter afin d’appeler une fonction situer quelque part en mémoire ; cette fonction appellera le syscall de réussite qui vous affichera un message du style « You win ». La difficulté du challenge est que, bien sur, l’exploitation ne se déroulera pas comme dans la plus part des stack-overflow classique que l’on peut rencontrer ; j’ai profite de bucher les manuels intel pour implémenter une pseudo-protection. La « protection » est réalise entièrement avec des mécanismes/principes issue de la famille de processeur x86, elle est donc portable et connus d’ailleurs. L’évasion se réalisera d’ailleurs avec encore des mécanismes x86. Pour cela je vais vous fournir une archive qui contiendra le binaire compilé, le fichier de configuration de bochs, les sources brutes et exporté en html, et un readme qui va vous expliquez en détails ce dans quoi vous vous lancez. Il faut aussi être honnête, le challenge manque pas mal de « vrai » n’hésitez donc pas à fouiner les sources pour trouver quelques éléments de résolution du challenge !

Je voulais remercier les bêtas-testeurs : Deimos et Ivanlef0u, leurs feedbacks a d’ailleurs servie à propose quelque chose de presentable, et une protection à peu prêt sûr :].

Pour valider le challenge, il suffit de me mailer à 0vercl0k[at]tuxfamily[dot]org avec un petit screenshot, et petit texte racontant un peu votre évasion juste pour voir si vous êtes bien passé par là où je voulais :). Je fixe donc la deadline au 21 septembre, ça vous laisse un mois..si des personnes désirent l’allonger n’hésitez pas à me mailer ; une fois celle-ci dépasse je vous montrerais la solution du challenge. A présent je vais vous laissez, voici quelques liens qui pourraient vous interessez :

J’esepere que certains trouveront le challenge sympathique ; en attendant stay l33333tz :

C:\Hydropon-1K\sources>cat * | wc -l
   1337

Bravo à jan0 pour avoir valider le challenge en premier (22/08/09) !

7 commentaires pour le moment

Ajoutez votre commentaire
  1. Azi, mais ta pas autre chose à foutre ?

    Un porno ? des cours de tecktonik ? un match de foot ?

    haha =D

  2. nice tuto
    Merci .

  3. Merci à toi dude ;).

  4. Et au final la solution du challenge c’est quoi ? ^^

  5. Salut,
    Je viens de te l’envoyer par email :).
    Cordialement,
    0vercl0k.

  6. Excuse mon mail était faux, tu peux renvoyer stp je suis curieux ?

  7. […] 0vercl0k’s w0rld. This entry was posted in Code and tagged Hydropon1K, it’s, measure, skillz., time. Bookmark the permalink. ← SCADA sous les balles […]

Get Adobe Flash player