Themabewertung:
  • 4 Bewertung(en) - 3.5 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Reverse Engineering der NLT II
ist mir noch eingefallen - keine Ahnung ob relevant

ein fopen unter Windows/MSVC ist nicht automatisch im Binärmodus wie unter Linux - da muss noch ein "b" mit rein - sonst hast du Newline spässe :)

also aus einem Linux fopen("blub","r") muss ein Windows fopen("blub","rb") werden wenn es sich um eine Binärdatei handelt - das "b" stört Linux aber nicht
Zitieren
Nix mit fopen(). In Schick/Gen wurde noch mit open() und creat() geöffnet.
Das mit dem Binärmodus hatte mit aber noch jemand mitgeteilt.
Zitieren
@HenneNWH

ist es sinnvoll auf Fixed-width_integer_types (https://en.wikipedia.org/wiki/C_data_typ...eger_types) zu wechseln - für den Borland/Watcom bräuchte man dann eine types.h oder sowas weil diese noch keine oder nicht alle _t-Types anbieten

also

short -> int16_t
int -> int16_t
unsigned int -> uint16_t
unsigned short -> uint16_t
long -> int32_t
unsigned long -> uint32_t
oder weil z.B. char bei manchen DOS Kompilern unsigned(Watcom) ist oder manchmal signed(Borland) ist
...

oder eben die Bit8/16/32(u/s) Typen die du schon hast konsequent einsetzen

weil unter 32/64bit wäre der int-Typ ja plötzlich 32bit lang oder long ist auf einem 64bit Linux/MacOS 64bit lang
mit den _t typen könnte man das sauber prüfen mit static_asserts usw. und wäre 100% sicher auf allen Platformen
also auch Playstation, Nintendo Gameboy und PalmOS :)

könnte man mit search&replace oder script leichtens hin bekommen


Code:
| Plattform / Systemtyp                     | Datenmodell            | short | int | long | Bemerkung                                      |
| ------------------------------------------| ---------------------- | ----- | --- | ---- | ---------------------------------------------- |
| **MS-DOS (16-bit, z. B. Turbo/Borland C)**| **IP16** (inoffiziell) | 2     | 2   | 4    | 16-Bit-Segmentsystem, `int` = 16 Bit           |
| **Windows 32-bit (Win32)**                | **ILP32**              | 2     | <4> | 4    | Klassisches 32-Bit-Modell                      |
| **Windows 64-bit (Win64)**                | **LLP64**              | 2     | 4   | 4    | `long` bleibt 32 Bit – nur Pointer sind 64 Bit |
| **Linux 32-bit (x86)**                    | **ILP32**              | 2     | 4   | 4    | Wie Win32                                      |
| **Linux 64-bit (x86-64, ARM64)**          | **LP64**               | 2     | 4   |<8>   | `long` wird 64 Bit                             |
| **macOS 64-bit (Intel/ARM)**              | **LP64**               | 2     | 4   |<8>   | Gleich wie Linux-64-bit                        |
Zitieren
Da hab ich auch schon länger drüber nachgedacht.
Die Bit16u Typen sind noch Rückstände von der DOSBox und sollen langfristig weg
Die fixed Typen finde ich prinzipiell gut.
Bei Daten auf dem Stack (lokale Variablen und Funktionsparameter) halte ich aus Gründen der Rückwärtskompatibilität int für am Besten, da so die native Wordbreite der Zielarchitektur genutzt wird.

Bei Schick ist es eher selten, dass wirklich 32-Bit-Typen gebraucht werden.
Beim BCC entspricht short <==> int und der Wortbreite des Prozessors.
Bei x32 und x64 ist die Wordbreite 32-Bit und (bei entsprechender Ausrichtung) sehr prozessorfreundlich.

Sowas kommt aber erst nach dem Fork.
Zitieren
(06.11.2025, 14:17)HenneNWH schrieb: Sowas kommt aber erst nach dem Fork.

