1 points par GN⁺ 2023-10-16 | 1 commentaires | Partager sur WhatsApp
  • Le tableur propriétaire vieux de 30 ans Lotus 1-2-3 fonctionne nativement sous Linux, un système qui n’existait pas au moment de sa sortie, grâce à des données retrouvées par hasard et à du hacking binaire
  • La découverte, dans une sauvegarde de BBS des années 1990, du SDK d’add-ins LPL que l’on croyait disparu et de Lotus 1-2-3 for UNIX a permis de compiler des plugins d’exemple et d’analyser les binaires UNIX
  • La distribution UNIX contenait un objet COFF Intel 80386 compressé, 123.o, dont environ 20 000 symboles et les informations de débogage ont révélé la structure interne
  • Le portage ne s’est pas limité à convertir COFF en ELF : il a fallu contourner les différences d’appels système et d’ABI de structures entre Linux et UNIX avec coffsyrup et des fonctions wrapper
  • Le port actuel s’exécute sans crash et est utilisable à 100 %, mais certains problèmes et le portage des pilotes de terminal restent à régler ; la version sous émulation DOS reste donc encore plus agréable visuellement

Le point de départ du portage d’une application propriétaire de 30 ans vers Linux

  • Lotus 1-2-3 était resté un abandonware vieux de 30 ans, mais plusieurs découvertes et hacks ont rendu possible un port natif Linux
  • La cible du portage est le classique Lotus 1-2-3 R3, même si Lotus 1-2-3 lui-même a eu des versions jusqu’en 2002
  • Ce projet est né du travail de maintenance du pilote lotusdrv, destiné à faire fonctionner correctement Lotus 1-2-3 sur des systèmes modernes
    • L’API du pilote a été comprise par rétro-ingénierie, et les pilotes existants fonctionnent bien sur les systèmes modernes

Le SDK LPL perdu et une sauvegarde de BBS

  • Lotus 1-2-3 a été conçu pour être étendu par des plugins, appelés add-ins, mais ceux-ci devaient être écrits dans un langage spécial appelé LPL
  • Le compilateur et le SDK LPL avaient disparu, et Lotus ne distribuait pas gratuitement le SDK : il le vendait 395 dollars
  • Le SDK a été récupéré sous forme de warez grâce à un ancien sysop qui conservait des sauvegardes sur bande d’un système BBS des années 1990
    • L’ADK récupéré peut être téléchargé sous le nom 123DADK.ZIP
    • Un programme LPL d’exemple est publié sous le nom modern.pl
  • La même sauvegarde de BBS contenait aussi une copie warez de Lotus 1-2-3 for UNIX, largement considérée comme perdue

Analyse des images disque de Lotus 1-2-3 for UNIX

  • La version UNIX subsistait sous forme d’un ensemble de fichiers TD0, de 123UNIX1.TD0 à 123UNIX5.TD0
  • TD0 s’est révélé être un ancien format d’image disque compressée des années 1980, converti en images disque brutes avec samdisk
  • Parmi les images converties, la première était une tar archive, les autres des ASCII cpio archive au format pre-SVR4 ou odc
  • Les images disque complètes ont été mises en ligne sur Internet Archive
  • Après extraction, on trouvait sous lotus/123.v10 des exécutables, de l’aide, des keymaps, des données de pilotes d’impression et vidéo, des fichiers d’exemple, des manuels, etc.
    • L’ensemble représentait 35 répertoires et 338 fichiers

123.o, l’indice décisif

  • Dans le répertoire sysV386/lib, un gros fichier découpé en 123.o.z_1 et 123.o.z_2 a été découvert
  • Une fois les deux morceaux réunis et décompressés, 123.o s’est révélé être un Intel 80386 COFF object file
    • Un fichier objet non stripped
    • 5 sections
    • Décalage des symboles 0x1efbdc
    • 19 755 symboles

      • optional header size 28
      • Ce fichier contenait des private symbols et des informations de débogage, ce qui a beaucoup aidé à comprendre la structure interne de Lotus 1-2-3
      • Les réponses obtenues sur alt.folklore.computers indiquaient que ce fichier n’avait probablement pas été inclus par erreur
      • Comme dlopen() n’était pas largement utilisé sur les UNIX du début des années 1990, il s’agissait probablement d’un objet partiellement lié destiné à être relié à nouveau avec des extensions

