1 Punkte von GN⁺ 2023-10-16 | 1 Kommentare | Auf WhatsApp teilen
  • Die 30 Jahre alte proprietäre Tabellenkalkulation Lotus 1-2-3 läuft nach der Wiederherstellung zufällig geretteter Materialien und Binary-Hacks nun nativ auf Linux, das es zum Zeitpunkt der Veröffentlichung noch gar nicht gab
  • Durch den Fund des verloren geglaubten LPL Add-in SDK und von Lotus 1-2-3 for UNIX in BBS-Backups aus den 1990er Jahren wurden das Bauen von Beispiel-Plugins und die Analyse der UNIX-Binaries möglich
  • Die UNIX-Distribution enthielt mit Intel 80386 COFF Object 123.o ein komprimiertes Objektfile, dessen rund 20.000 Symbole und Debug-Informationen die interne Struktur offenlegten
  • Das Portieren war nicht damit erledigt, COFF nur in ELF umzuwandeln; Unterschiede bei Systemaufrufen und Struktur-ABIs zwischen Linux und UNIX mussten mit coffsyrup und Wrapper-Funktionen umgangen werden
  • Der aktuelle Port läuft ohne Abstürze und ist zu 100 % benutzbar, allerdings bleiben einige Probleme und die Portierung des Terminal-Treibers offen, sodass die DOS-Emulationsversion optisch noch besser aussieht

Der Ausgangspunkt für die Portierung einer 30 Jahre alten proprietären App auf Linux

  • Lotus 1-2-3 war als 30 Jahre alte Abandonware zurückgeblieben, doch mehrere Funde und Hacks machten einen nativen Linux-Port möglich
  • Ziel der Portierung ist das klassische Lotus 1-2-3 R3; Lotus 1-2-3 selbst erhielt jedoch noch bis 2002 Releases
  • Das Projekt begann mit der Pflege des lotusdrv-Treibers, damit Lotus 1-2-3 auf modernen Systemen sauber läuft
    • Die Treiber-API wurde durch Reverse Engineering ermittelt, und die bestehenden Treiber funktionieren auf modernen Systemen gut

Das verlorene LPL SDK und BBS-Backups

  • Lotus 1-2-3 war so entworfen, dass es sich über Plugins, also Add-ins, erweitern ließ, doch diese mussten in der speziellen Sprache LPL geschrieben werden
  • Der LPL-Compiler und das SDK galten als verschwunden, und Lotus verteilte das SDK nicht kostenlos, sondern verkaufte es für 395 Dollar
  • Über einen ehemaligen Sysop, der Tape-Backups eines BBS-Systems aus den 1990er Jahren aufbewahrt hatte, wurde das SDK in Form einer Warez-Kopie wiederhergestellt
    • Das wiederhergestellte ADK kann als 123DADK.ZIP heruntergeladen werden
    • Ein Beispiel für ein LPL-Programm ist als modern.pl veröffentlicht
  • In denselben BBS-Backups befand sich auch eine Warez-Kopie von Lotus 1-2-3 for UNIX, die weithin als verloren galt

Analyse der Disk-Images von Lotus 1-2-3 for UNIX

  • Die UNIX-Version lag als Sammlung von TD0-Dateien von 123UNIX1.TD0 bis 123UNIX5.TD0 vor
  • TD0 wurde als altes komprimiertes Disk-Image-Format aus den 1980er Jahren identifiziert und mit samdisk in rohe Disk-Images umgewandelt
  • Vom konvertierten Satz war das erste Image ein tar archive, die übrigen waren ASCII-cpio-Archive im pre-SVR4- oder odc-Format
  • Die vollständigen Disk-Images wurden bei Internet Archive hochgeladen
  • Nach dem Entpacken erschienen unter lotus/123.v10 ausführbare Dateien, Hilfe, Keymaps, Drucker- und Video-Treiberdaten, Beispieldateien, Handbücher und mehr
    • Der gesamte Inhalt umfasste 35 Verzeichnisse und 338 Dateien

