
Nous vivons à une époque incroyable. Autour de nous, une multitude de technologies: téléphones, ordinateurs, montres intelligentes et autres gadgets. Chaque jour, les fabricants lancent de plus en plus d'appareils sur le marché. La plupart d'entre eux sont destinés à une vie courte et lumineuse (ou pas): une puissante société de marketing au moment de la sortie, 1-2 ans de support complet par le fabricant, puis un lent oubli. Les appareils simples peuvent fonctionner pendant des années après la fin de la période d'assistance officielle. Avec les appareils intelligents, cela devient plus difficile. C'est bien si le gadget continue de fonctionner au moins après la déconnexion des serveurs / services du fabricant. Et c'est une chance si la prochaine mise à jour du système d'exploitation, des pilotes ou d'autres logiciels ne bat pas la compatibilité.
Malheureusement, les événements se développent de plus en plus selon un scénario pessimiste. Et 5 à 10 ans après l'achat, nous avons entre nos mains des appareils techniquement solides, qui ne peuvent néanmoins pas être utilisés en raison du manque de support logiciel. Bien sûr, un gadget cassé est désagréable. Mais beaucoup plus désagréable s'il existe des données utilisateur dans un format incompatible avec quoi que ce soit. Ces données peuvent être considérées comme perdues si l'appareil cesse de fonctionner. Dans mon cas, le pire n'est pas encore arrivé, mais les alarmes sonnent déjà.
Il y a donc la célèbre société Korg, qui produit des équipements musicaux de très haute qualité. En 2010, j'ai acheté un synthétiseur de cette société pour pratiquer la musique comme passe-temps. La microstation Korg est un modèle assez avancé. Entre autres choses, il a un séquenceur à bord pour enregistrer ses pistes et peut écrire des données sur une carte mémoire au format SNG propriétaire. Il est possible d'exporter vers un format midi commun, mais presque toutes les métadonnées sont perdues: informations sur les effets et filtres superposés, divers réglages d'instruments virtuels, etc. Le problème principal pour moi personnellement est la vitesse de transition vers l'enregistrement des idées musicales. La muse est une création fantaisiste, et la plupart du temps je tombe sur une idée intéressante simplement en improvisant ou en jouant quelque chose de simple. Plus vite j'appuie sur le bouton d'enregistrement sans me promener dans le menu, plus je peux répéter et enregistrer un fragment intéressant, qui à l'avenir pourrait faire partie d'une œuvre à part entière. Bien sûr, cette approche est imparfaite, mais nous parlons d'un passe-temps. D'une manière ou d'une autre, depuis près de dix ans, j'ai accumulé environ mille croquis musicaux et croquis au format SNG.
La cloche sonna sous la forme d'une série de pépins du synthétiseur, nécessitant un clignotement de l'appareil. Et j'ai pensé à convertir toutes mes données accumulées au format Midi, d'autant plus que cela facilitera beaucoup leur stockage, leur organisation et leur édition. La recherche du convertisseur dans Google n'a rien donné. Il y a beaucoup de demandes sur toutes sortes de forums, l'histoire dure depuis 20 ans, sinon plus. Tout ce que j'ai trouvé était l'ancien utilitaire Windows de quelqu'un d'autre, naturellement incompatible avec mes fichiers.
Et puis j'ai décidé d'essayer de voir en quoi consiste ce format SNG? Peut-être que quelque part à l'intérieur, il y a des données MIDI normales que vous pouvez facilement extraire et enregistrer?
Une tentative de résoudre le problème "front"
Ainsi, à partir des instructions du synthétiseur, vous pouvez découvrir que le format SNG est un conteneur dans lequel les soi-disant «chansons» sont stockées. Chaque chanson contient 16 pistes de séquenceur avec des données musicales, ainsi que des paramètres pour les sons et les effets. Lors de l'exportation au format Midi via le menu du synthétiseur, chaque «morceau» est exporté vers un fichier .MID distinct, et tous les paramètres de sons et d'effets sont perdus. Parce que Je joue mes idées sous la forme la plus simple et sans effets, le problème est précisément un grand nombre de fichiers SNG et l'inconvénient du processus de conversion manuelle. Voyons si ce processus peut être accéléré ou automatisé.
Rappelons d'abord ce que sont les données MIDI. En termes simples, il s'agit d'un flux d'événements musicaux: appuyer et relâcher une touche, appuyer et relâcher une pédale de sustain, changer le tempo, le patch (instrument virtuel) et d'autres paramètres. Chaque événement contient un delta temporel à partir du moment de l'événement précédent et des données, par exemple, l'intensité et la hauteur de la note. Le format de fichier midi est très simple: en plus des en-têtes et des données elles-mêmes, il n'y a pratiquement rien.
Le rose est un événement Note On. Le jaune pâle est un delta du temps. Bleu - Événement Note Off.Essayons de chercher nos données midi dans le fichier SNG. Pour ce faire, écrivez une séquence de plusieurs notes sur le synthétiseur et exportez-la dans les deux formats. Parce que Puisque nous ne savons pas exactement où se trouvent les données musicales dans les fichiers binaires, nous allons essayer de répéter le processus avec différentes séquences de notes.
Ci-après, j'utilise l'éditeur Hex Synalyze It! Ses capacités à l'avenir nous seront très utiles. En attendant, utilisez simplement la fonction de comparaison binaire.

