1 points par GN⁺ 2024-01-23 | 1 commentaires | Partager sur WhatsApp
  • TheZZAZZGlitch montre qu’en enregistrant le son de crash d’une Game Boy Advance, il est possible d’identifier les données de jeu contenues dans la cartouche et, au final, de restaurer la même ROM
  • Le principe consiste à interpréter l’audio émis après le crash comme des données de ROM, mais cela nécessite de nombreux ajustements selon le format source, ce qui rend l’approche difficile à utiliser comme outil de dump universel
  • Sur plus de 4 heures d’enregistrement, une forme d’onde caractéristique apparaît vers 1 h 50, puis les sons d’instruments et les échantillons audio du jeu se font entendre successivement
  • Avec un script Python et une correction d’alignement, il atteint 99,76 % de précision, mais la ROM ne démarre pas ; en fusionnant 3 enregistrements avec un algorithme de vote majoritaire, la précision monte à 99,979 %
  • Après fusion de 7 enregistrements et filtrage des espaces vides, il obtient une correspondance à 100 %, confirmant la possibilité expérimentale de restaurer une ROM GBA uniquement à partir du son de crash

Une expérience qui lit les données ROM dans le son de crash

  • TheZZAZZGlitch démontre que le son émis par une GBA après un crash logiciel peut contenir des données de jeu
  • Une GBA crashée peut continuer à produire des sons basés sur les données internes de la cartouche, et l’analyse de cet audio avec du matériel et du code spécialisés permet d’identifier de quel jeu il s’agit
  • Cette méthode n’est toutefois pas un moyen simple de dumper les données d’une cartouche, ni une solution prête à l’emploi
    • Elle demande beaucoup de réglages adaptés aux différents formats sources

Une forme d’onde révélée dans un long enregistrement

  • Après avoir fait crasher la GBA et enregistré pendant plus de 4 heures, une forme d’onde caractéristique apparaît vers 1 h 50
  • Dans les segments suivants, on entend dans l’ordre de véritables sons d’instruments et échantillons audio inclus dans le jeu
  • Le reste des données s’entend comme des données 8 bits à 13 100 Hz, avec certains passages au rendu très étrange

Script Python et première tentative de restauration

  • TheZZAZZGlitch prépare, « après 2 jours de correction de bugs », un script Python capable de lire un enregistrement propre d’un dump de crash de GBA
  • Les données de la ROM contiennent de grandes zones d’octets nuls, qui apparaissent comme du silence et sont difficiles à parser depuis l’audio
  • Après avoir exécuté un script séparé pour réaligner les sections selon leur position dans la ROM d’origine, la ROM restaurée atteint 99,76 % de précision
  • Cette ROM ne démarre toujours pas, et la méthode, qui utilise des données de ROM connues pour révéler les données inconnues, relève techniquement de la « triche »
    • Même en procédant entièrement à l’aveugle, certaines hypothèses et estimations resteraient applicables

Fusionner plusieurs enregistrements pour améliorer la précision

  • L’étape suivante se concentre sur l’amélioration de la qualité d’enregistrement
  • En fusionnant 3 enregistrements avec un algorithme de « vote majoritaire », la précision monte à 99,979 %
  • La ROM produite parvient à démarrer, mais le texte est corrompu et un crash survient sur l’écran titre
  • En combinant ensuite 7 enregistrements et en filtrant les espaces vides, il obtient une correspondance à 100 %

Matériel physique et expériences supplémentaires

  • Dans la seconde moitié de la vidéo, il vérifie aussi comment cette méthode fonctionne sur du matériel physique
  • Il expérimente également avec d’autres jeux, tout en enquêtant sur un mystère lié au code ARM présent dans une cartouche clone
  • Des méthodes pour obtenir de meilleurs enregistrements sont également essayées
    • L’une d’elles consiste à utiliser un « cursed adapter » qui effectue un mixdown grossier sur un seul canal

