Hacking d'une console de jeu (à pris abordable)

Reverse engineering d'une console de jeu

Le

Ayant envie d'explorer un peu plus encore le monde du "hardware hacking", j'ai acheté une petite console de jeu pas trop chère (16€ quand même) dans l'objectif de la bidouiller un peu. A l'inverse de mon article sur le hacking d'un jeu de Gameboy que je vous invite à lire (disponible ici), on ne connait pas l'architecture de la console, on n'a pas de code ni de données. En bref, on a rien. Des petites photos de la bête juste dessous:

Console rétro violette vue de face, avec écran TFT éteint et boutons roses, avant le démontage

Dos de la console rétro : compartiment ouvert accueillant les 3 piles AAA de 1,5 V

Il s'agit d'une console rétro proposant 200 jeux dans un style 8 bits. La console dispose d'un écran TFT de 2,8 pouces et est alimentée avec 3 piles AAA. Comme il y a 200 jeux, j'espère trouver quelques mémoires externes au microcontrôleur.

Console rétro allumée : un jeu de labyrinthe 8 bits s'affiche sur l'écran TFT de 2,8 pouces

Je commence par la démonter. On remarque directement une grosse tache d'epoxy (en noir), qui cache le CPU. Comme je ne sais pas comment l'enlever, je m’intéresse aux autres composants. On remarque une carte avec de nombreux pin et la référence MW20200529 inscrite dessus, peut-être une mémoire ?

Carte électronique de la console démontée : CPU sous une goutte d'epoxy noire et module mémoire à 44 broches

Carte électronique vue à la loupe : CPU sous epoxy encadré en orange et module MW20200529 encadré en rose

Analyse passive du composant MW20200529

En recherchant une documentation sur internet, je fini par tomber sur le PCB ici.

Schéma PCB du module MW20200529 : brochage des lignes d'adresses A0-A23, de données D0-D15, CEB, OEB, VIN et GND

Il y a 24 lignes d'adresses (A[0-23]), 16 lignes de données (D[0-15]), deux lignes nommées CEB et OEB, la tension d'alimentation Vin et le GND. Il y a donc une capacité d'adressage de :

2^{N_{A}}.N_{D} = 2^{24}.16 = 268435456bit

Avec des adresses allant de 0x000000 à 0xffffff et des données codées sur 2 octets. En ce qui concerne les deux lignes, on peut imaginer que CEB ferait référence à Chip Enable et OEB à Output Enable, mais à ce stade on ne peut pas en être sure. Elle pourrait très bien être des lignes indiquant si on écrit / lit sur la mémoire.

Je me renseigne maintenant sur la puce au centre du circuit. J'arrive à lire les inscriptions suivantes grâce à ma super loupe: "0834KFD V00560002EDGB ZD7759 JAPAN". Le terme "V00560002EDGB" donne des résultats sur google.

Site de distributeur : fiche produit de la puce mémoire BGA V00560002EDGB, classée dans les Memory ICs

Il s'agit donc d'une mémoire de la marque Toshiba. On peut décomposer le model en V00560002-EDGB. Malheureusement, mes recherches ne m'ont pas permis de trouver de datasheet. Je prends donc la décision de comprendre par moi même le fonctionnement du composant.

Analyse active du composant MW20200529

Je commence par déterminer la tension d'alimentation en mesurant la tension avec un voltmètre entre Vin et GND.

Multimètre : mesure d'environ 3,09 V entre Vin et GND du module mémoire de la console

La tension d'alimentation se situe autour de 3.10V. Je me munie maintenant de mon analyseur logique acheté sur Amazon pour pas trop chère (et qui fonctionne bien moins bien que celle de Saleae, mais qui fonctionne quand même) afin d'essayer de capturer des trames échangées entre le processeur et la mémoire.

Pour rappel:

"Un analyseur logique est un instrument permettant de capturer, d'afficher et de mesurer simultanément plusieurs signaux électroniques dans un circuit numérique."

Saleae.com

Plus simplement, c'est un oscilloscope qui mesure des signaux à deux états (LOW et HIGH), et non sur une plage continue de tension comme un oscilloscope classique.