123.o als entscheidender Hinweis

  • Im Verzeichnis sysV386/lib wurde eine große Datei entdeckt, aufgeteilt in 123.o.z_1 und 123.o.z_2
  • Nach dem Zusammenfügen und Entpacken stellte sich 123.o als Intel 80386 COFF object file heraus
    • nicht gestripptes Objektfile
    • 5 Sektionen
    • Symbol-Offset 0x1efbdc
    • 19.755 Symbole

      • optionale Header-Größe 28
      • Die Datei enthielt private Symbole und Debug-Informationen, was beim Verständnis der internen Struktur von Lotus 1-2-3 sehr half
      • Die Antworten aus alt.folklore.computers deuteten darauf hin, dass diese Datei nicht versehentlich enthalten war
      • Da dlopen() auf frühem UNIX der 1990er Jahre noch nicht weit verbreitet war, handelte es sich wahrscheinlich um ein teilweise gelinktes Objekt für Erweiterungen und erneutes Linken

Interne Strukturen durch Debug-Informationen

  • Die UNIX-Version war eher ein direkter Source-Port der DOS-Version und funktionierte daher in weiten Teilen auf dieselbe Weise
  • Die enthaltenen Debug-Informationen klärten mehrere offene Fragen zum Inneren von Lotus 1-2-3
  • Zur Verbesserung der Grafikausgabe sollte der Treiber den Rasterizer hooken, doch allein anhand der Dokumentation war das Verhalten schwer zu verstehen
  • Über die Debug-Informationen wurde klar, dass der Rasterizer dynamisch kleine Bytecode-Programme erzeugt, die von der Grafik-Engine interpretiert werden
  • Nachdem die Opcodes bekannt waren, konnten sie in raster.c disassembliert und für Verbesserungen der Ausgabe verändert werden

Umwandlung von COFF nach ELF

  • objcopy kann COFF-Objektdateien in das unter Linux verwendete ELF-Format umwandeln
  • Mit dem Befehl objcopy -I coff-i386 -O elf32-i386 123.o 123elf.o wurde 123.o in 123elf.o konvertiert
  • Das Ergebnis wurde als ELF 32-bit LSB relocatable, Intel 803386, version 1 (SYSV), not stripped bestätigt
  • Laut objdump wurde das ursprüngliche Objektfile am 8. September 1990 um 06:23:50 kompiliert, also vor der ersten Linux-Version

Umgang mit ABI-Unterschieden zwischen Linux und UNIX

  • Das erste Problem war, dass Linux und UNIX keine kompatible System-Call-Schnittstelle verwenden
  • Die UNIX-Version nutzte das Interface lcall7; open() rief zum Beispiel ein Callgate in der Form call 0x7:0x0 auf
  • Unter Linux wird dieses Callgate nicht unterstützt, sodass das Programm unverändert abstürzt
    • Linux hatte früher einmal Kompatibilitätsunterstützung für lcall7 und lcall27, diese existiert aber nicht mehr
  • Ziel war es, solche Aufrufe zu entfernen und alle Calls über glibc zu routen

Relocations und coffsyrup

  • Es wurde zunächst versucht, Symbole einfach mit objcopy --strip-symbol open zu entfernen, doch objcopy verweigerte dies, weil open in einer Relocation verwendet wurde
  • Ein relocatable object file enthält Symbolreferenzen und Relocation-Informationen, damit es unabhängig von der Ladeadresse funktioniert
  • Um ein Symbol zu entfernen, müssen auch die Relocation-Informationen, die auf dieses Symbol verweisen, angepasst werden
  • Dafür wurde das kleine Tool coffsyrup geschrieben
    • Es kann auch COFF-Symbole entfernen, die objcopy ablehnt
    • Als Beispiel werden das Symbol open und die zugehörigen Relocations gesucht und verarbeitet

Binär inkompatible UNIX-Funktionen

  • Eine ganze Reihe standardmäßiger UNIX-Funktionen ist zwar quellkompatibel, aber nicht binärkompatibel
  • Ein typisches Beispiel ist struct stat
    • Derselbe C-Code lässt sich auf mehreren UNIX-Derivaten kompilieren
    • Das kompilierte Objektfile kann auf einem anderen System aber wegen Unterschieden bei der Größe von struct stat oder dem Offset von st_size kaputtgehen
  • Wichtige zu behandelnde Funktionen sind stat(), times(), uname(), fcntl(), ioctl() und andere
  • Der Ansatz bestand darin, mit objcopy Symbolnamen umzubenennen, sie mit coffsyrup als undefined zu markieren und dann Wrapper-Funktionen zu schreiben, die Linux-Strukturen in UNIX-Strukturen umwandeln
  • termios war dabei besonders schwierig, weil sich das Detailverhalten je nach UNIX-System subtil unterscheidet und nicht kompatibel ist, was das Debugging erschwerte