1 commentaires

 
GN⁺ 2024-01-23
Avis de Hacker News
  • Le problème lorsque 0x00 se répète longuement est lié à la récupération d’horloge (clock recovery)
    Certains flux de données numériques, en particulier les données brutes des têtes magnétiques de lecteurs de disque ou les communications série à haut débit comme Ethernet, sont transmis sans signal d’horloge séparé
    Le récepteur crée une horloge à partir d’une référence de fréquence approximative, puis aligne la phase de cette horloge sur les transitions du flux de données au moyen d’une boucle à verrouillage de phase (PLL)
    Pour que cette méthode fonctionne, les transitions de données doivent se produire assez souvent pour corriger la dérive de l’oscillateur de la PLL ; la durée pendant laquelle on peut tenir sans transition est appelée dans la spécification nombre maximal consécutif identique (CID)
    https://en.wikipedia.org/wiki/Clock_recovery

    • Autrefois, j’aimais le fait que l’on garantisse la possibilité de récupérer l’horloge et que l’on évite les problèmes de capacité de ligne grâce à des méthodes à livre de codes ingénieuses, qui traitaient soigneusement de courts intervalles de bits, comme le 8b/10b
      Par la suite, on est passé à des méthodes comme le 64/66b, qui ajoutent un court en-tête à de gros blocs de bits pour garantir des transitions d’horloge, puis font passer l’ensemble dans un brouilleur pseudo-aléatoire
    • Une autre inquiétude est qu’un endroit de la forme d’onde soit en couplage alternatif (AC coupling), empêchant le continu de passer
      Même avec une horloge parfaitement synchronisée, sur de longues séquences, un signal presque entièrement composé de 1 et un signal presque entièrement composé de 0 finissent par devenir identiques
    • Dans ce cas, cela ne semble pas très pertinent
      L’audio est analogique, il faut un DAC pour le décoder en flux binaire, et il est transmis à une fréquence fixe comme 44,1 kHz ou 48 kHz, sans synchronisation particulière
    • Sur cette page, j’ai trouvé un article très intéressant intitulé Wireless Set Number 10
      https://en.wikipedia.org/wiki/Wireless_Set_Number_10
  • Cela me rappelle le hack iPodLinux original, il y a près de 20 ans, qui avait dumpé le firmware de l’iPod de 4e génération via le haut-parleur piézoélectrique
    https://web.archive.org/web/20140810083116/http://www.newscientist.com/article/dn7085
    Par coïncidence, cela a ensuite aussi permis de faire tourner des jeux GBA sur iPod, mais jouer à Doom avec la click wheel et regarder des vidéos en noir et blanc était déjà largement satisfaisant

    • Bons souvenirs
      J’ai encore un iPod Classic, et après avoir amélioré la batterie, j’y ai mis quatre cartes MicroSD de 256 Go
      J’ai récemment vu un mod qui ajoute le Bluetooth, mais comme il faut remplacer la coque arrière, je ne pense pas aller jusque-là
      Il y a quelque chose d’intemporel dans son design, et aussi dans le fait de posséder directement des copies de ses fichiers musicaux
  • Content que cela reçoive davantage d’attention ici
    C’était déjà passé il y a quelques jours, mais c’était passé inaperçu : https://news.ycombinator.com/item?id=39037104
    La vidéo originale contient beaucoup d’éléments absents de ce court article, dont un adaptateur sur mesure bricolé par le hacker lui-même pour obtenir une qualité audio correcte sur la DS

  • Zzazz organise chaque année un concours/événement du 1er avril, qui implique généralement une certaine dose de hacking rétro ou de rétro-ingénierie
    Je recommande d’y participer
    Les éditions précédentes sont sur GitHub

  • L’architecture audio de Nintendo m’a toujours paru intéressante
    À l’origine, la NES avait un générateur d’échantillons capable de produire des formes d’onde arbitraires, et il pouvait être piloté de deux façons
    L’une consistait à lui fournir une adresse mémoire : il lisait les bits et les traitait comme une forme d’onde très simple, où 1 signifiait « augmenter la valeur de un » et 0 « diminuer la valeur de un », si bien que pour produire une forme d’onde plate, il fallait répéter quelque chose comme 10101010
    L’autre consistait à ce que le CPU fournisse directement en continu une « valeur initiale » pour piloter la puce, ce qui, en pratique, était plus rapide que de faire lire les bits en RAM par le pilote audio
    Le problème, c’est que cette méthode accaparait tous les cycles CPU et ne pouvait donc être utilisée que lorsque rien d’autre ne se passait
    Des jeux comme Battletoads s’en servaient pour jouer des coups de batterie de meilleure qualité pendant que l’action était à l’arrêt : sur l’écran-titre, lors de l’effet « croustillant » où toute l’action s’interrompt brièvement au moment de porter le coup final à un ennemi, et dans la mémorable musique de pause
    Voici une démo dans laquelle le jeu bascule entre le mode de pilotage direct et le mode où la puce lit les échantillons. Retro Game Audio a publié une vidéo modifiée avec un émulateur, qui montre le moment où l’on entre dans la sous-routine de pilotage direct : https://www.youtube.com/watch?v=JGT0FM3yh-w

  • Je me demande pourquoi ce genre de chose arrive à la base
    Est-ce courant que ces jeux « déversent » leur état sous forme audio ? Est-ce un outil de débogage intentionnel pour les développeurs de jeux ?

    • La vidéo précédente de l’auteur[1] explique les détails techniques de ce comportement
      En gros, le son de la GBA streame l’audio depuis un tampon en RAM, et une interruption doit indiquer au matériel de relire depuis le début du tampon
      Mais si l’interruption ne se produit pas, comme quand le jeu plante, le flux audio dépasse le tampon et se met à lire d’autres zones de la mémoire
      [1] https://www.youtube.com/watch?v=wSWNkpqjtQY&t=361s
    • C’est assez rare, et ce n’est pas non plus un outil de débogage intentionnel
      En théorie, la GBA aurait pu « arrêter » l’architecture quand un jeu plante, ou avoir un watchdog qui lie une mise à jour d’état devant s’exécuter périodiquement à une interruption non masquable et redémarre si cette mise à jour s’arrête
      Mais ce genre de fonction aurait coûté plus cher, donc la GBA n’en a pas
      Nintendo a en quelque sorte choisi l’approche traditionnelle des anciens fabricants de cartouches de jeu : « si notre jeu n’a pas de bug, nous n’avons pas à nous soucier du comportement d’un état matériel indéfini »
      Ainsi, quand un jeu GBA se retrouve dans un état de plantage comme une boucle infinie avec les interruptions désactivées, la puce audio ne sait pas que le système a planté et continue simplement à lire des bits consécutifs de la RAM pour les convertir en son
      Comme les routines de nettoyage qui géraient les lectures en fonctionnement normal ont disparu, elle continue à lire jusqu’à finir par atteindre les bits représentant les valeurs de la ROM de la cartouche
  • C’est vraiment absurdement impressionnant
    J’ai l’impression que des techniques comme l’algorithme de vote majoritaire utilisé ici sont probablement sous-exploitées dans de nombreux secteurs

    • Si ça vous intéresse, des techniques sophistiquées de restauration de signaux bruités existent maintenant depuis près d’un siècle
      Les supports de stockage magnétiques fonctionnent fondamentalement sur le même principe que ce hack
      https://en.wikipedia.org/wiki/Partial-response_maximum-likelihood
      On pourrait appliquer la même idée ici, puisque le contenu d’une ROM GBA aura de forts biais
      Le vote majoritaire gaspille beaucoup d’informations
    • Une application intéressante consistant à prendre la valeur la plus fréquente, ou plus généralement la médiane, consiste à supprimer le bruit ou les personnes de plusieurs photos prises au même moment
      Il suffit de superposer toutes les photos puis de ne garder que la médiane pour chaque pixel[1]
      [1]: https://patdavid.net/2013/05/noise-removal-in-photos-with-median_6/
    • C’est assez courant en récupération de données
      On lit l’image disque en boucle et on applique une décision par quorum, puis quand on obtient un résultat qui passe la somme de contrôle, on regarde si ça fonctionne correctement
      S’il existe des sommes de contrôle de plus haut niveau, comme des signatures de fichiers, c’est encore mieux pour une validation supplémentaire
      C’est aussi utilisé dans certaines applications aérospatiales
    • Je me suis dit que ça pourrait servir pour le scan de pellicules, en particulier dans des projets de fans comme 4K77
      Comme on travaille avec des copies d’exploitation potentiellement endommagées plutôt qu’avec un master pristine, utiliser plusieurs exemplaires pour supprimer les rayures et autres défauts pourrait réduire énormément le temps de retouche manuelle en postproduction
  • Le fait que 0xFF devienne 0x00 peut être dû à un condensateur de blocage du courant continu ou à un filtrage passe-haut
    Les circuits audio ne sont pas vraiment adaptés aux contenus non audibles
    Avec un peu de chance, connecter directement un oscilloscope numérique à la sortie audio de la puce améliorerait la précision de la capture, mais obtenir malgré tout une image amorçable reste assez impressionnant

    • D’après ce que je me souviens avoir lu dans les commentaires de la vidéo YouTube, l’objectif était de faire ça avec du matériel de base autant que possible
      C’est pour ça qu’il a passé des heures à répéter les captures pour moyenner les erreurs, au lieu d’utiliser un véritable oscilloscope d’acquisition de données
    • Exact, il faut produire un signal sans biais continu
      Même un schéma simple comme le codage Manchester aiderait beaucoup
      Si ça ne suffit pas, du NRZ, voire un codage convolutif, est aussi possible
      Il faut aussi envoyer une sinusoïde, ou à défaut au moins rendre la fréquence de l’onde carrée assez élevée pour ne pas être avalée par le condensateur de couplage AC
  • Dans tout ça, ce qui m’impressionne le plus personnellement, c’est la manière dont les pirates ont modifié le code pour exécuter les jeux depuis une mémoire flash inscriptible au lieu d’une ROM + mémoire volatile de sauvegarde

    • C’est une technique très courante dans les jeux Game Boy et Game Boy Advance piratés pour économiser les quelques centimes que coûte une batterie
      En fait, créer ce genre de patch n’est pas si difficile
      Les pirates rétro-ingénierent légèrement l’endroit où le code du jeu sauvegarde, puis écrivent un patch propre à chaque jeu pour flusher les sauvegardes vers la flash inscriptible
      Cela dit, les jeux GBA officiels utilisent toujours les fonctions du SDK Nintendo pour sauvegarder ; en hookant ces fonctions, il devient assez simple de créer un patch universel qui permet de sauvegarder n’importe quel jeu GBA sur une cartouche clone sans batterie
      J’ai écrit un patcheur qui fait ça, visible ici
      https://github.com/metroid-maniac/gba-auto-batteryless-patcher
  • Quelqu’un sait ce qui se passe en interne quand l’émulateur de TheZZAZZGlitch signale que le jeu essaie de sauter à une mauvaise adresse ?
    Je ne connais pas bien le processeur ARM7 utilisé dans la Game Boy Advance, mais j’ai du mal à imaginer comment il est possible de construire un appel de saut vers une valeur invalide
    Je me demande aussi ce qui se passerait si l’une des ROM mal restaurées par TheZZAZZGlitch était exécutée sur une vraie Game Boy

    • L’instruction bx permet de sauter vers une adresse arbitraire stockée dans un registre
      Et si on exécute la ROM mal restaurée sur une vraie Game Boy, elle plantera, puis finira par commencer à jouer la ROM dans le haut-parleur
      C’est tout l’intérêt de la vidéo :)
    • Il est probable que l’émulateur n’émule que les accès aux zones valides de la carte mémoire de la GBA, et qu’il lève cette erreur lorsqu’une zone invalide est accédée
      Sur le vrai matériel, ce qui se passerait… qui sait :)