En fait, seul le nom de la «chanson» coïncidait. En comparant deux fichiers SNG avec des séquences de notes différentes, nous pouvons approximativement deviner où exactement les données musicales sont stockées, mais pour l'instant cela ne nous aidera en aucune façon - le format des données est différent. Le fichier lui-même est dix fois plus volumineux que le fichier Midi et semble contenir beaucoup d'informations supplémentaires. Vous pouvez voir la signature KORG dans les quatre premiers octets et quelques autres lignes, y compris le nom du «morceau» et les noms des patchs (tons) assignés aux pistes.
Analyse de la structure des blocs de données
Cela pourrait être accompli si, heureusement, il n'y avait pas d'outils qui facilitaient l'analyse et la compréhension de la structure des données binaires. Le même programme Synalaze It! Nous aidera à cela, ce qui vous permet de créer et d'appliquer une «grammaire» pour l'analyse des fichiers binaires.
La grammaire est une structure descriptive hiérarchique qui vous permet de représenter des données binaires sous une forme lisible par l'homme. Le programme vous permet de télécharger la grammaire pour certains formats. Par exemple, pour le même midi:

Pour le format SNG, aucune grammaire toute prête n'était attendue. Eh bien, voyons ce que nous pouvons extraire du fichier par nous-mêmes.
Commençons par le titre. En règle générale, cette partie contient la signature du fichier, les informations de version, les tailles et les décalages des blocs de données. Après avoir comparé plusieurs fichiers SNG différents, nous trouvons les parties invariables et prêtons une attention particulière à celles qui changent

Créez une structure de titre dans l'éditeur de grammaire. Les 4 premiers octets sont évidemment la signature du fichier. Supposons que les 4 octets suivants sont versionnés. Les quelques dizaines d'octets suivants ne changent pas et ne contiennent rien d'intéressant - nous allons créer pour eux des données binaires de la taille appropriée. Mais alors le plaisir commence. Vous pouvez remarquer certains modèles dans le comportement des octets aux décalages 0x13 et 0x1b. La seconde semble correspondre au nombre de «chansons» dans notre fichier. Et le premier augmente également avec la quantité de données dans l'en-tête - cela semble être la taille, seul le compte à rebours ne vient pas du début du fichier, mais de l'octet suivant 0x14. À ce stade, nous ne pouvons que deviner le type de données numériques. Supposons que la taille soit de type UInt32, c'est-à-dire prend 4 octets. Ajoutez-les à notre structure. Maintenant, nous pouvons définir la taille de la structure d'en-tête (taille + 20).

Grammaire avec structure d'en-tête de fichier ajoutée Voyons ce qui vient ensuite. Si vous regardez attentivement, vous remarquerez que les abréviations à trois lettres sont dispersées dans le fichier: SNG1, SDK1, SGS1, etc. Ces caractères se trouvent dans tous les fichiers SNG, nous pouvons donc supposer que ce sont des signatures de certains blocs. De plus, notre titre s'est terminé avec beaucoup de succès juste avant l'une de ces signatures. Comparez le comportement des 4 octets suivants dans des fichiers de tailles différentes. On peut voir que les valeurs augmentent avec l'augmentation de la quantité de données.

Quelques expériences, analyses et calculs supplémentaires, et l'image suivante commence à émerger:

Vue graphique alternative Ainsi, notre fichier est constitué d'une hiérarchie de blocs assez simple. Il existe des blocs parents qui peuvent contenir plusieurs blocs enfants. Il existe des blocs de feuilles (dans la terminologie des arbres binaires) qui ne contiennent pas d'autres blocs.
Puis la magie commence.
Avec seulement quelques structures de grammaire, nous pouvons analyser complètement la structure du fichier de blocCréez donc une structure de modèle DataChunk avec les champs suivants (la taille est indiquée entre crochets):
id: String [4]
taille: Int [4]
hiérarchie: Int [4]
données: structure
Créez maintenant une structure parentChunk qui hérite de DataChunk. Dans la propriété de la hiérarchie, spécifiez Fixed Value 0x400 - c'est un signe du bloc parent. Assurez-vous de cocher la case Doit correspondre.
De même, créez childChunk. Dans ce cas, la hiérarchie aura deux valeurs: 0x240100 et 0x100
Ajoutez des références aux structures parentChunk et childChunk à la structure parentChunk de données - de cette façon, nous créons la récursivité.
Enfin, ajoutez une référence à la structure parentChunk dans le nœud principal.

