Sommaire
- 0) Bonjour archive, qui es-tu ?
- 1) Éditeur hexadécimal, mon ami !
- 2) Le script Python
- 3) Récursion infinie…
Bonjour bonjour
Depuis quelques semaines maintenant, je suis l'heureux propriétaire (et pas privateur) d'un flipper Stern Ghostbusters, une bien belle machine bourrée de mécanique et d'électronique…
Lors de l'installation, le vendeur m'a expliqué les rudiments de la maintenance de la bête, et m'a surtout fait télécharger et installer une mise à jour du firmware, en m'expliquant qu'il avait déjà eu des gros soucis sur des machines suite à une mise à jour mal appliquée.
Le firmware pèse un petit 967MB. PARDON ? 967MB pour un flipper ?
Le poids associé à la crainte sur un éventuel soucis lors des futures mises à jour m'a donc incité à regarder le contenu de cette archive… Ceux qui souhaitent jouer également peuvent la télécharger sur le site de Stern Pinball.
0) Bonjour archive, qui es-tu ?
Le classique, quand on rencontre un nouveau fichier sans connaître son véritable format (le fichier a pour extension spk), c'est de demander à la libmagic et son utilitaire file…
$ file ghostbusters-1_13.spk
ghostbusters-1_13.spk: data
Ha. Allons bon…
$ strings ghostbusters-1_13.spk | head -n 10
SPKS
SPK0|e
SIDX
spike
STRS
etc/init.d/game
etc/init.d/game_monitor
etc/init.d/update
etc/fstab
usr/local/spike/kernel.sha1
Mais qu'est-ce-donc que ceci ? Je ne connais aucun format d'archive répondant à ce format, et mes recherches sur internet n'ont rien trouvé. On va continuer avec strings quelques instants… tentons la chance.
$ strings ghostbusters-1_13.spk | grep vermagic
vermagic=2.6.30 mod_unload ARMv5
Ha ben voilà, on a un noyau Linux dans le flipper ! Ça c'est une bonne surprise, j'ai maintenant un Linux de plus à la maison… Et autre bonne surprise, ce n'est pas un format compressé vu que la chaîne est encore en clair.
Mais ça ne m'explique pas ce qu'est ce format d'archive, car si le noyau est bien un Linux, alors ce n'est pas une archive disque qui elle serait reconnue par file. Étrange, étrange.
1) Éditeur hexadécimal, mon ami !
Pour la suite des opérations, j'utilise l'excellent okteta et sa très pratique table de conversion. Le but sera de comprendre le format du fichier pour pouvoir ensuite l'extraire.
À l'ouverture, on remarque donc en premier élément SPKS, suivi d'un ensemble de 64 bits avant la chaîne SPK0.
Que peuvent contenir ces 64 bits, qui sont : 0xEFBB693C 0x02000000… Après un peu de creusage de méninges, en little endian, les 32 premiers bits correspondent à l'offset pour atteindre la fin du fichier… donc la taille de la section qui suit ? Et 2 pourrait être un nombre d'éléments ou un flag quelconque ?
Laissons ce 2 pour plus tard, et continuons.
SPK0 est suivi à son tour d'un entier de 32 bits puis d'un mot «SIDX»… Il semblerait que ce format utilise des en-têtes ASCII de 4 lettres pour chacune des sections, ce qui va beaucoup nous aider.
L'entier de 32 bits est à son tour… un offset, qui nous mène à un nouveau «SPK0» dans le fichier. Et ce SPK0 est suivi d'un offset qui nous mène à la fin du fichier…
Donc le 2 dans SPKS indiquait un nombre d'éléments, des «sous-archives» probablement… Tout de suite après se trouve un SIDX, suivi par un entier de 32 bits indiquant sa taille…
Et on peut itérer ainsi… Le bloc SPKS contient N SPK0 qui contiennent successivement un SIDX, puis des STRS contenant la liste des noms de fichier, puis une liste de FINF, autant qu'il y a de strings, puis une section SDAT qui ne contient par contre pas d'information de taille (elle commence par un 0 sur 32 bits) mais juste les fichiers concaténés les uns aux autres… zut, la structure change sur cette partie, probablement pour simplifier la construction du fichier.
Vu les noms, on peut se douter que FINF contient les informations sur les fichiers. Le premier fichier est etc/init.d/game, et le second etc/init.d/game_monitor… Lisons donc les données, ces fichiers commenceront probablement par un shebang.
SDAT est suivi, comme je l'ai dit, de 4 octets à 0, puis… d'un #!/bin/sh, commençant à l'adresse 0x6E0. Bingo. Il n'y a plus qu'à localiser le suivant… Il se situe à l'adresse 0x1F83. Donc le fichier pèse 6307 octets. Et quand on cherche 6307 dans le premier bloc FINF, on le trouve en troisième position. Donc un FINF contient 32 bits pour indiquer la taille du FINF, 32 bits de on sait pas quoi (ils sont à 0), puis la taille du fichier.
Nous voilà désormais équipés pour écrire le script python qui décompressera l'archive.
2) Le script Python
Quick and Dirty devrait être une variante officielle de Python.
#!/usr/bin/env python3
import os
import os.path
import struct
import sys
fh = open(sys.argv[1], "rb")
hdr_magic = fh.read(4)
assert(hdr_magic == b'SPKS')
whole_size, part_count = (struct.unpack('<II', fh.read(8)))
print("File size is %s, for %s parts" % (whole_size, part_count))
for part in range(part_count):
files = []
print("Working on part %s" % part)
hdr = fh.read(4)
assert(hdr == b'SPK0')
# Following the header is the part size
(whole_size,) = struct.unpack('<I', fh.read(4))
header_start = fh.tell()
assert(fh.read(4) == b'SIDX')
(idx_size,) = struct.unpack('<I', fh.read(4))
fh.read(48)
assert(fh.read(4) == b'STRS')
(strs_size,) = struct.unpack('<I', fh.read(4))
strings = fh.read(strs_size).split(b'\0')
# Now the file infos
hdr = b''
i = 0
while hdr != b'FEND':
hdr = fh.read(4)
(size,) = struct.unpack('<I', fh.read(4))
if size > 0:
hdr_data = fh.read(size)
(file_offset, file_size) = struct.unpack('<II', hdr_data[:8])
files.append((strings[i], file_size))
i += 1
# Now we should have reached SDAT
assert(fh.read(4) == b'SDAT')
fh.read(4) # Skip 4 \0
header_end = fh.tell()
i = 0
for (filename, file_size) in files:
print("Extracting %s..." % (filename))
os.makedirs(os.path.dirname(filename), exist_ok=True)
tgt = open(filename, "wb")
tgt.write(fh.read(file_size))
tgt.close()
i += 1
assert(fh.read(4) == b'SEND')
Et on peut lancer le script, dans toute sa splendeur…
$ python3 spk.py ghostbusters-1_13.spk
File size is 1013562351, for 2 parts
Working on part 0
Extracting b'etc/init.d/game'...
Extracting b'etc/init.d/game_monitor'...
Extracting b'etc/init.d/update'...
C'est-y pas beau ?
3) Récursion infinie…
Dans les fichiers extraits, nous avons un fichier binaire ARM usr/local/bin/spk… SPK ? C'est trop tentant…
Mais ma machine est hélas en amd64, pas en ARM.
QEMU à la rescousse les amis, dans son mode le moins connu, le mode «user», qui permet de lancer un binaire Linux d'une architecture X sur un Linux d'une architecture Y…
$ qemu-arm ./usr/local/bin/spk
Usage: spk command [ command_opts ]
spk install [-s] [-f] PACKAGE_FILENAME
spk list PACKAGE_FILENAME
Hoooo que c'est beau… Nous avons là le programme pour extraire l'archive, c'est magique ! Il suffisait donc d'extraire l'archive pour pouvoir l'extraire…
Et la commande list fonctionne bien pour lister le contenu de l'archive. Et excellente nouvelle, des sha1sum et des md5 (on sait jamais, pour les collisions ?) sont donnés pour chaque fichier, ce qui devrait un peu protéger les mises à jour…
Par contre, le contenu est beaucoup moins intéressant pour de futurs dépannages du flipper en cas d'incident plus poussé : tout est dans un fichier image.bin de 973638KB, à un format inconnu… jusqu'à un prochain journal, si j'en ai le temps…
PS: Alors, j'ai fait cette recherche…
$ strings ghostbusters/game | grep -i openssl
SHA1 part of OpenSSL 1.0.2 22 Jan 2015
Je veux pas critiquer, mais il y a des outils de communication, propriétaires, qui utilisent encore aujourd'hui des OpenSSL plus vieux qu'un flipper… la honte…
# Noms ou Listes >?>
Posté par freestyle . Évalué à 5.
Tu en connais ou tu sais ou on peut trouver une liste fiable , histoire de savoir quoi et pourquoi eviter certain de ces outils
En tous cas merci pour ce journal très rafraichissant - Du Linux dans du flipper - j'imaginais bien que Tux est partout mais là ca me surprends en bien .:)
[^] # Re: Noms ou Listes >?>
Posté par Pinaraf . Évalué à 10.
J'ai oublié de le préciser : le flipper n'est pas connecté à internet, y'a pas de prise réseau… Donc même si ils avaient utilisé OpenSSL 0.9 j'aurais pas critiqué.
Et donc l'outil de communication, imposé dans ma boite hélas, c'est Zoom…
# Super interéssant
Posté par octane . Évalué à 8.
Très interréssant et gg pour l'extraction
Au cas où et parceque j'aime bien extraire aussi des firmwares je te conseillerai binwalk et photorec (quand c'est ni chiffré ni compressé).
Ceci dit je comprends mal la raison qui pourrait pousser un flip à se mettre à jour (?). C'est pas connecté au net quand même ?
[^] # Re: Super interéssant
Posté par Pinaraf . Évalué à 10.
Alors, dans les changelogs, y'a :
1) correction de bugs ou de fautes sur les messages (et il en reste… ils doivent pas avoir de correcteur sur leur éditeur)
2) ajout de nouvelles fonctionnalités…
Cf. http://f0727d06e1d39b514478-a613b39d02a32124478c749a23d19af0.r44.cf5.rackcdn.com/ghostbusters-1_13-README.txt
On n'est pas sur un flipper mécanique, y'a un gros écran de DEL avec au moins un endroit où tu déclenches des jeux interactifs, sans bille, à contrôler au flipper
[^] # Re: Super interéssant
Posté par Nibel . Évalué à 10.
Je suppose que c'est un de ces engins :
Belle acquisition, c'est marrant de voir du Nux sur ce genre de machines, j'aurai jamais cru (je pensais même pas qu'il éxistait des mises à jour de firmware pour les flippers, c'est dire…).
J'ai hâte de voir si tu arrives à décompiler le image.bin, on pourrait imaginer changer les règles du flipper !
La majeure partie des morts l'était déjà de son vivant et le jour venu, ils n'ont pas senti la différence.
[^] # Re: Super interéssant
Posté par Pinaraf . Évalué à 6.
Je pense pas que les règles seront dans le image.bin hélas, à mon avis ça sera plutôt dans l'exécutable game à côté… Ça m'étonnerait qu'ils utilisent un système de script pour le jeu… Mais c'est à suivre…
Et sinon c'est le modèle de gauche sur la photo, le «pro».
[^] # Re: Super interéssant
Posté par Francois Revol (site web personnel) . Évalué à 6.
Sinon y a Hachoir aussi :
https://blog.pastoutafait.fr/billets/presentation-de-hachoir-sous-ubuntu
[^] # Re: Super interéssant
Posté par Patrick Trauquesègues . Évalué à -2. Dernière modification le 29 mai 2017 à 03:02.
# aptitude
hachoir-metadata VirtualBox\ VMs/Nouveau\ groupe/unstable20161204/unstable20161204.webm
hachoir-urwid --debug VirtualBox\ VMs/Nouveau\ groupe/unstable20161204/unstable20161204.vdi
Mais au deuxième fichier pris au hasard, il semble qu'il me faille creuser un peu plus avant d'utiliser de tels outils…
Bon, rien à voir avec cet article d'anthologie.
# Ca fait plaisir
Posté par Trololo . Évalué à 10.
Entre les X journaux reprenant avec quelques modifications, ce qu'on trouve déjà ailleurs (but in English), j'ai pris grand plaisir à lire ton journal.
Retour aux sources, Pas de blabla inutile, Un PB, une solution …..on met les mains dans le cambouis et on avance pas à pas …..
A force d'entendre que DLFP c'était mieux avant …. …lire les péripéties d'un bidouilleur qui plutôt que d'attendre qu'on lui trouve une réponse à sa question se casse la tête pour trouver lui même une solution…. rempli mon cœur de joie
Merci Pinaraf
[^] # Re: Ca fait plaisir
Posté par AlexTérieur . Évalué à 8.
Je me joins aux louanges. Merci.
Sinon, près d'un giga, flipper électronique ou pas ça fait un peu beaucoup non ? Ça ne sentirait pas une intégration d'une distrib' Linux à la va vite ? Ça m'étonnerait que tout le giga soit entièrement exploité… simple interrogation.
[^] # Re: Ca fait plaisir
Posté par Pinaraf . Évalué à 10. Dernière modification le 28 mai 2017 à 17:42.
Alors dans l'archive d'un giga, il n'y a pas tout le système (!!). Il n'y a pas le shell par exemple, donc les scripts ne risquent pas de marcher.
Tout est sur une carte SD, mais où était le fun de prendre la carte SD pour la brancher sur un PC plutôt que d'analyser le contenu de l'archive ? :) (plus sérieusement, j'ai préféré jouer avec le flipper que l'ouvrir pour le moment, et en plus comme ça vous pouvez «reproduire»)
Sinon quelques chaines intéressantes extraites de la mise à jour :
- GCC: (Sourcery CodeBench Lite 2014.05-29) 4.8.3 20140320 (prerelease)
- /scratch/maciej/arm-linux-2014.05-rel/obj/glibc-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu/default/csu/abi-note.o
Ça semble correspondre à un usage de ça : https://sourcery.mentor.com/GNUToolchain/release2795
Ils auraient sûrement à gagner à utiliser buildroot, j'enverrai peut-être mon CV pour leur proposer de l'aide :)
[^] # Re: Ca fait plaisir
Posté par Pinaraf . Évalué à 10.
Et j'oublie le principal dans la question… dans le giga, 99% des données c'est vraiment les données du jeu (image.bin). Je n'ai pas encore analysé, mais il y a probablement :
- toutes les vidéos en 4/16 couleurs sans aucune forme de compression
- tous les sons, sans aucune compression
- toutes les polices, sans aucune compression (je me répète ?)
J'ai parcouru un peu le fichier à l'éditeur hexadécimal et ça ressemble vraiment à du stockage sous cette forme (on voit des formes se dessiner en de-zoomant)
Mais sans aucune forme de compression, une vidéo de 128x32 pixels, en disons 4 couleurs, 30 FPS… déjà 240 kB par seconde. Juste quand tu gagnes une extra-ball, t'as une vidéo de ~5 secondes, donc l'extra coûte 1200 kB. Et des animations sur cet écran, il y en a beaucoup beaucoup.
Et si on ajoute à ça les fichiers sonores, on part sur du volumineux, nécessairement.
Après si ça se trouve, les sons sont en MP3 dégueu, les images compressées à mort, les polices dans d'autres fichiers… mais j'y crois pas :)
[^] # Re: Ca fait plaisir
Posté par AlexTérieur . Évalué à 1.
Merci pour tes réponses :)
Tu dois avoir raison, il doit avoir des données "multimédias" non compressées, je n'y avais pas pensé, l'explication est plus raisonnable, ce sont quand même de beaux bijoux.
[^] # Re: Ca fait plaisir
Posté par reynum (site web personnel) . Évalué à 2.
Moui sur DLFP on entend surtout "c'était mieux à vent" ;-)
+1
kentoc'h mervel eget bezan saotred
[^] # Re: Ca fait plaisir
Posté par freem . Évalué à 2.
L'une des formulations est probablement due à un bug du logiciel de synthèse bouchotte. Il faudrait faire un rapport de bug je pense.
# emulateur de flipper
Posté par jemore . Évalué à 9.
Peut etre pourrais-tu glaner quelques info sur le format BIN du coté de PinMame : un émulateur de flipper, qui permet d'executer les ROM des différents fabricants.
[^] # Re: emulateur de flipper
Posté par Pinaraf . Évalué à 9.
Merci, je regarderai.
Pour le moment, je prévoyais de m'amuser avec mon éditeur hexadécimal…
J'ai joué avec les contrastes pour que ça soit lisible… Sur la toute droite c'est l'éditeur hexadécimal qui affiche les offset, au milieu les valeurs en hexa et à droite décodées en ascii…
[^] # Re: emulateur de flipper
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à 1.
Ben, je pense que to fichier data, c'est juste les images/animations!
On arrive a lire le texte en plissant les yeux.
[^] # Re: emulateur de flipper
Posté par Pinaraf . Évalué à 2.
Tout à fait, la capture d'écran me paraissait assez claire : on y voit en hexadecimal le logo de Stern Pinball.
Cf un futur journal pour les détails sur ce fichier :)
# C'est pas la taille qui compte mais comment on s'en sert...
Posté par Psychofox (Mastodon) . Évalué à 3.
967MB ça fait quand même beaucoup quand on compare aux roms de Devil Crush / Devil Crash qui font respectivement 205kB (pcengine) et 385kB (megadrive).
# Porté en logiciel?
Posté par ʭ ☯ . Évalué à 4.
Il n'y a plus qu'à faire une table avec ces données pour le seul flipper libre que je connaisse sous Linux : pinball.
Sinon, ça utilise peut-être ce moteur libre?
⚓ À g'Auch TOUTE! http://afdgauch.online.fr
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.