Obligement - L'Amiga au maximum

Samedi 19 août 2017 - 03:33  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Hit Parade
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Moteurs de recherche
 · Pages de liens
 · Constructeurs matériels
 · Matériel
 · Autres sites de matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Développeurs logiciels
 · Logiciels
 · Développeurs de jeux
 · Jeux
 · Autres sites de jeux
 · Scène démo
 · Divers
 · Informatique générale


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


En pratique : Modification de fichiers binaires
(Article écrit par Pierre Ardichvili et extrait d'Amiga News - avril 1991)


Voici quelques notions (très) élémentaires sur la modification des fichiers binaires.

Modification, correction, "patch"

Pour modifier un programme, il y a la voie royale et la voie expéditive. La voie royale consiste, quand on a les sources, à les modifier et à recompiler. Mais voilà, on n'a pas toujours les sources, et quand on les a, comme par hasard, elles ont été écrites pour le compilateur qu'on n'a pas, et ça ne va pas toujours tout seul.

En plus, on n'est pas nécessairement programmeur dans le langage utilisé, ni même programmeur du tout !

La voie expéditive consiste à faire un "patch", c'est-à-dire une modification directe. On peut aussi vouloir donner à l'utilisateur un moyen de modifier un fichier ou le comportement d'un programme plutôt que de lui fournir une nouvelle version, surtout quand le dit fichier est en ROM, ou protégé. On lui fournit un correctif, qui est un petit programme qui, lancé au bon moment, va modifier le programme chargé en mémoire. C'est ce qui se passe lorsque votre startup-sequence contient l'instruction "Setpatch", qui va corriger en mémoire quelques fichiers et donc annuler certains "bogues" du système.

Une autre approche est celle des programmes copieurs de disquettes qui ont, par exemple, une fonction d'annulation du système de protection particulièrement ridicule qui consiste à demander de taper un mot trouvé dans la doc (je rappelle que je suis personnellement toujours aussi opposé au piratage, mais le type de protection ci-dessus est doublement stupide car énervant et parfaitement inefficace).

Mais laissons ces techniques aux programmeurs, et voyons ce que peut faire un amateur capable de se débrouiller un peu.

Le fichier exécutable d'un programme est en fait une suite de nombres binaires, dont certains sont des codes d'instructions, d'autres des adresses, d'autres encore, ceux qui nous intéressent, des valeurs de constantes ou des codes de caractères, affichables ou non.

Si nous disposons d'un moyen (FileMaster par exemple) de lire et d'écrire en binaire dans un fichier exécutable, et d'une manière telle que les sommes de contrôle des blocs soient recalculées automatiquement, nous pourrons déjà faire des choses intéressantes.

Notions de base

Quelques notions de base sur la représentation des caractères. Il y a dans le répertoire "C:" de l'Amiga un moyen de lire directement un fichier en binaire, c'est l'instruction "Type" avec l'option "h". Ce "h" veut dire hexadécimal, car la lecture en binaire pur est impraticable. Les suites de nombres binaires de 8 bits qui constituent le fichier sont représentés en notation hexadécimale par des groupes de deux caractères de 0 à 9 puis de A 4 F. Par exemple :
décimal     binaire     hexadécimal
255     =   11111111 =  FF
C'est d'ailleurs le plus grand nombre entier positif représentable par 8 bits ou deux caractères en hexadécimal. Le répertoire "C:" de votre AmigaOS 1.3 contient une commande "Eval" qui vous permettra de faire sans peine ces conversions.

Lorsque vous utiliserez "Type" avec l'option "h", vous venez dans la moitié de gauche de l'affichage des blocs de huit caractères qui sont exclusivement 0 à 9 et A à F. Dans la colonne de droite, vous verrez, en regard, des caractères divers dont certains forment des chaînes parfaitement lisibles. Les points correspondent à des codes non affichables.

Il faut donc à présent parler de la représentation des caractères. Il existe pour cela une norme dite ASCII, qui permet d'associer chacun des nombres 0 à 255 (représentés par 00 à FF en hexadécimal) à un caractère. Certains, à partir du n°32 (hexadécimal 20 ; nous dirons désormais hex 20) jusqu'au 126 (hex 7E), puis du 161 au 254, sont affichables, d'autres sont des caractères de contrôle, comme le retour au début de ligne (dec 13, hex OD), ou la barre d'espacement (dec 32, hex 20), ou encore le caractère NULL (dec 0, hex 00) qu'il ne faut pas confondre avec le caractère affichable 0 (dec 48, hex 30). En fait, comme rien n'est simple en informatique, la deuxième moitié de la table (dec 127 à 255) existe en plusieurs variantes. Ceci ne nous gênera pas trop car l'immense majorité des caractères affichables que nous souhaiterons modifier se trouve dans la première moitié de la table.

Modifions

Où trouver une table ASCII ? Dans la doc de votre imprimante ou dans le manuel d'AmigaOS. A ne pas confondre avec la table des codes clavier, rien à voir !

Maintenant, ce n'est pas parce que vous verrez un "A" dans la moitié de droite de l'affichage de "Type opt h", qu'il s'agit nécessairement d'un "A". Ce qui est sûr, c'est qu'il y a à cet endroit des "1" et des "0" correspondants au code hexadécimal 41. L'Amiga sait comment il doit lire cet endroit du fichier, c'est le programme qui lui dit si à cet endroit il y a un morceau d'une adresse, d'un code d'instruction, un code de contrôle ou un caractère d'une chaîne affichable.

Et maintenant, modifions ! Nous allons prendre trois exemples de complexité croissante.

1. Franciser un logiciel

Je prends un programme au hasard : F/A-18 Interceptor. Lorsque vous avez réussi votre mission, plutôt que l'ordre sec "Come back to carrier", vous préféreriez "A la soupe".

Prenez FileMaster, chargez une copie du programme (j'espère que vous n'êtes pas assez fou pour faire des modifications sur un original !) et demandez une recherche de la chaîne de caractères ASCII "Come ba" ; il suffit d'en mettre assez pour qu'il n'y ait pas de confusion possible.

Lorsque FileMaster l'a trouvée, vous choisissez le mode ASCII, et vous tapez dans la moitié de droite le texte que vous voulez, par-dessus l'ancien, en remplaçant par des espaces les caractères en trop.

Deux remarques s'imposent :
  • Ne débordez ni à gauche ni à droite, car vous écraseriez des codes que le programme voudra lire plus tard, avec plantage assuré à la clé.
  • Il en résulte qu'on ne pourra pas remplacer une chaîne que par une autre plus courte ou au plus de longueur égale !
Essayez, c'est amusant mais on s'en lasse vite.

2. Installation sur disque dur

Reprenons le cas d'Interceptor. Il y a sur la disquette le programme principal, puis deux répertoires "Text" et "Pix", dans lesquels se trouvent des fichiers que le programme appelle au cours de son chargement ou en fonctionnement. Copiez tout cela dans un tiroir appelé "Simulateurs" de votre disque dur.

Ouvrez-le, cliquez sur l'icône, tout a l'air de bien se passer, et à un moment donné, plus rien. Pourquoi ? Parce que le programme veut aller chercher les répertoires "Text" et "Pix" dans df0:, et bien entendu il ne les trouve pas car vous avez retiré la disquette. Un coup de FileMaster, on cherche la chaîne "df0:", et on en trouve une bardée ! Remplaçons toutes les chaînes "df0" par une chaîne quelconque, par exemple "F18", mettons dans notre startup-sequence une ligne :

Assign F18: dh0:Simulateurs

...et le tour est joué. Désormais le programme principal ira chercher ses données dans l'unité logique "F18:", qui est dans le cas présent le bon répertoire.

3. Sortons du monde des chaînes ASCII

Nous allons prendre l'exemple du programme Files de Matt Dillon (Fish 169). C'est un programme de catalogue de fichiers. Je l'utilise pour savoir à tout moment où trouver sur mes disquettes un programme dont je connais le nom. Ce qui m'énerve, c'est qu'il ouvre une ridicule petite fenêtre en bas et à droite de l'écran ; la première chose à faire est de charger le fichier de données en allant cliquer de la souris dans cette fenêtre pour ensuite faire un choix dans un menu tout en haut à gauche ! Matt Dillon est un génie mais la convivialité, il s'en moque éperdument et il ne s'en cache pas.

Dans le cas présent, on a la chance d'avoir les sources. En regardant le fichier main.c, on est un peu ahuri de la complication de l'approche qu'il a prise pour ouvrir une simple fenêtre, mais on réalise que cette approche a pour but d'ouvrir une fenêtre dans le coin inférieur droit de l'écran du Workbench, quels que soient le mode et la résolution dans lesquels il est ouvert (PAL ou NTSC, entrelacé ou non).

En examinant le listing, on trouve assez facilement que deux des paramètres intéressants de la fenêtre (coordonnées du coin supérieur gauche), sont calculés à partir de deux des éléments consécutifs d'un tableau, égaux respectivement à -16 et -8. Je passe sur les raisons de ceci ; toujours est-il que la logique du programme veut que si on les remplace par des valeurs positives appropriées, la fenêtre s'ouvrira où l'on voudra.

Il faut encore savoir que ces paramètres sont représentés dans la structure d'une fenêtre par un entier signé à 16 bits, donc par un groupe de quatre caractères hexadécimaux. Ceci dit, dec -16 = hex FFF0 et dec -8 = hex FFF8.

On recherche donc par FileMaster la chaîne hexadécimale FFF0FFF8, et on la remplace par 00000001. Ceci fait s'ouvrir la fenêtre à l'endroit voulu mais n'en a pas modifié la taille. Pourquoi avoir remplacé FFF8 par 0001 et pas 0000 ? Tout simplement pour ouvrir la fenêtre un pixel plus bas que le haut de l'écran, ce qui permet avec la souris d'attraper la première ligne de pixels de l'écran et pouvoir le faire glisser vers le bas. Ça, ça devrait vous en mastiquer une fissure, mais le truc n'est pas de moi, il est de William Hawes.

On constate ensuite que les dimensions de la fenêtre principale sont données par des variables auxquelles sont assignées les valeurs 320 et 100, sur deux lignes consécutives du programme. Il faut donc rechercher ces chaînes séparément (hex 0140 et hex 0064) et par bonheur on les trouve, pas trop distantes l'une de l'autre. On les remplace par les chaînes hexadécimales 0280 (correspondant à 320) et 00FF (correspondant à 255 pour avoir une ouverture plein écran, moins une ligne dont nous avons parlé plus haut). Et cette fois, ça marche, la fenêtre de Files s'ouvre en plein écran.

La description un peu longue de cette manipulation a surtout pour but de montrer qu'il faut parfois de la patience et un peu de recherche, mais je vous garantis que j'y ai passé moins de temps qu'à recompiler ou plus exactement à préparer une recompilation, il suffit de lire le "ReadMe" qui accompagne les sources de Files pour s'en convaincre.

Limitations

Le correctif est expéditif, mais c'est un expédient. Il résout un problème et peut en créer d'autres. Par exemple, essayer d'ouvrir une fenêtre aux dimensions 640x256 ne fera pas plaisir à un Amiga NTSC. La version de Files modifiée comme ci-dessus ne marchera pas sur ce type de machine.

Déontologie

Non, cette notion n'est pas réservée aux médecins ! Je me permets de vous recommander de ne modifier des programmes qu'à votre usage personnel. Si vous avez l'intention de distribuer un programme modifié, ayez soin d'en demander l'autorisation à l'auteur.

Premièrement, Si votre modification ne couvre pas tous les cas de figure, les défaillances du programme modifié peuvent nuire à la réputation de l'auteur. En second lieu, vous êtes passible de poursuites en contrefaçon. Le milieu de l'Amiga est jeune et dynamique, mais il y a toujours un savant équilibre à réaliser entre la créativité et la jungle.

Les éditeurs de texte/hexadécimal disponibles sont FileMaster (Fish 361), NewZap (Fish 164) et FedUp (Fish 230). Je rappelle que ces deux derniers programmes ont en commun le défaut de ne pas trouver une chaîne si elle est à cheval sur deux blocs.

La revanche de Matt Dillon

Dans la première partie de cet article, nous avons examiné la méthode expéditive de modification d'un exécutable grâce à un programme de lecture-écriture directe dans un fichier binaire. Cette méthode a l'avantage d'être simple et de ne pas exiger une compréhension profonde de l'écriture du programme concerné. Elle permet aussi de faire des bêtises. Nous l'avons appliquée à Files de Matt Dillon pour modifier la taille de la fenêtre de travail du programme, sans essayer de trop comprendre la logique du programme : cela nous a pris moins de temps que de tout recompiler, surtout avec un compilateur différent de celui que l'auteur a utilisé, mais nous avons créé un bogue, car le programme Files ainsi modifié refuse d'ouvrir une fenêtre dans un écran NTSC. C'était de la bidouille, mais la bidouille est amusante et elle rend d'appréciables services.

En fait, il y avait moyen de faire la chose en moins de 40 secondes, en utilisant une autre technique que Matt mis à notre disposition dans un certain nombre de ses programmes (Files, Clock, DME). Nous allons examiner cette méthode.

Principes généraux

Pour agir sur le comportement d'un programme, on peut procéder de diverses manières :
  • Commencer par un dialogue avec proposition des valeurs par défaut, comme dans le programme Prep de préparation des disques durs de Commodore.
  • Passer au programme des paramètres en même temps que ses arguments ; typiquement, c'est l'approche des programmes d'archivage Arc, Zoo, etc. et des éditeurs style Z, Emacs et des compilateurs.
  • Le doter de menus déroulants, comme AZ, ou d'une combinaison d'écrans de commande et de menus, comme Deluxe Paint
  • Lui associer un fichier de configuration que le programme va lire chaque fois qu'on le lance, comme AmigaShell avec shell-startup, ou ParM avec Parm.config.
Toutefois, lorsque les paramètres à modifier sont peu nombreux, et la modification peu fréquente, les méthodes ci-dessus sont lourdes et encombrantes pour l'utilisateur, soit que l'on soit obligé de valider à chaque lancement des choix toujours les mêmes, soit que l'on doive suivre lors de l'installation du programme une procédure comportant le placement d'un fichier auxiliaire à un endroit bien précis, où le programme saura le trouver.

L'idée est alors de procéder à un correctif (patch), c'est-à-dire à une modification directe de l'exécutable, mais sans avoir recours à un utilitaire du type FileMaster, et sans avoir à rechercher dans l'exécutable la chaîne à modifier. Une solution est proposée par Matt Dillon, elle s'appelle DEEMU, et on la trouve sur Fish 168.

DEEMU

Lu à l'envers, l'acronyme DEEMU signifie : User Modifiable Executable Embedded Data. En français et à l'endroit, ça donne : Données Exécutables Encapsulées Modifiables par l'Utilisateur.

L'idée est simple : au début du bloc d'initialisation des variables du programme, on initialise une structure appelée DEEMU, dont le nom est en fait sans importance, mais qui contient des éléments de repérage, et les constantes à modifier. Pour les modifier, on fait appel à un programme auxiliaire qui s'appelle CONFIG. En gros, ce programme va chercher dans l'exécutable le repère cité plus haut, va lire à la suite les constantes de la structure, les présenter d'une manière interactive à l'utilisateur pour modification, s'occuper des problèmes de longueur des chaînes, et faire les écritures dans l'exécutable.

Voyons à titre d'illustration comment cela se passe pour Files. On trouve dans le source "main.c", juste après les #include, l'initialisation d'une structure :

DEEMU

On y voit le repère STRT, le type de la structure sur laquelle l'utilisateur pourra intervenir, ici une structure de fenêtre référencée NW (en fait, il y a quatre caractères disponibles), un drapeau non utilisé, la longueur en octets du champ sur lequel on veut intervenir (ici 8, puis qu'il y a 4 entiers signés de 16 bits à modifier), puis les valeurs de ces quatre entiers, à savoir LeftEdge, TopEdge, Width, Height (note : ce ne sont pas nécessairement les valeurs des éléments de la structure, mais éventuellement des constantes à partir desquelles les éléments de la structure peuvent être calculés).

