Contexte et objectifs
En 2015, l'auteur a constaté que la totalité de la mémoire du jeu Wing Commander tournait dans les 640 Ko alloués par DOS, soit moins d’un million d’octets. L’idée était d’isoler les coordonnées X, Y, Z du vaisseau principal afin de les piloter à distance et de créer un mode coopératif où chaque joueur contrôlerait son propre engin.
Méthodologie de localisation des variables
Le processus a commencé par deux captures de mémoire réalisées avec la commande MEMDUMPBIN du débogueur DOSBox : une première lorsque le vaisseau était immobile (snapshotorigin) et une seconde après un déplacement linéaire (snapshotmoved). En appliquant les opérateurs logiques (snapshotorigin ⊙ snapshotlater) ∧ (snapshotorigin ⊕ snapshotmoved), 35 clusters d’octets variables ont été identifiés. L’inspection visuelle a réduit le champ à une douzaine de zones contenant des flottants ou de petits entiers. L’adresse finale retenue pour les coordonnées était 13D3:A9C2, confirmée par l’ajout d’entiers via la commande SM du débogueur, ce qui a déplacé le vaisseau de façon visible.
Pour la rotation, les vecteurs 3D étaient stockés sous forme de scalaires 4 octets où la valeur 256 représentait 1,0. Les petites rotations ne modifiaient qu’un seul octet, ce qui a permis de repérer les vecteurs up et forward dans la zone réservée aux propriétés d’entité (0x00‑0x3F). L’octet 0x3D était utilisé de façon récurrente pour la caméra, offrant ainsi un « window » de trois octets (0x3C‑0x3E) où les changements étaient observables.
Implémentation du trampoline et appel de fonctions
Les simples écritures en mémoire ne suffisaient plus à déclencher des actions complexes comme le tir laser. L’auteur a donc injecté un trampoline dans la chaîne de caractères "Loading WING COMMANDER" à l’adresse 13D3:0187 (et plus tard 13D3:0395) afin de rediriger le flux d’exécution vers des fonctions internes du jeu. Le code assembleur utilisé était :
pushf
pusha
xor si,si
push si ; argument : vaisseau 0
call far 12D7:0156 ; appel via stub, overlay‑indépendant
pop si
popa
popf
retf ; retour à l’adresse poussée par DOSBoxCe fragment conserve les registres du cadre de jeu, passe l’identifiant du vaisseau comme argument, puis revient proprement grâce à la convention cdecl. En mars 2017, un point d’injection stable a été trouvé dans la boucle principale à 0560:20E3, garantissant que le trampoline s’exécutait toujours dans un contexte prévisible. En juillet, la fonction do_damage a été détournée pour empêcher le second joueur de subir des dégâts, finalisant ainsi le comportement coopératif.
Résultats et limites
Le projet a permis de piloter deux vaisseaux simultanément, d’activer les canons laser et de désactiver les dommages subis par le second joueur. Cependant, la dépendance aux overlays Borland, chargés dynamiquement selon le chemin de jeu, impose une fragilité : chaque mise à jour du jeu ou modification du chargement d’overlay peut rendre le trampoline invalide. De plus, les fonctions de ciblage (missiles, IA ennemie) restent hors de portée sans une instrumentation plus profonde, limitant l’expérience coopérative à la navigation et au tir de base.