2011
01.04

Voici donc la troisième et dernière partie de cette série d'articles sur la lecture de disques Wii en Python. Maintenant que tout le travail de documentation des différentes structures et des différents formats dont on a besoin a été fait, la dernière étape est de faire quelque chose de propre et d'utilisable à partir de tout ça. En effet, des bouts de code à balancer dans un shell Python c'est loin d'être propre, même si c'est bien pour expérimenter rapidement.

Le résultat de tout ça s'appelle wiiodfs, pour Wii Optical Disc FileSystem. Il s'agit d'une application capable de monter une image de disque Wii sous Linux, mais également d'une bibliothèque pouvant être utilisée dans d'autres programmes qui auraient besoin d'accèder à un disque de Wii. Il reste encore un peu de travail à faire au niveau du packaging mais 99% du code utile est là, utilisable et fonctionnel.

La première grande différence avec ce qui a été fait lors des deux articles précédents est qu'on ne peut pas se permettre de dumper toute la partition dans un fichier temporaire, ou dumper tous les fichiers dans un dossier. C'est sale, lent et ça a peu d'intérêt. Dans wiiodfs, toute la partie déchiffrement et accès aux fichiers est faite à la volée lorsqu'on en a besoin. Toute l'architecture de la bibliothèque est donc basée sur ce besoin.

wiiodfs est séparé en 4 couches de différents niveaux. La couche de niveau n peut utiliser toutes les couches de niveau inférieur. Voici ces différentes couches expliquées en détail :

  • L'accès brut à l'image disque, aux métadonnées et à la table des partitions/volume groups. Très simple, pas de déchiffrement, pas de gestion du filesystem, uniquement de quoi lire l'image d'un point A à un point B et de quoi récupérer les informations sur les partitions du disque.
  • L'accès brut aux données d'une partition déchiffrée. C'est surement la partie la plus intéressante donc je reviendrai dessus plus tard, mais elle va en gros lire les données brutes sur la partition, les déchiffrer et retourner ces données à l'utilisateur.
  • L'accès aux fichiers sur la partition avec une API facile à utiliser : on utilise Filesystem.open qui nous renvoie un objet qui se comporte comme un fichier Python, sur lequel on peut appeler les méthodes read ou seek par exemple. On peut également lister les dossiers, récupérer la taille d'un fichier, vérifier si un fichier existe, etc.
  • Enfin, une interface permettant d'utiliser le filesystem via PyFS, une bibliothèque dont le but est de définir une interface commune pour différentes classes de gestion des systèmes de fichier afin de pouvoir les utiliser uniformément.

Comme dit juste au dessus, je pense que la partie sur laquelle il faut le plus s'attarder est la deuxième couche, celle qui gère le déchiffrement des partitions. En effet, déchiffrer des blocs de 0x8000 octets n'est pas spécialement rapide et il faut donc un moyen de garder en cache les clusters déchiffrés pour ne pas déchiffrer 20x le même cluster à la suite. Pour cela, j'ai réimplémenté un cache de type LRU. Les caches LRU sont les caches les plus simples, qui gardent un certain nombre de valeurs dans leur ordre de dernière utilisation. Ainsi, toutes les valeurs les plus récemment utilisées sont dans le cache, et les autres sont éliminées du cache au fur et à mesure qu'elles ne sont plus utilisées. On pourrait surement faire beaucoup plus intelligent mais ça n'était pas mon but ici (et de toute façon c'est déjà bien rapide).

wiiodfs fournit également un script nommé wiiodmount qui permet donc de monter une image disque de Wii sur un dossier. Pour cela, le script utilise la 4ème couche ainsi qu'une fonctionnalité de PyFS qui permet d'exporter un filesystem conforme à l'API de PyFS via FUSE. C'est magique et ça marche plutôt très bien lors de mes tests.

Pour conclure cette série d'articles, je vais simplement dire que c'était une aventure très intéressante pour moi : je connaissais très peu la Wii il y a une semaine et l'implémentation de wiiodfs m'a permi de comprendre un certain nombre de notions utilisées par la console de Nintendo, par exemple tout ce qui concerne le chiffrement des données. wiiodfs est surement loin d'être fini ou même utilisable pour tout le monde (il faudrait que je prenne le temps de faire le packaging par exemple) mais c'est une implémentation simple et efficace d'un filesystem assez peu documenté, dont j'espère qu'elle sera utile à des gens 🙂

Finissons par des liens et des remerciements :

  • Wiiodfs, dépot Mercurial du projet.
  • Wiibrew, une de mes principales sources de documentation.
  • Dolphin, un émulateur GC/Wii assez génial et libre.

Pendant les prochains jours j'essaierai de prendre le temps d'écrire de nouveaux articles sur les formats de fichier que j'ai trouvé dans le FS de Tales of Symphonia : Dawn of the New World. Des trucs comme les textures, les modèles, les sons, les musiques, etc. Stay tuned!

5 comments so far

Add Your Comment
  1. Super boulot ! Bravo 🙂

  2. Joli travail ! C’est sympa de nous faire partager tes travaux/expériences/projets.

    • A priori je suis parti pour le format des sons et musiques pour mon prochain article. Avec un peu de chance ça sera avant ce soir, sinon demain après midi.

      • ou plus tard il semblerais ^^

        En tout cas ils sont toujours bien sympas ces articles 🙂

        • Oui, j’ai été bien occupé ces dernières semaines et en plus j’ai un peu de mal à trouver comment présenter facilement un format complexe.

          Si ça intéresse quelqu’un par contre j’ai du code pas très lisible mais qui fonctionne bien (et plutôt rapidement).

*