La structure interne révélée par les informations de débogage

  • La version UNIX était proche d’un port direct du code source de la version DOS, et fonctionnait donc en grande partie de la même manière
  • Les informations de débogage incluses ont permis de répondre à plusieurs questions sur les entrailles de Lotus 1-2-3
  • Pour améliorer la sortie des graphiques, l’objectif était d’accrocher le rasterizer depuis le pilote, mais la documentation seule ne permettait pas vraiment de comprendre son fonctionnement
  • Grâce aux informations de débogage, il est apparu que le rasterizer générait dynamiquement un petit programme en bytecode, ensuite interprété par le moteur graphique
  • Une fois les opcodes identifiés, il est devenu possible de les désassembler dans raster.c, de les modifier et de les exploiter pour améliorer la sortie

Conversion de COFF vers ELF

  • objcopy peut convertir un fichier objet COFF vers le format ELF utilisé par Linux
  • La commande objcopy -I coff-i386 -O elf32-i386 123.o 123elf.o convertit 123.o en 123elf.o
  • Le résultat de la conversion a été identifié comme ELF 32-bit LSB relocatable, Intel 803386, version 1 (SYSV), not stripped
  • D’après objdump, l’heure de compilation du fichier objet d’origine était le 8 septembre 1990 à 06:23:50, soit avant la première version de Linux

Gestion des différences d’ABI entre Linux et UNIX

  • Le premier problème était que Linux et UNIX n’utilisent pas d’interface d’appels système compatible
  • La version UNIX utilisait l’interface lcall7 ; par exemple, open() appelait une callgate de la forme call 0x7:0x0
  • Linux ne prend pas en charge cette callgate, et l’exécuter tel quel provoque un crash
    • Linux a autrefois eu une prise en charge de compatibilité pour lcall7 et lcall27, mais ce n’est plus le cas
  • L’objectif était de supprimer ces appels et de router tous les appels via glibc

Relocations et coffsyrup

  • La tentative consistant simplement à supprimer le symbole avec objcopy --strip-symbol open a échoué, car open était utilisé dans une relocation, ce que objcopy refuse
  • Un relocatable object file contient des références de symboles et des informations de relocation afin de fonctionner quelle que soit l’adresse à laquelle il est chargé
  • Pour supprimer un symbole, il faut aussi modifier les informations de relocation qui le référencent
  • Pour cela, un petit outil nommé coffsyrup a été écrit
    • Il peut supprimer des symboles COFF que objcopy refuse de retirer
    • Dans l’exemple, il recherche et traite le symbole open et les relocations associées

Des fonctions UNIX non compatibles au niveau binaire

  • Beaucoup de fonctions UNIX standard sont compatibles au niveau source, mais pas compatibles au niveau binaire
  • L’exemple typique est struct stat
    • Le même code C peut être compilé sur plusieurs familles UNIX
    • Mais le fichier objet compilé peut se casser sur un autre système à cause de différences de taille de struct stat ou d’offset de st_size
  • Les principales fonctions à traiter sont stat(), times(), uname(), fcntl(), ioctl(), etc.
  • L’approche a consisté à renommer les symboles avec objcopy, à les marquer comme undefined avec coffsyrup, puis à écrire des fonctions wrapper convertissant les structures Linux en structures UNIX
  • termios a constitué une difficulté particulièrement importante, car ses comportements détaillés diffèrent subtilement d’un système UNIX à l’autre et ne sont pas compatibles, ce qui a rendu le débogage difficile

