APPLICATIONSCOURS DE BIDOUILLAGE ★ INITIATION - PROTECTIONS LOGICIELLES ★

Protection Logiciel n°42|Amstrad Cent Pour Cent)Applications Cours De Bidouillage

Nous avons tous, un jour ou l'autre, tenté de copier des fichiers sans succès, lister un programme Basic sans rien obtenir de cohérent. Le pourquoi du comment est simple : ces fichiers et listings étaient protégés pour que vous ne puissiez rien voir de leur contenu.

Nous allons vous expliquer le fonctionnement de ces protections; ainsi, vous pourrez vous amuser comme des petits fous pour mettre vos chefs d'oeuvre à l'abri des regards indiscrets.
Voici donc en exclusivité mondiale pour les lecteurs d'Amstrad Cent Pour Cent, l'initiation qui, même dans vos rêves les plus fous, n'aurait été imaginable: comment protéger vos créations personnelles ?

XOR LE MAGNIFIQUE

Pour m'aider à préparer ce dossier, j'ai simplement demandé à l'un des plus férus en La matière, XOR, de me révéler quelques-uns de ses secrets, Il va de soi que sous ce pseudo ( bien connu dans le milieu des tripatouilleurs d'octets ) se cache une tête remplie d'idées, qui nous a fait la gentillesse de partager son savoir avec nous.

TOI PAS LIRE MOI