Analyseur logique Saleae relié par ses sondes colorées à une carte de développement sur breadboard

Je branche d'abord mes jumpers (des pinces) sur des lignes au hasard (des lignes de données et d'adresses) pour voir si tout fonctionne. Pour cela, je lance la capture puis je démarre la console et j'observe si il se passe des trucs.

Analyseur logique branché par des pinces sur les lignes de données et d'adresses du module mémoire de la console

Analyseur logique : premiers changements d'état capturés sur les lignes A11, D3 et A5 au démarrage de la console

On obtient bien des résultats (des changements d'état). En zoomant un peu plus:

Analyseur logique : zoom à l'échelle de la microseconde sur les transitions des lignes A11, D3 et A5

Et en zoomant encore un peu plus:

Analyseur logique : zoom plus fin montrant les créneaux successifs sur A11 et D3 et une brève impulsion sur A5

Analyseur logique : A11 reste à l'état bas pendant que A5 oscille rapidement et que D3 change de valeur

Analyseur logique : mesure d'une impulsion de 42 ns sur la ligne de données D3

On mesure des impulsions de 42ns sur la ligne D3 et A5, soit une fréquence de 1.714 MHz (pour les plus petites) et des impulsions de 542ns (923kHz). Je branche un 4ème jumper sur la ligne A0 pour obtenir d'avantage de résultat.

Analyseur logique : quatrième sonde sur A0, impulsions de 542 ns régulières en parallèle d'un signal d'horloge sur D3

Dumper la mémoire

Maintenant je souhaite récupérer l'entièreté de la mémoire pour l'analyser. Pour cela j'ai pensé à utiliser un Arduino que je vais venir connecter à la mémoire. Comme je n'ai que 14 pins GPIO digitals sur mon arduino, je réfléchis au moyen le plus efficace pour dumper l’entièreté de la mémoire.

Idée n°1

Une première idée un peu naïve serait de dumper la mémoire petit bout par petit bout à l'aide d'un arduino:

  • Je réserve 6 GPIO digital de l'Arduino pour les 6 premiers bits d'adresses (A[0-5]), 8 pour 8 premiers bits de données (D[0-7]). Je fais ensuite varier les 6 bits d'adresses entre 0x00 et 0x3f et je note les valeurs des bits de données. Toutes les autres lignes d'adresses sont connecté à la masse.

  • Je déplace les 8 GPIO digital connectés sur les lignes D[0-7] vers les 8 autres lignes de données (D[8-15]), puis je refais varier les 6 bits d'adresses de 0x00 à 0x3f. Je note les valeurs des bits de données.

J'aurai alors les données 16 bits de l'adresse 0X00 à 0x3F, mais pour des adresses plus grandes la technique ne marche plus.

Idée n°2

J'utilise un montage à plusieurs Arduino, synchronisés entre eux, ce qui devrait marcher mais serait trop coûteux.

Schéma : trois Arduino synchronisés se partagent les bus d'adresses et de données du MW20200529 pour dumper la mémoire

Idée n°3

J'utilise mes quelques connaissances en électronique numérique et je trouve une solution moins chers. On cherche à produire un signal parallèle de type compteur sur 23 bits et lire un signal parallèle sur 16 bits. Il nous faudrait donc idéalement un registre à décalage série-parallèle à 23 bits pour envoyer les adresses et un registre à décalage parallèle-série à 16 bits pour recevoir les données.

Animation : un registre à décalage 74HC595 convertit des bits série en sortie parallèle Q0-Q7 au rythme de l'horloge

Une solution pourrait être l'utilisation d'un FPGA, mais je n'en ai pas. Je décide donc d'opter pour 3 74HC595 pour la conversion série-parallèlle et 2 74HC165.

Cet article n'est pas terminé, mais faute de temps et de moyen je le mets en pause.

Accès Restreint

Cet article n'est pas (encore) publique.
Pour obtenir un accès anticipé, contactez-moi.

[[ passwordError ]]

[[ post.title ]]

[[ post.description ]]

Le [[ post.date ]]

[[ tag ]]
[[ currentMatchIndex + 1 ]] / [[ searchMatches.length ]] 0 / 0

Sommaire

Page principale