URL: https://linuxfr.org/users/pied/journaux/an-unexpected-linux-reverse-engineering Title: An unexpected Linux : reverse engineering Authors: Pinaraf Date: 2017年05月28日T11:57:04+02:00 License: CC By-SA Tags: arm et linux_embarqué Score: 115 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(' 0: hdr_data = fh.read(size) (file_offset, file_size) = struct.unpack('

AltStyle によって変換されたページ (->オリジナル) /