Le Musicien du Midi (2/2)
đ Introduction
đđ Solution
Dans ce challenge, un fichier .midi est fourni. GrĂące au premier dĂ©fi, les joueurs ont normalement pu se familiariser avec le format MIDI, ce qui leur permet dâaborder ce deuxiĂšme niveau dans de bonnes conditions.
En examinant ce fichier MIDI de la mĂȘme maniĂšre que dans le premier challenge :
On observe un spectre ne contenant aucune information exploitable, accompagnĂ© dâun son particuliĂšrement dĂ©sagrĂ©able.
Il est donc nĂ©cessaire de comprendre le fonctionnement interne dâun fichier .midi afin de pouvoir le manipuler et rĂ©vĂ©ler le message cachĂ©.
Note-on | Note-off
Les termes note-on et note-off dĂ©signent des Ă©vĂ©nements spĂ©cifiques dans un fichier MIDI. Ils dĂ©crivent respectivement le dĂ©but et la fin de la lecture dâune note.
- Note-on : indique le moment oĂč une note commence Ă ĂȘtre jouĂ©e. Cet Ă©vĂ©nement prĂ©cise quelle note jouer, sa vĂ©locitĂ© (intensitĂ©) et le canal MIDI utilisĂ©.
Par exemple :
- Note-on pour la note âC4â (do central) avec une vĂ©locitĂ© de 80 (sur une Ă©chelle de 0 Ă 127).
- Note-off : marque la fin de la note, câest-Ă -dire quand elle cesse de sonner.
Ces deux Ă©vĂ©nements sont fondamentaux pour la construction dâune sĂ©quence musicale en MIDI. Un fichier MIDI est donc essentiellement une suite de note-on et de note-off, dĂ©finissant la durĂ©e et lâintensitĂ© de chaque note jouĂ©e.
Nous allons examiner les événements note-on dans notre fichier .midi.
Pour cela, plusieurs méthodes existent. Ici, nous allons utiliser le module mido en Python, qui permet de lire et manipuler des fichiers MIDI.
Voici un petit script :
1
2
3
4
5
6
7
8
from mido import MidiFile
mid = MidiFile('remy.mid')
for i, track in enumerate(mid.tracks):
print('Track {}: {}'.format(i, track.name))
for msg in track:
print(msg)
Ce script, rĂ©alisable en quelques secondes avec lâaide de la documentation officielle Mido, permet dâafficher les diffĂ©rents champs prĂ©sents dans notre fichier .mid.
On retrouve ici les Ă©vĂ©nements note_on et note_off. Il est normal dâobserver plusieurs Ă©vĂ©nements liĂ©s aux mĂȘmes notes (si vous avez bien compris leur fonctionnement).
On peut remarquer que les numéros de notes ressemblent à des valeurs ASCII. Nous allons donc extraire ces valeurs issues des événements note_on pour les interpréter en caractÚres ASCII.
Voici un script pour cela :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from mido import MidiFile
mid = MidiFile('remy.mid')
FLAG = []
for i, track in enumerate(mid.tracks):
print('Track {}: {}'.format(i, track.name))
for msg in track:
for i in str(msg).splitlines():
if i.startswith('note_on'):
chunk = i.split()
for m in chunk:
if m.startswith('note='):
valeur_note = int(m.split('=')[1])
FLAG.append(valeur_note)
for i in FLAG:
print(chr(i), end="")
En récupérant la valeur des champs note_on et en les convertissant en caractÚres ASCII, nous pouvons ainsi reconstituer le FLAG !
đ FLAG : MB{note_hidden_message}
đ