L'ordre des éléments dans la structure de données de parentChunk doit être Variable, il est également nécessaire de définir le nombre minimum et maximum d'enfants de cette structure: 0 et Illimité, respectivement.
Appliquons les changements, et le tour est joué - notre fichier est bien analysé dans les blocs principaux

Nous ne savons toujours rien des données elles-mêmes, mais nous pouvons désormais naviguer beaucoup plus facilement dans le fichier et nous concentrer sur la recherche des informations dont nous avons besoin.
Analyser un bloc contenant une table des matières d'un fichier
Pour la formation, essayons d'analyser un bloc simple, par exemple, SDK1. Apparemment, il contient quelque chose comme une table des matières - une liste de chansons et probablement quelques décalages / tailles.

Créez une structure sdk1Chunk qui hérite de childChunk. Nous éditerons le champ ID, indiquant la signature de notre bloc dans le champ Valeurs fixes. N'oubliez pas la case à cocher Doit correspondre. Dans les données de bloc, on peut observer un motif de répétition assez évident: le nom du «morceau» et des données jusqu'ici inconnues. Notez que la taille des fragments répétés est de 64 octets. De plus, en comparant les versions de fichiers avec un nombre différent de «chansons», vous pouvez déterminer que le nombre est stocké dans les quatre premiers octets. En utilisant des calculs simples et en faisant plusieurs hypothèses, nous obtenons la version suivante de la structure dans la grammaire:

Ici, j'ai créé une structure enfant SongInfo de 64 octets et indiqué la possibilité de répéter numSongs fois. Voici le résultat de l'application de la grammaire:

Une analyse plus approfondie des dossiers reste une question technique. J'ai changé les réglages généraux du «morceau» et les paramètres des pistes individuelles sur le synthétiseur. En comparant les versions de fichiers avec diverses modifications, vous pouvez améliorer et affiner la grammaire. Après un nombre suffisamment important de telles itérations, il n'y a presque pas de données non reconnues dans le fichier. J'ai été un peu emporté par le processus et j'ai trié presque toutes les sections du fichier, même si cela n'était pas nécessaire pour la tâche d'origine.
Une petite partie de la grammaire d'un fichier SNG après 8 heures d'analyse Les détails de ce processus me manqueront - à l'avenir, nous nous concentrerons directement sur l'analyse des données musicales.
Mais plus à ce sujet dans la partie suivante. Nous y rencontrerons une tâche intéressante de conversion de données (elle est tout à fait appropriée pour les entretiens), essayons de la résoudre avec un petit script et entendons un résultat de conversion de test assez inhabituel.
Résultats préliminaires
Le besoin de fichiers binaires de rétro-ingénierie peut survenir de manière inattendue. Par exemple, pour analyser le micrologiciel de l'appareil, convertir à partir de formats de données rares, analyser les menaces numériques ou même modifier de manière triviale les sauvegardes de jeu. Des outils modernes vous permettent de résoudre ces problèmes rapidement et efficacement. Il y a environ 10 ans, je recherchais le micrologiciel d'un ordinateur portable et ce processus pourrait prendre plusieurs semaines. Il a ensuite fallu écrire manuellement des scripts pour analyser les blocs de données et disposer les structures. Avec une nouvelle approche partiellement automatisée, j'ai créé une grammaire de fichiers presque complète en seulement quelques jours.
Vous pouvez démarrer l'analyse du fichier binaire en recherchant des chaînes - elles peuvent donner les premiers indices et accélérer le processus d'analyse. Les fichiers binaires sont souvent constitués de blocs de données organisés selon une structure hiérarchique ou linéaire. Si vous traitez avec cette structure, une analyse plus approfondie sera beaucoup plus facile. L'en-tête du fichier peut donner des indications sur les décalages / tailles des blocs de données. Dans les premières étapes, il est logique de se concentrer sur la description des structures et des blocs évidents. La tâche d'analyse est grandement simplifiée par la possibilité de créer de nouvelles versions de fichiers avec différents réglages, paramètres et données. Il existe un certain nombre de difficultés associées à des types de données inconnus et à l'ordre des octets dans leur représentation binaire (Endianness). Nous aborderons ces questions dans la partie suivante.
Lecture recommandée
Andreas Pehnack. Comment aborder l'analyse de format de fichier binaire