4 points par GN⁺ 2026-01-13 | 1 commentaires | Partager sur WhatsApp
  • Un jeu de Snake qui s’exécute sous Windows, Linux et dans le navigateur à partir d’un unique fichier de 13 KiB, avec prise en charge des trois plateformes depuis une seule source
  • Il suit les règles classiques de Snake : contrôler le serpent pour manger la nourriture sans heurter les murs, avec score, niveaux et structure en labyrinthe
  • Chaque plateforme est implémentée en C (WinAPI/X11) et en JavaScript (HTML5 Canvas), puis compressée et fusionnée pour tenir dans environ 3 à 5 KiB chacune
  • Windows s’exécute via un en-tête PE atypique et le mécanisme apphelp, Linux via la compression lzma et un dropper shell, et le navigateur via des astuces HTML/CSS
  • En combinant les trois implémentations, l’auteur obtient un unique exécutable de 13 312 octets, montrant le potentiel expérimental d’une structure d’exécutable multiplateforme

Une approche multiplateforme inspirée par Cosmopolitan libc

  • Cosmopolitan libc est une boîte à outils permettant de compiler du code source C en un unique binaire exécutable sur plusieurs systèmes d’exploitation
    • Exécution native prise en charge sur divers OS comme Windows, Linux et BSD
  • En raison de l’absence de support GUI et de la taille importante des binaires, l’auteur a choisi de relever le défi de créer lui-même un jeu vidéo de moins de 16 KiB
    • L’objectif était de produire un jeu basé sur une source unique, exécutable sous Windows, Linux et dans le navigateur

Structure et règles du jeu

  • Le jeu est un Snake standard, contrôlé avec les flèches directionnelles ou WASD
    • ESC pour quitter, R pour réinitialiser, P pour mettre en pause, barre d’espace pour démarrer
  • Le score augmente à chaque nourriture mangée : 10 points pour la nourriture normale, 20 points pour la nourriture jaune (15 % de probabilité)
    • La nourriture disparaît après un certain temps, déterminé par la vitesse du serpent (proportionnelle à sa longueur)
  • Après 10 nourritures mangées, on passe au niveau suivant, avec une disposition des murs modifiée aléatoirement
    • Le labyrinthe est généré de manière à toujours laisser un chemin jusqu’à la nourriture
    • La position initiale du serpent est elle aussi aléatoire, mais placée dans une direction garantissant au moins 5 cases libres
  • La taille du fichier du jeu terminé est de 13 772 octets

Implémentation sur les trois plateformes

  • La version Windows est écrite en C sur WinAPI et inclut un script de compression et un stub décompresseur
    • Elle exploite les octets librement contrôlables après la signature MZ de l’en-tête PE pour insérer un script shell
    • Le fichier est ainsi à la fois un exécutable Windows valide et un script shell Linux valide
    • Au premier lancement, l’erreur « The application was unable to start correctly (0xc0000005) » peut apparaître, mais une relance permet un fonctionnement normal
  • La version Linux utilise la compression lzma, et un petit dropper shell extrait puis exécute le binaire ELF64 compressé
    • Elle est conçue pour s’exécuter en ignorant certaines parties situées au début et à la fin du fichier
  • La version HTML exploite le fait que le navigateur ignore les données inutiles en tête de fichier et traite ensuite le HTML
    • Le CSS est utilisé pour empêcher l’affichage à l’écran des données inutiles

Assemblage et structure du fichier unique

  • Les fichiers des trois plateformes sont concaténés dans un ordre précis, afin que chaque environnement n’exécute que la partie qui lui correspond
    • Windows reconnaît la section PE, Linux la section ELF, et le navigateur la section HTML
  • La taille finale du fichier est de 13 312 octets, aboutissant à un binaire polyglotte exécutable dans les trois environnements
  • Le fichier contient successivement un en-tête PE Windows, du code compressé LZMA pour Linux, puis du code HTML/CSS/JavaScript
    • Les exemples de code montrent notamment la signature MZ, le marqueur ks, la balise <html> et un bloc <script> placés dans cet ordre

Portée technique

  • Mise en œuvre d’une structure d’exécution unique prenant en charge Windows, Linux et le navigateur dans un seul fichier
  • Bifurcation des chemins d’exécution selon la plateforme grâce à l’imbrication des formats PE, ELF et HTML
  • Une réalisation expérimentale combinant compression, détournement de formats et exécution multiplateforme dans une taille extrêmement réduite de 13 KiB