Vérification de licence et résultat d’exécution

  • Après plusieurs hacks, le programme s’exécutait sans crash, mais ne fonctionnait pas sans licence
  • En plaçant un breakpoint sur exit(), le symbole interne chargé de vérifier une licence valide s’est révélé être lic_init()
  • L’examen du code avec IDA a montré que la vérification de licence recherchait un fichier LICENSE.000, puis vérifiait que sa date d’expiration, le nom d’utilisateur et le nom système correspondaient aux valeurs rapportées par le système
  • Au final, Lotus 1-2-3 a été porté vers un nouveau système d’exploitation : Linux
  • L’état actuel est le suivant
    • Il s’exécute sans crash
    • Utilisable à 100 %

      • Certains problèmes doivent encore être peaufinés
      • Le portage des pilotes de terminal reste à faire
      • Pour l’instant, la version DOS exécutée en émulation est plus agréable visuellement, mais cela peut être corrigé
      • Le code du portage est publié sur github

1 commentaires

 
GN⁺ 2023-10-16
Avis sur Hacker News
  • C’est presque incroyable qu’ils aient récupéré une copie warez du SDK depuis une sauvegarde sur bande d’un vieux système BBS, au point de réussir à compiler même les plugins d’exemple
    Ça m’a rappelé Why History Needs Software Piracy

    • J’avais envie de créer une archive de conservation à long terme regroupant les manuels, mises à jour de firmware, pilotes et utilitaires de synthétiseurs, équipements Eurorack, etc. encore vendus aujourd’hui
      Comme ce sont des matériels qui existeront encore dans plusieurs décennies, il y aurait une vraie valeur d’intérêt général à disposer d’un dépôt centralisé, durable et utilisable par toute la communauté, au-delà du simple stockage dans le cloud personnel de chaque fabricant
      J’avais aussi envisagé de publier l’archive chaque année, ou de vendre des Blu-ray d’archivage sur des supports physiques censés tenir une centaine d’années
      Ainsi, quand il faudra sauver le firmware corrompu d’un module Eurorack DSP à base d’ARM, la probabilité que quelqu’un possède le dernier rare fichier .bin nécessaire serait proche de 1
  • Mon père conservait quantité de fichiers Lotus 1-2-3 importants sur un ordinateur portable secondaire avec un vieux Windows, et comme il devait encore les ouvrir de temps en temps, la situation était assez inquiétante
    J’ai récemment découvert que LibreOffice pouvait convertir les fichiers Lotus en ODF/ODS, même en ligne de commande, et j’ai tout converti avec un simple script bash
    J’ai ensuite téléversé en lot les fichiers convertis dans Nextcloud avec Collabora, puis j’ai donné à mon père un compte et quelques consignes d’utilisation simples ; il peut maintenant consulter les fichiers en ligne, et ils sont aussi inclus dans la routine de sauvegarde normale du serveur
    Un grand merci aux archéologues de la donnée comme l’OP et aux contributeurs de LibreOffice

    • S’ils sont aussi anciens et encore importants, je suis assez curieux de savoir de quel genre de fichiers il s’agit
  • Ça me rappelle quand j’avais 7 ans et que j’ai demandé une Nintendo : mon père m’a acheté à la place un PC 286, Lotus 1-2-3 et l’aventure textuelle Indiana Jones

    • Au Computer Museum de Boston, j’avais vu une LISP Machine qui avait l’air géniale et j’ai demandé à en avoir une, mais j’ai finalement reçu un Commodore 64
      Mon premier langage a donc été BASIC plutôt que LISP, et j’ai l’intention d’attribuer tous mes échecs dans la vie à cette tragédie ; aucune objection ne sera acceptée
    • J’ai supplié pour avoir une NES, mais mon père m’a acheté un C64 en disant : « c’est mieux, tu comprendras plus tard », et ça a fini par changer ma vie
    • Je voulais un BBC Micro, mais j’ai reçu un ZX Spectrum, et au final c’était bien mieux pour me donner goût à la programmation
      Même si le Spectrum était déjà sur le déclin à ce moment-là
    • J’ai reçu un Apple IIgs et Leisure Suit Larry, mais ni moi ni mon grand frère n’arrivions à répondre de manière fiable aux questions de vérification d’âge au démarrage
  • Je travaille sur quelque chose de similaire, mais j’ajoute une étape qui transforme d’abord une partie du programme en fichiers objet
    Ainsi, on n’est pas limité aux seuls fichiers objet existants, mais il faut un peu de rétro-ingénierie pour que ça fonctionne
    J’ai réalisé une preuve de concept avec aln, le linker de l’Atari Jaguar : j’ai séparé un exécutable Linux x86 au format a.out en fichiers objet ELF, puis je l’ai réédité en exécutable ELF x86 en contournant les différences d’ABI
    https://forums.atariage.com/topic/354341-porting-the-original-atari-jaguar-sdk-to-elf/

  • C’était intéressant à bien des égards
    Le processus de portage d’un binaire UNIX vers un binaire Linux sans code source, ni compilateur ni langage d’origine, était impressionnant, et c’est exactement le genre de contenu qui fait HN
    Ça rappelle aussi qu’en 2023, Usenet sert encore à autre chose qu’à faire circuler des fichiers rar
    Et cela ravive le souvenir de la culture BBS d’avant la démocratisation d’Internet, qui a diffusé auprès du grand public l’enthousiasme et d’excellents sharewares

    • On dirait que l’esprit BBS revient
      C’est d’autant plus vrai quand on voit Twitter et d’autres réseaux sociaux s’effondrer ; les plus âgés de la génération Z se passionnent pour le rétro des années 80-90, au point de télécharger des sons de négociation de modem comme sonneries
      Mon neveu de 23 ans l’a fait récemment, et des œuvres comme American Horror Story ou Stranger Things entretiennent encore cette nostalgie
      Le vieux dicton selon lequel, si l’on attend assez longtemps, tout revient à la mode semble donc juste
  • Il y avait aussi eu une bonne discussion en mai 2022 l’an dernier
    https://news.ycombinator.com/item?id=31455968

  • Le lien https://scenelist.org/ dans cet excellent article était exactement la bombe de nostalgie dont j’avais besoin ce matin
    Très bon voyage dans les souvenirs, vivement recommandé

  • Liens associés
    Lotus 1-2-3 for Linux - https://news.ycombinator.com/item?id=35807639 - mai 2023, 73 commentaires
    Lotus 1-2-3 - https://news.ycombinator.com/item?id=35872758 - mai 2023, 117 commentaires
    Lotus 1-2-3 For Linux - https://news.ycombinator.com/item?id=31455968 - mai 2022, 83 commentaires
    Lotus 1-2-3 arbitrary resolution - https://news.ycombinator.com/item?id=26316637 - mars 2021, 123 commentaires

  • J’avais complètement oublié 1-2-3, alors que je l’avais brièvement utilisé l’an dernier
    Le binaire 123 fonctionne encore très bien sous Linux, et le fait qu’un logiciel disparu depuis longtemps fonctionne simplement comme ça est un accomplissement assez remarquable

  • J’ai toujours voulu quelque chose comme ça. Comme je n’utilise pas beaucoup les polices ou les images dans les feuilles de calcul, un tableur en terminal me convient parfaitement
    Je suis content qu’il soit enfin là, et j’espère qu’il sera aussi porté sur Mac et Windows

    • Le même site propose aussi des critiques de divers tableurs Linux en terminal
      https://lock.cmpxchg8b.com/spreadsheet.html
    • Emacs dispose depuis longtemps d’un mode tableur, SimpleEmacsSpreadsheet
      Je ne l’ai jamais utilisé, mais ça vaut la peine d’y jeter un œil
      Par ailleurs, Org-Mode d’Emacs est un outil qu’on peut explorer sans fin, et il existe aussi une façon d’utiliser les cellules de tableaux org-mode comme un tableur avec la fonctionnalité Calc d’Emacs
      https://www.youtube.com/watch?v=15aDIvb5LJs
      Ça a l’air assez puissant et, fidèle à Emacs, ça fonctionne aussi bien dans le terminal que dans un environnement fenêtré
    • Il y a déjà sc : https://www.unix.com/man-page/linux/1/sc/