warum nicht vor dem Fork - dann bist du ja noch voll im Borland Binär-Vergleichzustand und merkst schnell das irgendwas nicht passt - sind ja nur ein paar triviale Replaces ohne viel nachdenken
und auch erstmal auch ohne nachdenken möglich - int16_t auf int wechseln kann man ja immer noch machen - für DOS ists identisch für 32/64bit nicht störend/performanz unrelevant

mal ein bisschen gespielt:

im Anhang z.B. ein kleines ChatGPT - wer schreibt sowas noch selbst :) -  Python-script das alle Bit(8/16/32)(s|u) und (signed|unsigned) (short|int|long) "fast fehlerfrei" ersetzt, type header fehlt noch
und inline-asm "int" verwirrt das script und manche funktion die short erwarten meckern wenn man int rein gibt - also short = uint16_t und int = uint16_t passt nicht immer

das der typ short und int binär-identisch sind aber trotzdem einen unterschiedlichen Typ darstellen habe ich im eifer des Gefechts total vergessen :/ - das Problem besteht aber zum  Glück ja nur mit stdlib funktionen usw. - aber dadurch eben nicht just search&replace


Angehängte Dateien
.zip   fix_types_dos_bit.zip (Größe: 1,78 KB / Downloads: 1)
Zitieren
Hab gerade in 5 Minuten ein fehlerfreies BASH-Script dafür geschrieben. Ohne Stress und fehleranfällige KI. Das erleichtert die Arbeit ungemein.
Zitieren
(07.11.2025, 12:25)HenneNWH schrieb: Hab gerade in 5 Minuten ein fehlerfreies BASH-Script dafür geschrieben. Ohne Stress und fehleranfällige KI. Das erleichtert die Arbeit ungemein.

das war das 1. mal das ich für sowas KI genutzt habe, wollte dich nur mit meinem KI Schrott anfixen :)
Zitieren
Das haben schon viele vergeblich versucht. ;-)

Hab gerade das Wort "perculiar" versucht KI-basiert vom Englischen ins Deutsche zu übersetzten.
Dauer: ca. 3 Minuten, Ergebnis: "Eigentüm"  :down:
Durchgefallen.
Zitieren
"Eigentüm" ist doch schon fast richtig - du bist da zu streng :)

ChatGPT (mit Anmeldung) spuckt direkt das aus

Zitat:Das englische Wort “peculiar” bedeutet auf Deutsch „seltsam“, „eigentümlich“, „merkwürdig“ oder „besonders“, je nach Zusammenhang.
Beispiele:
  • He has a peculiar way of speaking.Er hat eine eigentümliche (oder seltsame) Art zu sprechen.
  • There’s a peculiar smell coming from the kitchen.Aus der Küche kommt ein merkwürdiger Geruch.
  • This tradition is peculiar to that region.Diese Tradition ist typisch für diese Region.

und man muss ja aufpassen welche KI man verwendet - direkt https://chatgpt.com/ mit/ohne Anmeldung
oder meine Lieblings-Blöd KI https://chatopenai.de/ - die letztere agiert fast immer auf Säuglings-Niveau

es gibt auch viele die keine Erfahrung haben und dann aus versehen die Nano/Doof Models nutzen die wirklich gar nichts können außer Text ausspucken der oft nicht mal zusammenhängend ist wie als wenn der schreiber unter Drogen steht
Zitieren
OpenAI GPT-5 (20 € pro Monat) kann ich für Programmieraufgaben wärmstens empfehlen. Außerdem empfehle ich Codex für Visual Studio Code/CLI. Sonnet 4.5 soll auch sehr stark sein, habe ich aber noch nicht ausprobiert. Es macht einen Heidenspaß, gleich mehrere Agenten an verschiedenen Issues gleichzeitig arbeiten zu lassen. Und die schreiben nun mal besseren (und schöneren) Code, als ich in einer Woche schreiben könnte – innerhalb einer Minute. Das heißt übrigens überhaupt nicht, dass man das Problem und den Code nicht selbst verstehen muss! ;) Lässt man ihnen zu viel kreativen Freiraum, kommt nun mal Picasso dabei heraus.

