Le PSP (Program Segment Prefix) est un élément mémoire ajouté au devant du programme et contenant diverse informations comme la chaîne de commande passé au programme. Néanmoins pour nos besoins de décompilation, les valeurs contenues dans le PSP importent peu.
Ce qui est important c'est qu'il est ajouté au début de l'image du programme ce qui du coup décale toutes les adresses relatives (plus exactement le segment de ces adresses). Un PSP à une taille de 256 octets, soit 16 segments (0x10), tous les segments vont donc devoir être décalé de 0x10 ce qui inclut donc :
- la valeur initiale de CS
- la valeur initiale de SS
- tous les segments se trouvant dans la relocation table
Oui mais le programme utilise aussi des valeurs de segment, du coup comment les mettre à jour ? Et bien c'est justement à ça que sert la relocation table qui liste en fait dans le programme tous les endroits où une valeur de segment est utilisé.
Pour prendre un exemple très concret, reprenons Ravenloft. Comme je l'ai dit précédemment la table ciblent trois segments : 0x0000, 0x0255 et 0x026E. Le premier élément a pour adresse : Segment:0x0000 et Offset:0x0001 soit le deuxième octet du programme et quelle est la valeur stocké là ? 0x026E comme de par hasard l'un des trois segments identifiés par la relocation table et à laquelle il faudra ajouter 0x10 pour transformer cette valeur relative en absolue.
On peut alors dresser le schéma suivant de l'état initial de la mémoire et des registres segments :
PS : dans cette explication j'ai supposé que le programme serait posé à l'adresse 0000:0000 hors dans la réalité des fait cet adresse serait déjà occupé par le système d'explication et de fait le décalage commencerait au segment où le SE a décidé de chargé le programme plus le décalage imposé par le PSP.
1 Commentaire