Cela fait des années que les programmeurs protègent leurs logiciels ; de même, tous les jours de nouvelles méthodes et ruses arrivent à leur esprit tordu. Or ( donc, pour vous parler de tout, il nous faudrait écrire un livre  ( tiens, c'est pas une mauvaise idée ). Donc, sans être trop prétentieux, nous allons commencer par le commencement, à savoir la protection des fichiers en lecture.

La méthode la plus simple et la moins efficace est la « sauvegarde par l'option P ». En effet, encodez un fichier Basic de quelques lignes, sauvegardez le comme suit:

SAVE "TOTO",P

Réinitialisez votre ordinateur et chargez le fichier par:

LOAD "TOTO"

Faites « LIST ». Etrange, non? Pas de liste disponible, C'est comme si le fichier n'avait jamais existé. Pourtant ,le fichier ainsi protégé peut être exécuté normalement par:

RUN "TOTO"

Cette fameuse « option P » code le programme. L'ordinateur teste ce codage en exécutant la commande LOAD. S'il constate une protection, il exécute un NEW en fin de chargement, d'où l'impossibilité de lister le programme car, en fait, celui-ci n'est plus en mémoire.

Aujourd'hui n'importe quel logiciel de traitement de fichier possède une instruction pour supprimer cette protection, Renommez, par exemple, un tel fichier à l'aide de Discology en suppriment le [P]. Voilà, le fichier vient d'être déprotégé.

Il existe d'autres méthodes plus radicales pour cacher une liste, Vous pouvez, par exemple, cacher des lignes Basic qui n'apparaîtront pas à la commande LIST, ajouter un programme en langage machine à la suite de votre source Basic, encoder une petite routine machine dans le programma lui même - et cela sous les yeux du voyeur - , écrire vos fichiers dans les User inaccessibles au Basic automodifier un programme Basic ( poker de nouveaux Token ) ; eu encore plus compliqué, masquer (ou coder) votre source Basic pour le rendre complètement incompréhensible.

Il reste enfin le classique des classiques,« le code d'accès au programme ». Nous allons faire maintenant le tour de ces méthodes, Avant de nous lancer, il faudra vous munir d'une disquette vierge et formatée et, si vous en avez les moyens, d'un éditeur de secteurs comme Discology.

Et pourquoi pas un assembleur si le coeur vous en dit ?

Voici, pour vous mettre en haleine, un petit programme qui trouvera sa place an début de vos listings Basic. Il vous demandera un code qui autorisera l'accès au programme.

Attention, ce programme ne protège pas le source contre la lecture mais rend son utilisation impossible aux personnes non autorisées.

Voilà, il suffit de modifier la variable CODE$ an remplacent le mot « PASSE » parce lui de votre choix,.

Passons à des choses plus sérieuses. Faites un CAT après avoir inséré une disquette dans le lecteur. L'ordinateur affiche alors:

Drive A : User 0

Suivi du contenu de la disquette.

Le « Drive A » indique qu'il s'agit du lecteur A ( premier lecteur ), « User 0 » vous indique que les fichiers affichés sont dans la zone courante 0. Cela nous emmène à penser qu'il existe d'autres zones pour sauvegarder nos fichiers.

Sous Basic, vous pouvez accéder à 16 zones utilisateur ( User de 0 à 15 ). Pour cela, utilisez la commande:

ùUSER, nb

Avec la variable nb allant de 0 à 15. Vous Constatez grâce à là commande CATque les fichiers de l'User 0 ne figurent pas dans l'User, 1, 2, 3 ... 15.

Au-delà de cette limite (15), le Basic est incapable d'accéder aux Users supérieurs, Pour cela, utilisez le poke suivant :

POKE &A701, nb

Avec la variable nb allant de 0 à 255. Cool, non ? Saviez-vous que ces User ne sont pas détectés par la commande CATALOGUE de Discology?

Autre chose, quand un fichier est effacé du catalogue d'une disquette par la commande ùERA,"fichier", celui-ci est en fait encore disponible dans le User 229 jusqu'à la prochaine sauvegarde d'un fichier sur cette même disquette.

Allez voir cet User pour vous en persuader. La récupération d'un fichier effacé devient alors un jeu d'enfant.

Si TOTO.BIN a été effacé par:

ùERA, "TOTO.BIN"

Récupérez-le avec:

POKE &A701,229
ùREN, "0:TOTO.BIN", "TOTO.BIN"
ùUSER, 0

Vous venez ainsi de renommer le fichier "TOTO.BIN" en le replaçant en  USER 0.

Jusqu'à présent, nous n'avons pas fait appel è des connaissances trop particulières. Par contre, pour la suite de notre histoire, il va falloir être attentif, Pas de frayeurs inutiles car je vais juste vous démontrer comment est stockée une ligne Basic par l'ordinateur, Ces explications seront primordiales pour la suite de notre initiation,

LES LIGNES BASIC

En chargeant un programme Basic, ou plus simple en saisissant une ligne Basic grâce Il son éditeur, la mémoire de l'ordinateur subit certaines modifications. Le Basic sait comment stocker vos lignes en mémoire, nous allons les décoder. Un programme Basic commence toujours à l'adresse 368 (&170 héxadécimal).

Les deux premiers octets indiquent la longueur de la lignetle Basic n'en n'utilise qu'un et c'est une faille que nous étudierons plus loin}, les deux suivants stockent le numéro de la ligne ; vient ensuite une suite de codes (lestokens) qui sont la représentation des instructions Basic. Ex: le Token 138 correspond à l'instruction CLS. Suite à toutes cesinstructrons,vientserajouterunO qui signifie la fin de la ligne, Alors, la deuxième ligne peut commencer, etc.

La fin du programme sera marquée par trois 0 successifs. Cela vous parait compliqué 7 Alors suivez-moi de très près.

Réinitialisez votre ordinateur et pokez les valeurs suivantes:

Pour un numéro de ligne égale à 50:

POKE 365+2,50
POKE 368+3,0

Pour mettre un CLS dans cette ligne:

POKE 368+4,138

Enfin, pour marquer la fin de la ligne:

POKE 368+5,0

Reste la longueur. 2 octets pour stocker la longueur+2 octets pour le numéro de ligne + 1 octet pour le Token et 1 dernier octet pour le 0 de fin de ligne. Cela nous fait une petite addition dont le résultat est 8. Donc:

POKE 368+0,8
POKE 368+1,0

Pour voir le résultat, faites simplement LIST.

C'est magique, non?

Vous venez de créer une ligne 50 contenant l'instruction CLS. Il va de soi que la prochaine ligne Basic sera stockée à partir de 368+6 et cela jusqu'en fin de programme ( trois 0 ).

Vous voulez connaître le numéro de la  33eme ligne d'un programme Basic ? Pas de problème, encodez en mode direct  celui-ci:

nbligne = 33 :deb = 368 : FOR l=1 to nbligne-1:A=PEEK(DEB):deb=deb+a:NEXT:PRINT PEEK(deb+2)+PEEK(deb+3)*256

Il va de soi qu'il faut remplacer le « nbligne » par 33 ou toute autre valeur de votre choix. Voyons maintenant d'autres astuces sorties tout droit du sac de XOR.

LES LIGNES CACHEES DU BASIC

Pour commencer ce chapitre, saviez vous que le Basic n'affiche les lignes (par les commandes LIST ou EDIT) qu'à partir de la ligne numéro 1 ? Le zéro, il ne connaît pas. Alors, rien ne nous empêche de lui balancer une ligne zéro pour l'embrouiller jusqu'à la moelle. la méthode est fort simple. Il suffit de poker en 370 un zéro. Vous vous souvenez qu'à cette adresse (tout comme la suivante) se trouve le numéro de la première ligne du Basic.

Voici un exemple. Tapez:

10 CLS

Faites LIST pour constater la présence de cette ligne. Puis pokez directement:

POKE 370,0

Refaites LIST. Hé ! hé ! hé ! Y'a p'us de Liste. Mais attention, le programme est toujours là et vous pouvez même le lancer par RUN, Quelle classe! Je ne le dirais jamais assez. Voilè pour la ligne zéro: sachez tout de même qu'un éditeur de fichiers tel Discology est capable de lire ce type de ligne.
On peut cacher une ligne au sein même du programme. Pour cela, Il existe encore une méthode simple mais à laquelle il fallait penser. Reportez-vous plus haut dans les explications pour vous remémorer la structure d'une ligne Basic (longueur, numéro de ligne, etc.). Le Basic, en exécutant un programme, ne tient pas  compte de la longueur donnée en début de ligne. Son ,repère de fin ,de ligne est. Je zéro placé en fin de ligne. La longueur est utilisée par l'éditeur Basic pour lister le programme ou les sauts (GOTO, GOSUB".~, Pour cacher une ligne, il suffit de tromper le listeur Basic en lui Indiquant une longueur égale à la ligne courante, plus la longueur de La ligne qui restera cachée. Soyons clair.

Vous voulez cacher la ligne 25 de votre programme ? Il suffit de calculer sa longueur (disons 35 octets) puis celle de la ligne précédente (disons la ligne 20 qui a une longueur de 56 octets), d'additionner l'ensemble et de poker la somme de cette addition comme longueur de la ligne 20.
C'est pas clair, hein ?

Je vais vous donner un exemple. Tapez ce petit programme:

10 MODE 1:CLS
20 INKE 0,0: INK 1,26
30 BORDER 0
35 PRINT "COUCOU"
40 END

Nous allons cacher la ligne 35. Calculons donc, dans un premier temps, l'adresse des octets qui renferme la longueur des lignes 30 et 35 de notre programme Basic. Pour cela, j'ajoute en fin de programme, le sous-programme que voici:

100 DEB=368 :MODE 2
110 LL=PEEK (DEB+1)*256+PEEK (DEB+0)
120 NL=PEEK (DEB+3)*256+PEEK (DEB+2)
130 PRINT “LIGNE ”NL;” = “LL;” OCTETS”
140 PRINT “ADRESSE ” ;DEB+1
150 CALL &BB18 :DEB=DEB+LL :GOTO 110

Faites alors un RUN 100 (pour executer le programme à partir de la ligne 100) et vous saurez tout sur votre programme Basic: â savoir, la ligne 30 fait 8 octets qui sont stockés an 395-396 (même si 396 'est égal à zéro). tout comme la ligne 35 qui a una longueur de 15 octets. J'ajoute les 8 au 15 pour obtenir une longueur fictive de 23. Je poke en 395 cette valeur et hop lia ligne 30 va cacher la suivante. Essayez maintenant:

POKE 398,23:LIST

La ligne 35 a disparu !
N'ayez pas peur, lancez le programme pour vérifier que le COUCOU s'affiche, même s'il ne figure plus dans la liste ( ! ). Vous pouvez y aller. .. EDIT 35, RENUM, etc. Elle ne montrera plus le bout de son nez. La ligne 35 est devenue..."fantôme.

ET LES TOKENS DOCTEUR?

Il t a très longtemps, avec mon ami Septh, j'avais concocté un petit programme intitulé « Le CLS le plus rapide du monde ». Il était truffé de lignes automodifiant le programme Basic, donc carrément incompréhensible à première vue. lmaginez, en effet, une ligne du type:

OUT 1,100,10

Cela ne veut rien dire. Parcontre, si la ligne précédente modifie le TOKEN de OUT; qui est 185, en le remplaçant par 204 (TOKEN de SOUND), les choses n'auront plus la même signification.

Voici un exemple:

10 MODE 1
15 POKE 393,204
20 0UT 1,100,10
25 POKE 395,185
30 LIST

Cachez les deux lignes 15 et 25 par la méthode décrite plus haut et donnez m'en des nouvelles.

ETRANGES APPLICATIONS

Cela dit, vous ne voyez toujours pas comment il est possible, à partir de ces éléments, de tromper une personne fouinant dans vos programmes. O.K. ! je suis là pour ça.
Commençons par un petit exercice simple. Je vais vous montrer comment inclure un petit programme en langage machine dans votre source Basic. Pour ne pas compliquer les choses, j'ai choisi volontairement une routine bidon qui ne fait qu'un simple bip, équivalent de PRINT CHR$(I7).

LD A,1
JP &BB5A

En désassemblant cette routine, on obtient les cinq codes hexadécimaux suivants:

3E,07,C3,5A,BB

Nous allons également créer une ligne Basic bidon qui réservera cinq octets pour stocker notre routine. Que pensez-vous de:

10 REM 12345

Cette ligne est la première de notre  programme Basic. Elle commence donc en 368. La zone 368-369 réservée pour la longueur, 370-371 pour le numéro de ligne. Le token de REM {ou de l'apostrophe le remplaçant « ' » est codé avec un 192 dans l'octet 372. Vient ensuite un espace en 373 et cinq octets ( de 374 à 378 ) qui stockent les Cinq valeurs ASCII de 1,2,3,.4, 5 soit 49,50,51,52,53.
Vérifiez par vous-même:

PRINT PEEK (314) -> 49
PRINT PEEK (318) -> 53

C'est dans cette zone que nous allons poker notre routine assembleur. C'est également cette zone qui sera appelée pour l'exécution de la routine du bip sonore. Voici la démarche à suivre:

POKE 374,&3E
POKE 375,&07
PDKE 376,&C3
POKE 377,&5A
POKE 378,&BB

Faites LIST. Vous voyez, votre ligne da REM ne ressemble plus à grand-chose. Parcontre, elle renferme maintenant la petite routine. Vous pouvez sauvegarder ce programme et une éventuelle suite sans problème avec l'instruction:

SAVE "TOTO "

Pour exécuter le routine, il suffit de l'appeler par:

CALL 374

Essayez, vous m'en donnerez des nouvelles. I1vadesoi qu'au lieu de faire un petit bip, vous auriez pu décoder un programme ( préalablement codé ) ou lancer un appel à une autre routine machine ...
A propos de codage/décodage, voici un petit exemple pour éclairer le principe. L'opération logique XOR ( tiens donc ) a la particularité de restituer une valeur à condition de l'utiliser deux fois de suite sur unmême octet.
Je m'explique:

  • soit une valeur A et B. En appliquant A XOR B, on obtient C. A étant la valeur initiale, et B une constante de notre choix. Nous nous retrouvons donc avec deux valeurs, C et B. La valeur A étant apparemment perdue. Eh bien non, A n'est pas perdue, Il suffit de faire B XOR C et Je résultat est A. Voilà l'exemple pour coder une ligne da LONGS octets.

     ORG 314
     LD HL,ADRESSE DEBUT
     LD B,LONG
BOUC LD A,(HL)
     XOR 123
     LD (HL),A
     INC HL
     DJNZ BOUC
     RET

Il va de soi que vous devriez au préalable calculer l'adresse de début de cette dernière:
Voici le code assemblé soit 13 octets:

21,??, ??,06, ??,7E,EE,7B,77,23,10,F9,C9

Prenez n'import lequel de vos programmas Basic et ajoutez-y les deux lignes suivantes:

1 REM 1234567890123
2 CALL 374

Pokez ensuite les 13 octets comme dans l'exemple précédent. Exécuetez en mode direct un CALL 374 et sauvez le fichier sous un nom de votre choix. Jouez ensuite la voyeur. « Loadez » le programme et « listez » le. Drôle de tête, non? Exécutez-le, c'est comme si de rien n'était.. Vous pourrez par exemple placer dès le début de votre programme ( après les deux lignes ) un ON BREAK GOTO 60000 et en ligne 60000 un CALL 374.

De là, n'importe quelle interruption du programme par la touche ESC recodera ce dernier. La classe, quoi !

Bon, c'est pas tout mais faudrait p'têt penser à boucler la boucle. Je vais donc vous donner le nec plus ultra, à savoir ..

LE BASIC MACHINAL

Je suis assez fier de cet intertitre. Il va de soi qu'il fait référence au langage machine collé eux fesses du Basic. Donc indétectable mais, surtout, illisible par le petit frère curieux ( si,si, regardez, il est déjà en train de lire le journal par dessus votre épaule ).
Le principe d'ajouter une routine en langage machines la suite d'un programme Basic est comme d'habitude, fort simple. Il suffit de poker la routine machine a la suite des trois zéros finissant le programme Basic sans oublier de déclarer la nouvelle longueur du fichier Basic dans le HEADER ( en-tête du fichier en français. Avant de nous lancer, voyons de quoi est constitué ce HEADER.
Créez un fichier bidon comme suit:

10 '
20 'prog bidon
30 '

Sauvez-le sous le nom de 04.BAS ( c'était mon appellation, vous pouvez en prendre une autre ).

Lancez Discology et grâce à l'éditeur de fichier ( EDITION -> MODES -> EDITION FICHIER ), éditez le fichier Q4.BAS. Vous devez obtenir une page similaire au document 1:


Doc 1

Le HEADER est formé des 128 premiers octets, soit les huit premières lignes affichées à l'écran.
L'adresse 0 correspond à l'USER, les 11 octets suivant, c'est le nom du fichier. Les six qui suivent ne sont pas utilisés. A l'adresse &12, nous trouvons le type de fichier (00=BASIC, 01=BASIC protégé, 02=binaire, 03=binaire protégé). Les octets &13 et &14 ne sont pas utilises. En &15 et &16, on trouve l'adresse d'implantation du programme dans notre exemple 70 et 01 soit &170 ou 368 décimal). l'octet &17 ne sert à rien. &18 couplé à &19 donne la longueur du fichier(ces octets nous intéressent1. Dans notre exemple, le fichier a une longueur de &0022 octets (soit 34 octets en décimal).

On continue dans la joie et la négresse, &1A et &1B donnent l'adresse d'exécution. Cette adresse est à zéro pour les fichiers Basic. Les valeurs allant de &1C à &3F ne sont pas utilisées. Viennent, enfin, &40 et &41 qui redonnent pour la deuxième fois la longueur du fichier, Attention, ces adresses sont prioritaires par rapport à &18 et &19.

L'adresse &42 ne sert à rien ; par contre, en &43 et &44 nous trouvons le checksum de l'ensemble du HEADER, à savoir la somme de l'addition de tous les octets allant de la zone &0000 à &0042. On nomme également cette addition CSH. Le reste des octets (&45: à &7F) peut être rempli avec n'importe quoi car il s'agit d'une zone utilisée comme buffer lors de la sauvegarde. Ouf ! c'est fini.

Pour ne pas être trop lourd, nous allons implanter un tout petit programme machine:

LD A,7
JP &BB5A

Soit en codes machine les cinq octets suivants:

&3E,&07,&C3,&5A,&BB

Pour cela, on doit augmenter de cinq les zones &18-&19 ainsi que &40-&41, sans oublier d'augmenter de &0A ou 10 décimal ( deux fois 5 ) la zone de CSH ( &43-&44 ).

Il ne restera alors plus qu'à placer les cinq octets à la suite des trois zéros de fin du fichier Basic (à partir de l'adresse &A0) voir Doc 2.


Doc 2

Revenez maintenant sous Basic.

Rechargez le fichier Q4.BAS, Listez-le.

Apparemment rien n'a changé.

Nous avons vu dans le HEADER qua la longueur initiale du fichier était de &22 soit 34 (en décimal).
Sachant qu'un fichier Basic commence en &170 ou 368 nous en déduisons facilement que notre routine est installée en &192 ou 402décimaJ. Vérifiez par vous-même:

FOR I=402 TO 406: PRINT HEX$(PEEK(I),2):NEXT

Si vous avez encore des doutes, exécutez donc la fameuse routine assembleur par:

CALL 402

Voilà nous devons arrêter les frais pour  aujourd'hui. Il va de soi que l'appel à la routine peut être (doit être ! ) dans le source Basic ( une ligne cachée, par exemple ), Pour cela, insérez dès le début  un CALL bidon qu'il suffira de réajuster une fois les opérations terminées.
Avant de finir avec ce chapitre et comme bonus d'adieu, je vous pariais plus haut (dans le HEADER) du type de fichier. Sachez que tout comme un fichier Basic protégé (type 1), un fichier binaire protégé (type 3) ne pourra être loadé. Faites donc: le test pour vous en persuader.

DES QUESTIONS?

A partir de là, vous vous posez sans doute la question suivante : « Il est bien gentil le p'tit Poum, il nous file plein de trucs pour cacher des instructions ou rendre le programme illisible. Mais rien n'empêchera le premier venu de prendre Discology et de copier mon programme. Alors, j'ai fais tout ça pour du beurre ? »

Bien sûr que non, car il suffit ensuite de rendre le programme incopiable (lisez plus bas! et cacher tous les tests par une ou un mélange des méthodes données ici même.

C'EST FINI !

Si ces quelques lignes vous ont plu ; si vous commencez déjà à taper du pied dans l'espoir d'en savoir plus ; si vous faites sauter le standard de la rédaction ; si les traiteaux de mon bureau cèdent sous la pression de votre courrier ; si les gros chèques arrivent sur mon compte en suisse (n° 126584654294)... « IF ces Si sont TRUE THEN » je vous promets de reprendre mon courage en m'aventurant dans l'antre du grand Xor, histoire de vous narrer d'autres contes machiavéliques du genre.

Poum qui remercie Xor (il va de soi)

★ LICENCE: COMMERCIALE
★ ANNÉES: 1991
★ AUTEURS: XOR , Alain Massoumipour

CPCrulez[Content Management System] v8.75-desktop/c
Page créée en 056 millisecondes et consultée 1352 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.