1 commentaires

 
GN⁺ 2026-01-13
Commentaires sur Hacker News
  • J’ai extrait l’exécutable Linux et j’ai été surpris de voir que readelf et objdump n’arrivaient pas à le lire correctement
    En creusant, j’ai découvert que le nom de l’éditeur de liens dynamique avait été forcé dans des champs inutilisés du header PT_DYNAMIC afin d’économiser de l’espace

    1. Je me demande si ça a été fait à la main, ou s’il existe un outil qui fait ce genre de chose
    2. J’aimerais aussi savoir s’il existe des outils capables d’analyser ce type de binaire anormal
    • On peut le lire avec ndisasm ou un éditeur hexadécimal
      Mais je considère que casser volontairement le format de cette manière est une économie sans intérêt
      Ça peut aussi entrer en conflit avec des mécanismes de sécurité comme l’antivirus ou le DEP, donc je préfère ne pas toucher à ce genre d’exécutable
    • Je ne comprends pas ce que veut dire « choke », chez moi les deux outils ont fonctionné normalement
  • Je suis étonné de voir à quel point la taille du fichier du Zelda d’origine était petite
    C’est fascinant de voir à quel point ils ont réussi à créer de l’émotion et de l’immersion avec si peu de code et de données
    The Legend of Zelda (Wikipedia)

    • C’est de la vraie magie. Un jeu appelé Eindeloos sur Commodore 64 contenait lui aussi une immense carte dans 64 KB
      La carte a été extraite 40 ans plus tard, et rien qu’en PNG elle dépasse les 800 KB
      Voir la carte du jeu
    • Zelda 1 faisait 128 KB, sans aucune compression. Sa suite faisait environ le double
    • Les donjons et les grottes tenaient en fait tous dans une seule carte rectangulaire
      Les designers les ont assemblés comme un puzzle dans les contraintes d’espace
      Référence sur la structure de la carte de Zelda
  • Résultats de mes tests

    • Navigateur : ça fonctionne si on change l’extension en .html
    • Linux : j’avais une erreur disant que la commande lzma n’existait pas, puis ça a marché après installation du paquet xz
    • Windows : en l’exécutant en .com ou .exe, j’obtenais l’erreur 0xc0000005, mais ça fonctionne après avoir désactivé le réglage DEP
    • Ça fonctionne aussi correctement sur Windows 11
    • Si on fait simplement chmod +x snake.com puis qu’on l’exécute, Mono essaie de le lancer puis échoue
      En revanche, bash snake.com fonctionne bien. Testé sur Debian 13
  • Ce qui est intéressant, c’est que ce fichier est en fait la fusion de trois exécutables en un seul
    Il pourrait donc contenir des programmes complètement différents selon la plateforme

  • Ça me rappelle kkrieger, un FPS de 96 KB
    Son niveau graphique était impressionnant pour l’époque
    kkrieger (archive)

    • Discussions liées : 2017, 2023, 2024
    • Il fonctionne encore sur des PC récents. Je l’ai téléchargé et testé moi-même
    • En jouant récemment à Metroid Prime 4, je me suis demandé ce que donnerait un jeu moderne construit sur ce type d’idée
  • Je me demande s’il existe un moyen de l’exécuter sur Mac autrement que dans le navigateur
    J’obtiens l’erreur cannot execute binary file

  • Je me demande si on pourrait pousser ce mécanisme plus loin pour créer un vrai exécutable universel
    Par exemple, écrire le code en Haxe, le compiler en C++ pour produire des versions Win32 et Linux,
    le convertir en JavaScript pour qu’il puisse aussi s’exécuter en HTML,
    puis fusionner les trois résultats dans un seul fichier

  • J’aime bien l’idée d’une application autonome qui s’exécute partout à partir d’un seul fichier
    Je travaille moi aussi sur cette direction en développant une plateforme serverless
    L’idée est de créer des applications pilotées par les données dans un unique fichier .html, avec des web-components chargés à distance
    Le fait de pouvoir ouvrir directement du HTML via le protocole file:// est très puissant, mais souvent sous-estimé

    • L’auteur original l’a en réalité implémenté trois fois — une version en C basée sur WinAPI, une en C basée sur X11, et une version JS basée sur HTML5 Canvas
      Ce n’est donc pas simplement une instance de navigateur lancée, mais bien deux applications natives complètes
    • Malheureusement, hors environnement HTTPS, les navigateurs imposent beaucoup de restrictions fonctionnelles
    • J’aimerais en savoir plus sur cette manière de développer des applis HTML autonomes. Je me demande s’il existe des exemples publics
  • C’est étonnant que les fichiers polyglottes soient apparus si tard
    Techniquement, ça semble être quelque chose qu’on aurait pu faire il y a 10 ou 20 ans

    • Je me demande quand le tout premier fichier polyglotte est apparu
      EICAR.COM me vient à l’esprit comme un exemple ancien qui faisait à la fois texte et exécutable
  • Ça me fait penser à des concours de mini-jeux web ultra-compacts comme js13kGames