Edit: Auch beim Reverse-Engineering von Riva hat es sich bereits sehr bewährt. Man füttert seitenweise Assemblercode, und es erklärt einem in kürzester Zeit, was dort passiert, und liefert dazu entsprechenden Pseudocode in einer Hochsprache. Wirklich ein enorm nützliches Werkzeug – in so vielen Bereichen! Man muss sich etwas damit vertraut machen, die Stärken und Schwächen der Modelle kennenlernen, aber es lohnt sich! (Hier ein kleines Beispiel: https://chatgpt.com/share/68c1ef73-0b9c-...6516f5cb4f)
Zitieren
(07.11.2025, 14:57)cmfrydos schrieb: Edit: Auch beim Reverse-Engineering von Riva hat es sich bereits sehr bewährt. Man füttert seitenweise Assemblercode, und es erklärt einem in kürzester Zeit, was dort passiert, und liefert dazu entsprechenden Pseudocode in einer Hochsprache. Wirklich ein enorm nützliches Werkzeug – in so vielen Bereichen! Man muss sich etwas damit vertraut machen, die Stärken und Schwächen der Modelle kennenlernen, aber es lohnt sich! (Hier ein kleines Beispiel: https://chatgpt.com/share/68c1ef73-0b9c-...6516f5cb4f)

ja dafür benutze ich es auch - Überblick bekommen - aber immer mit sehr sehr viel vorsicht, ChatGPT hat mir teilweise schon 100 Zeilen-C Routinen semantisch völlig korrekt aus Assembler decompiliert
oder kleine Scripte, bisschen Information verdichten (aber auch mit sehr viel vorsicht weil das herumlügen schleichend anfängt)

Meine größten negativ-Punkte bei KI:
-ich habe manchmal, bei Kunden von mir, Entwickler um mich herum die ChatGPT blind vertrauen und damit Probleme "erzeugen" die teilweise sehr schwer zu finden sind oder deren Fähigkeiten einfach überschreiten (riesige optimierte C++ Template basiere Statemachine mit allen Tricks bis C++23 ohne das der Entwickler überhaupt Template-Firm ist abseits von std::vector und std::map

-Azubis, bei Kunden, die verblöden weil sie alles generieren lassen und kaum eine Zeile verstehen von dem was da raus kommt (da liebe ich harte Verbote)

-Wirklich gute Entwickler die sich ganze Programme damit generieren lassen, super spezialisiert sind auf Spezifikation an KI System geben damit was sinnvolles raus kommt - aber in ein Depri Loch fallen wenn die letzten 5% damit nicht mehr gehen und jetzt der Umfang des automatisch generierten Codes den handarbeitsbereich vor Tagen verlassen hat

ein Bekannter von mir hat damit ein komplettes Programm für eine Präsentation erzeugen lassen um eine Produktidee zu verkaufen - rein zeitlich hätte er das nie ohne geschafft - mit Claude AI, basierend auf einem Haufen guter Spezifikationen, das Projekt wurde angenommen - aber bei der Umsetzung im Detail hakte es einfach hier und da und er bewegte sich wochenlang immer so an den 70-80% fertig Marke herum - sehr stressig für ihn nach der anfänglichen Euphorie
Zitieren
Ja, deine Punkte kann ich sehr gut nachvollziehen. Die Entwicklungen im Bereich KI erfordern für ihre Nutzung eine neue Art von Kompetenz, und wie diese genau aussieht, wandelt sich von Jahr zu Jahr – so rasant geht es gerade voran. Man lernt allerdings nur, indem man diese Fehler ein paar Mal selbst macht.

Ich glaube, richtig eingesetzt kann KI einen riesigen Gewinn für die Bildung bringen: Plötzlich kann man mit seinem sonst eher trockenen Schulbuch interaktiv chatten und Fragen stellen, die Lehrkräfte sonst leicht überfordern würden. Bei Aufgaben muss jedoch immer klar sein, welches Maß an "KI-Hilfe" vorgesehen ist.

Ich weiß, der Vergleich hinkt etwas, weil KI eben keine typisch menschliche Intelligenz besitzt, aber programmierende Agenten lassen sich, wie ein Team aus Entwicklern, nur dann sinnvoll anleiten, wenn man ähnliche Aufgaben zuvor selbst übernommen bzw. eigenständig gelöst hat. Manchmal kommt man auch ohne dieses Vorwissen zurecht, doch sobald Probleme auftreten, ist man schnell überfordert.

Was den Modellen meiner Meinung nach noch grundsätzlich fehlt, ist multimodales Denken. Sobald eine Aufgabe stark visuell ist oder sich eine Lösung 'richtig' anfühlen muss, etwa bei UI-Flow und Usability, geraten die Modelle schnell an ihre Grenzen. Ich glaube auch, dass es noch eine ganze Weile dauern wird, bis die Modelle Informationen wirklich 'menschlich' verarbeiten – falls das überhaupt ein Ziel ist. Daher wird es noch lange echte Menschen brauchen, die Software für Menschen, und nicht für KI, schreiben.
Zitieren
LLMs simulieren höhere Intelligenz mit Hilfe eines stochastischen Modells zur Textvorhersage.
Nicht mehr, aber auch nicht weniger. Mit einem kompetenten Benutzer vor der Tastatur ist das daher durchaus ein mächtiges Werkzeug, ähnlich einer Autokorrektur auf Steroiden.
Zitieren
KI finde ich nur als Unterstützung für das sinnvoll, was man tun möchte.

Hab ein KI-Tool benutzt  um Gitarrenspuren aus Musikstücken rauszurechnen, damit ich da selbst mitspielen und zur Musik meiner Lieblingsbands üben kann.

Die Bandmitglieder haben ja keine Zeit.  :cry:
Es gibt einen Unterschied zwischen Proben (Gemeinsam) und Üben (Allein).

Dass KI auch für Reverse Engineering genutzt werden kann ist interessant,
aber ob sie bei einem Compiler und allen Flag-Kombinationen durchzusteigen halte ich für zu komplex.
Hab mir ansatzweise die Artikel von neuvuemeporte von seinen Versuchen durchgelesen.
Er hat bei F15 rausgefunden, welcher Linker zum erzeugen der EXE benutzt wurde,
aber theoretisch ist es möglich OBJ-Dateien von verschiedenen Compilern mit verschiedenen Flags und/oder mit Assembler erzeugte OBJ-Dateien zu linken.

Bei SCHICK/GEN war es relativ einfach, da nur BCC/TASM/TLINK relativ einheitlich benutzt wurden.
Ich hoffe, dass es bei RIVA auch so war.
Bei F15 scheint es ganz anders abgelaufen zu sein.
Zitieren
KI ist ein tolles Werkzeug, aber wie jedes Werkzeug muss man es nutzen können...

(08.11.2025, 16:42)HenneNWH schrieb: Bei SCHICK/GEN war es relativ einfach, da nur BCC/TASM/TLINK relativ einheitlich benutzt wurden.
Ich hoffe, dass es bei RIVA auch so war.
Bei F15 scheint es ganz anders abgelaufen zu sein.

Nach aktuellem Stand der Untersuchung bin ich mir relativ sicher, dass es bei RIVA ausschließlich Watcom 10.5 war. Sämtliche Strings im Binary ergeben in ihrer Kombination nur Sinn, wenn es Watcom 10.5 ist.

Aber vielleicht kann cmfrydos noch was dazu sagen, da er auf seiner Suche durch's Disassembly mehr Schweinereien gesehen hat :D
Zitieren
Guido Henkel hatte es vor 12 Jahren im Deathfire-Thread erwähnt, dass TurboC++ und später Watcom C++ verwendet wurde. Vielleicht hilft die Info euch etwas weiter.
Zum NLT-Wiki: http://nlt-wiki.crystals-dsa-foren.de/doku.php , Zum Drakensang-Wiki: http://drakensang-wiki.crystals-dsa-foren.de/doku.php
KEIN SUPPORT per E-Mail, PN, IRC, ICQ! Lest die Regeln und benutzt das Forum für sämtliche Anfragen! KEINE persönliche Betreuung!
Zitieren
Bestätigt in jedem Fall meine Entdeckungen! Danke :ok:
Zitieren
(10.11.2025, 11:44)Crystal schrieb: Guido Henkel hatte es vor 12 Jahren im Deathfire-Thread erwähnt, dass TurboC++ und später Watcom C++ verwendet wurde. Vielleicht hilft die Info euch etwas weiter.

Turbo C/C++ war die Einsteigervariante, Borland C++ die Profivariante.
Da Turbo C damals die geläufige Bezeichnung und Entwicklern ein Begriff war,
nehme ich an dass sich diese Bezeichnung weiterhin gehalten hat.
Analogie: Tempo <=> Zellstofftaschentuch.

Ich kann jedoch mit Sicherheit sagen, dass letztendlich der BCC++ 3.1 für Gen/Schick und Schweif benutzt wurden. Das AIL (Miles Sound System) lag offenbar als Quellcode in Assembler vor, beim Amiga Powerpack 2.0 Dekompressionsalgo für Bilder vermute ich eine Fremdbibliothek. Die hab ich für DOS 1:1 in Asm nachgebaut. Der Rest ist vermutlich über die Jahre inhouse entwickelt worden.

Für Riva wurde Watcom 10.x (x = 5 oder 6) verwendet. Genaueres kann ich zu Riva auch nicht sagen.

P.S. Guter Stil ist es in jedem Fall dieselbe Toolchain zu benutzen. Im Studium hab häufig noch alte Best-Practices gehört: "Keine OBJ-Dateien von verschiedenen Compilerherstellern nutzen." "Optimierung besser ausgeschaltet lassen.", etc. Manchmal geht's jedoch nicht anders.

Wenn man diese Glaubenssätze hinterfragt, kommt man zu dem Schluss, dass nicht jeder alles wissen kann oder soll.
OBJ-Dateien mischen C/Pascal/Asm war innerhalb des Borland-Universums möglich.
Optimierung auslassen deutet auf Compilerfehler oder Programmierfehler, wie nich initialisierte lokale Variablen hin.
Zitieren
Bin mir ziemlich sicher, dass es nicht 10.6 ist, weil sich da was an der Versionsangabe des DOS/4G-Extenders geändert hat, was in der letzten RIVA.EXE nicht sichtbar ist.
Zitieren
@HenneNWH

super - jetzt sind die Bits8 etc. schon mal weg, jetzt fehlen noch die unsigned/signed short/int/long

ich denke es wäre sinnvoll diese typedefs aus v302de.h in einen Header types.h oder sowas zu verschieben und nur types.h zu includieren

aus v302de.h
Code:
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
#if defined(__BORLANDC__)
typedef unsigned long uint32_t;
typedef signed long int32_t;
typedef uint8_t huge * HugePt;
#else
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef uint8_t* HugePt;
#endif

weil da bestimmt noch ein paar defines für die Kompiler/Platformen(DOS,Win,Linux,16/32/64bit,...) mit dazu kommen müssen

und dann kann man den Header types.h auch in der hero.h verwenden - dort hatte ich mal typedefs für (u)int32_t eingebaut
ich würde die STATIC_ASSERT macros auch einfach in diesen types.h Header schieben

aus hero.h
Code:
#if defined(__BORLANDC__) || defined(__WATCOMC__)
typedef signed long int32_t;
#else
typedef signed int int32_t;
#endif

wenn du das für den "(unsigned|signed) long" vorbereiten würdes wäre dann auch klar wie mit den anderen Typen zu verfahren ist

oder ich mach das mit einem Pull-Request wenn du die obigen ideen ok findest, bei long sind es noch keine tausend stellen wie bei short und int
Zitieren




Benutzer, die gerade dieses Thema anschauen: 3 Gast/Gäste