Qu’est-ce qu’un éditeur binaire ?

Un éditeur binaire est un outil qui permet de modifier directement un fichier en notation hexadécimale ou ASCII. Là où un éditeur de texte traditionnel manipule des « chaînes », un éditeur binaire accède à la séquence brute d’octets du fichier et autorise la modification de n’importe quel bit ou octet à une position donnée.

C’est un indispensable pour l’analyse logicielle, la récupération de données ou l’étude de protocoles. Dans le monde des applications de bureau, HxD ou Binary Ninja sont très connus. Mon objectif, cette fois, était cependant de créer un éditeur binaire à fichier unique qui fonctionne uniquement dans le navigateur.


Approche d’implémentation

  • 100 % côté client (aucune transmission de données)
  • Lecture des fichiers locaux via l’API FileReader
  • Affichage de l’hexadécimal (Hex) à gauche et de l’ASCII à droite
  • Passage en mode édition au clic pour modifier directement la valeur
  • Mise en évidence en rouge des zones modifiées
  • Possibilité de basculer entre mode d’édition HEX et ASCII
  • Téléchargement des résultats modifiés sous forme de fichier

Points de blocage rencontrés et corrections

1. Décalage du cadre d’édition

Dans la première version, le cadre jaune censé entourer la cellule en cours d’édition était légèrement décalé, ce qui donnait une impression étrange. La cause venait de l’écart entre la référence d’affichage du texte et celle de la bordure à cause du line-height CSS et du positionnement flex. Même en supposant l’usage d’une police monospace, la ligne de base varie selon le moteur de rendu, ce qui déplaçait visuellement le cadre vers le haut ou le bas.

En imposant vertical-align: middle et en transformant l’élément en inline-block pour harmoniser la hauteur, le problème a été résolu.

.hex-cell.editing {
  outline: 2px solid yellow;
  vertical-align: middle;
}

2. La touche Échap insérait des caractères

Au début, si l’on appuyait sur Échap alors qu’une cellule était en mode édition, des caractères comme « EE » se retrouvaient inscrits dans la cellule.

La raison : l’événement keydown n’était pas intercepté, si bien que le navigateur transmettait le code de la touche au traitement d’entrée de la cellule. Le flux normal ne prend que 0–9 et A–F, mais la touche Escape possède aussi un code (anciennement keyCode=27, aujourd’hui key="Escape"). Celui-ci empruntait la même route et était interprété comme "E", d’où l’apparition de "EE".

La solution est simple : capter explicitement Escape dans keydown, annuler l’édition et empêcher la propagation à la routine d’entrée.

document.addEventListener("keydown", e => {
  if (e.key === "Escape") {
    cancelEdit();
    e.preventDefault(); // Empêcher l'acheminement vers la routine d'entrée
  }
});

Désormais, Échap ne sert plus qu’à quitter l’édition et aucun caractère parasite n’est injecté.

3. Les mises en évidence restaient après un nouveau chargement

Après avoir chargé un premier fichier et modifié quelques octets, l’ouverture d’un nouveau fichier laissait les surlignages rouges du précédent.

La cause : le tableau et l’état qui suivent les cellules modifiées n’étaient pas réinitialisés lors du chargement. Vider seulement la zone d’affichage ne suffisait pas, car les « drapeaux de modification » internes restaient actifs et le nouveau fichier héritait du marquage en rouge.

La correction a consisté à appeler clearModifiedState() immédiatement après la lecture du fichier pour remettre complètement les drapeaux à zéro.

4. Bascule entre modes HEX/ASCII

La première mouture permettait d’éditer en parallèle l’HEX et l’ASCII, ce qui rendait la source de vérité confuse. Manipuler le même octet via deux formulaires différents entraînait une concurrence d’écriture : une saisie ASCII écrasait instantanément la représentation Hex, et pendant la frappe, on voyait parfois un état incohérent.

Pour lever cette confusion, j’ai ajouté une liste déroulante qui impose de choisir un mode explicite, avec HEX en valeur par défaut. L’utilisateur sait ainsi « je suis en train de saisir en HEX », et la synchronisation est redevenue simple.


Extrait de code

Voici à quoi ressemble la fonction de modification.

function applyEdit(offset, newValue) {
  if (mode === "hex") {
    buffer[offset] = parseInt(newValue, 16);
  } else {
    buffer[offset] = newValue.charCodeAt(0);
  }
  markModified(offset);
  render();
}

markModified(offset) sert à ajouter le surlignage rouge : il compare la valeur avec l’original et ajoute une classe si elle diffère. L’implémentation reste très simple.


Conclusion

Cet éditeur binaire pour navigateur fonctionne hors ligne et reste sûr d’un point de vue sécurité : un outil entièrement côté client.

  • Pour corriger rapidement un binaire
  • Pour examiner un fichier dans un environnement où l’on ne peut pas installer d’application dédiée
  • Pour comprendre intuitivement la structure des octets dans un contexte pédagogique

Autant de situations où il peut rendre service.