Lizenzprüfung und Ausführungsergebnis

  • Nach mehreren Hacks lief das Programm ohne Abstürze, funktionierte jedoch ohne Lizenz nicht
  • Durch einen Breakpoint auf exit() stellte sich heraus, dass das interne Symbol für die Prüfung einer gültigen Lizenz lic_init() war
  • Eine Analyse des Codes in IDA zeigte, dass die Lizenzprüfung nach einer Datei LICENSE.000 sucht und dann prüft, ob Ablaufdatum, Benutzername und Systemname darin zu den vom System gemeldeten Werten passen
  • Schließlich wurde Lotus 1-2-3 auf das neue Betriebssystem Linux portiert
  • Der aktuelle Stand ist wie folgt
    • läuft ohne Abstürze
    • zu 100 % benutzbar

      • einige Probleme müssen noch weiter bereinigt werden
      • die Portierung des Terminal-Treibers steht noch aus
      • aktuell sieht die DOS-Version in der Emulation noch besser aus, lässt sich aber verbessern
      • der Portierungscode ist auf github veröffentlicht

1 Kommentare

 
GN⁺ 2023-10-16
Hacker-News-Meinungen
  • Kaum zu glauben, dass jemand aus einem Tape-Backup eines alten BBS-Systems eine Warez-Kopie des SDK wiederhergestellt und sogar die Beispiel-Plugins gebaut hat.
    Das erinnert an Why History Needs Software Piracy.

    • Ich wollte Manuals, Firmware-Updates, Treiber und Utilities für heute verkaufte Synthesizer, Eurorack-Geräte usw. sammeln und daraus ein Langzeitarchiv machen.
      Solche Geräte sind Hardware, die auch in Jahrzehnten noch existieren wird; über die Ablage in persönlichen Clouds einzelner Hersteller hinaus hätte ein zentralisiertes, langlebiges Repository für die ganze Community großen öffentlichen Nutzen.
      Ich habe auch überlegt, das Archiv jährlich zu verteilen oder archival Blu-rays auf physischen Medien zu verkaufen, die etwa 100 Jahre halten.
      Dann läge die Wahrscheinlichkeit nahe 1, dass irgendjemand die letzte seltene .bin-Datei hat, die man braucht, um die beschädigte Firmware eines ARM-basierten DSP-Eurorack-Moduls zu retten.
  • Mein Vater hatte eine Menge wichtiger Lotus-1-2-3-Dateien auf einem Zweit-Laptop mit altem Windows liegen und musste sie gelegentlich öffnen; dieser Zustand war ziemlich beunruhigend.
    Kürzlich habe ich erfahren, dass LibreOffice Lotus-Dateien in ODF/ODS konvertieren kann, sogar über die Kommandozeile, und habe alles mit einem einfachen bash-Skript umgewandelt.
    Ich habe die konvertierten Dateien gesammelt in eine Nextcloud mit Collabora hochgeladen und meinem Vater einen Account samt kurzer Anleitung gegeben; jetzt kann er die Dateien online ansehen, und sie sind auch in der normalen Backup-Routine des Servers enthalten.
    Großen Dank an Datenarchäologen wie den OP und an die LibreOffice-Contributors.

    • Dass die Dateien nach so langer Zeit noch wichtig sind, macht mich ziemlich neugierig, um welche Art von Dateien es sich handelt.
  • Das erinnert mich daran, wie ich mit 7 um ein Nintendo gebeten habe und mein Vater mir stattdessen einen 286-PC mit Lotus 1-2-3 und dem Indiana-Jones-Textadventure gekauft hat.

    • Im Computer Museum in Boston sah ich eine LISP Machine, die so cool wirkte, dass ich sie haben wollte, bekam am Ende aber einen Commodore 64.
      Deshalb wurde meine erste Sprache BASIC statt LISP, und ich werde alle Fehlschläge meines Lebens dieser Tragödie zuschreiben; Widerspruch wird nicht akzeptiert.
    • Ich habe um ein NES gebettelt, aber mein Vater kaufte mir einen C64 mit den Worten: „Das ist besser, du wirst es später verstehen“ – und letztlich hat es mein Leben verändert.
    • Ich wollte einen BBC Micro, bekam aber einen ZX Spectrum, und im Ergebnis war das viel besser dafür, mein Interesse am Programmieren zu wecken.
      Selbst wenn der Spectrum damals schon auf dem absteigenden Ast war.
    • Ich bekam einen Apple IIgs und Leisure Suit Larry, aber weder ich noch mein älterer Bruder konnten die Altersprüfungsfragen am Anfang zuverlässig beantworten.
  • Ich arbeite an etwas Ähnlichem, füge aber den Schritt hinzu, Teile des Programms zuerst in Objektdateien umzuwandeln.
    Dadurch ist man nicht nur an bereits vorhandene Objektdateien gebunden, aber damit es funktioniert, braucht es ein gewisses Maß an Reverse Engineering.
    Ich habe mit dem Atari-Jaguar-Linker aln einen Proof of Concept gebaut: Ein Linux-x86-a.out-Executable wird in ELF-Objektdateien zerlegt und anschließend, unter Umgehung der ABI-Unterschiede, wieder zu einem ELF-x86-Executable gelinkt.
    https://forums.atariage.com/topic/354341-porting-the-original-atari-jaguar-sdk-to-elf/

  • In vielerlei Hinsicht interessant.
    Der Weg von einem UNIX-Binary zu einem Linux-Binary, ohne Sourcecode und ohne den ursprünglichen Compiler oder die Sprache, sah beeindruckend aus – genau solche Inhalte machen HN aus.
    Es erinnert auch daran, dass Usenet 2023 noch für mehr genutzt wird als nur zur Verteilung von rar-Dateien.
    Und es ruft die Zeit vor der breiten Verbreitung des Internets in Erinnerung, als die BBS-Kultur Leidenschaft und großartige Shareware-Distributionen unter die Leute brachte.

    • Der BBS-Geist scheint zurückzukommen.
      Umso mehr, wenn man sieht, wie Twitter und andere Social Media ins Wanken geraten; ältere Gen-Z-Leute verfallen dem 80er-/90er-Retro und laden sich sogar Modem-Handshakes als Klingeltöne herunter.
      Mein 23-jähriger Neffe hat das kürzlich auch gemacht, und Serien wie American Horror Story oder Stranger Things befeuern diese Nostalgie zusätzlich.
      Das alte Sprichwort stimmt also: Wenn man nur lange genug wartet, kommt alles wieder in Mode.
  • Auch im Mai 2022 gab es dazu eine gute Diskussion.
    https://news.ycombinator.com/item?id=31455968

  • Das in diesem hervorragenden Artikel verlinkte https://scenelist.org/ war heute Morgen genau die Nostalgie-Bombe, die ich gebraucht habe.
    Eine sehr schöne Reise in die Vergangenheit, klare Empfehlung.

  • Verwandte Links:
    Lotus 1-2-3 for Linux - https://news.ycombinator.com/item?id=35807639 - Mai 2023, 73 Kommentare
    Lotus 1-2-3 - https://news.ycombinator.com/item?id=35872758 - Mai 2023, 117 Kommentare
    Lotus 1-2-3 For Linux - https://news.ycombinator.com/item?id=31455968 - Mai 2022, 83 Kommentare
    Lotus 1-2-3 arbitrary resolution - https://news.ycombinator.com/item?id=26316637 - März 2021, 123 Kommentare

  • Weil ich es letztes Jahr kurz ausprobiert hatte, hatte ich 1-2-3 völlig vergessen.
    Das 123-Binary läuft unter Linux immer noch problemlos, und dass längst verschwundene Software einfach funktioniert, ist eine ziemlich beachtliche Leistung.

  • So etwas wollte ich schon immer. Da ich in Spreadsheets kaum Schriftarten oder Bilder nutze, passt eine terminalbasierte Tabellenkalkulation perfekt.
    Schön, dass es das endlich gibt; ich hoffe, es wird auch auf Mac und Windows portiert.

    • Auf derselben Website gibt es auch Reviews verschiedener Terminal-Linux-Tabellenkalkulationen.
      https://lock.cmpxchg8b.com/spreadsheet.html
    • In Emacs gibt es schon lange den Spreadsheet-Modus SimpleEmacsSpreadsheet.
      Ich habe ihn nie benutzt, aber er ist einen Blick wert.
      Außerdem ist Emacs Org-Mode ein Tool, in das man endlos tief einsteigen kann, und es gibt auch eine Möglichkeit, org-mode-Tabellenzellen zusammen mit der Emacs-Calc-Funktion wie eine Tabellenkalkulation zu nutzen.
      https://www.youtube.com/watch?v=15aDIvb5LJs
      Sieht ziemlich mächtig aus und läuft Emacs-typisch sowohl im Terminal als auch in einer Fensterumgebung.
    • Es gibt bereits sc: https://www.unix.com/man-page/linux/1/sc/