Ensuite, une référence à un texte, qui apparaît ailleurs (dans la fenêtre de requête de chargement du fichier catalogue). La série de zéros complète simplement l'espace réservé au texte en question. Enfin, l'identificateur de fin de structure DEEMU, à savoir END, et les zéros qu'il faut pour aligner la structure sur des mots entiers.

Ceci paraît compliqué, mais en fait ces quelques lignes supplémentaires dans le programme ne l'alourdissent que très peu, et rendront la manipulation de modification très simple, rapide et même... conviviale !

Matt fournit un programme CONFIG, qui est écrit précisément pour permettre des modifications des paramètres indiqués plus haut, à savoir emplacement et taille d'une fenêtre, contenu d'un ou de plusieurs textes donnés. En fonction des modifications qu'il veut permettre à l'utilisateur, le programmeur pourra écrire son programme de type CONFIG, qu'il livrera à l'utilisateur. Ce programme CONFIG pourra d'ailleurs intervenir sur des programmes de différents auteurs, à condition que ces derniers adoptent les conventions adéquates.

Comment se passe alors la modification ?

Dans le cas présent, on tape "CONFIG FILES". Les réponses ont été données pour ouvrir une fenêtre à tout l'écran. Contrairement à ce qui se passait dans le cas du correctif approximatif que nous avions décrit au début de l'article, dans le cas présent, la logique du programme est respectée, et la fenêtre de Files s'ouvrira à tout l'écran, au lieu de refuser l'ouverture de la fenêtre dans un écran NTSC.

Conclusion

Cette méthode de correctif vaut ce qu'elle vaut, elle protège la réputation de l'auteur du programme, car elle lui permet de contrôler ce que peut faire l'utilisateur ; elle a sa puissance et ses limitations.

Il s'agissait simplement de montrer ici une manière de traiter la modification des programmes différente de l'écriture directe dans les exécutables par l'utilisateur.


[Retour en haut] / [Retour aux articles]