[ - Intro - Explications - L'outil expliqué - Liens - Notes de fin - ]
 
[ - Tutoriaux : Bases ~ Jnz / Jz ~ Jmp ~ La fonction d'enregistrement ~ Crack GifMovieGear 3.0 - ]

La deuxième chose que nous allons voir est le saut inconditionnel afin de pouvoir sauter par dessus une protection quand cela est quasi obligatoire. 

Emplacement : dans le package fourni
Outils : W32Dasm 8.93, Hexworkshop 2.54 et JumpGen 0.4b trouvable dans le package.

Je vais aller un peu plus vite cette fois, car on a vu le principal avant.
 

Le Crack

Le désassemblage nous donne ceci :

//******************** Program Entry Point ********
:00401000 6A00                    push 00000000
:00401002 6800304000              push 00403000

* Possible StringData Ref from Data Obj ->"ENREGISTRE-MOI SINON JE ME FACHE "
                                        ->"!!!"
                                  |
:00401007 6812304000              push 00403012
:0040100C 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:0040100E E829000000              Call 0040103C
:00401013 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"Cour n"
                                  |
:00401015 6837304000              push 00403037

* Possible StringData Ref from Data Obj ->"Mon premier Crack : Le saut inconditionnel"
                                  |
:0040101A 6850304000              push 00403050
 

Cette fois pas de test eax, eax mais directement notre Nag-screen, suivi du programme.
Là, il s'avère qu'on ne peut pas détourner une condition vu qu'il n'y en a pas !
La solution envisageable que nous avons vu précédemment est le NOP.

:00401000 6A00                    push 00000000 
:00401002 6800304000              push 00403000
:00401007 6812304000              push 00403012
:0040100C 6A00                    push 00000000
:0040100E E829000000              Call 0040103C
devient 
:00401000 9090                    nop ( 2 x )
:00401002 9090909090              nop ( 5 x )
:00401007 9090909090              nop ( 5 x )
:0040100C 9090                    nop ( 2 x )
:0040100E 9090909090              nop ( 5 x )

Evidemment, ça marche mais c'est lourd et pas très pro !
On modifie pas moins 19 bytes ! Il faut donc réfléchir et voir en assembleur ce qui pourrait nous aider.
L'idéal serait de pouvoir sauter toute cette partie : de 00401000 ( début du Nag ) à 00401013 exclu ( début du programme ).

Que cela ne tienne, fesons un saut sans conditions : un jmp ( jump )
On a vu précédemment que pour un saut court, l'opcode était : EB+distance.

Pour avoir cette distance, on va utiliser Jumpgen qui va se charger de nous donner l'opcode complet.
Lançons cet outil et passons nos informations.

NB: ne prennez pas 68k à moins que votre processeur soit du style Motorola 68000 ce qui serait TRES étonnant ; )

Donc, on a EB11.

Fesons la modification sous Hexworkshop et relançons le programme.
Ca marche...
Si on désassemble notre programme cracké, cela donne la chose suivante :

//******************** Program Entry Point ********
:00401000 EB11                    jmp 00401013 <=== notre saut

* Possible StringData Ref from Data Obj ->"VILAIN NAG-SCREEN"
                                  |
:00401002 6800304000              push 00403000

* Possible StringData Ref from Data Obj ->"ENREGISTRE-MOI SINON JE ME FACHE "
                                        ->"!!!"
                                  |
:00401007 6812304000              push 00403012
:0040100C 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:0040100E E829000000              Call 0040103C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401000(U)
|
:00401013 6A00                    push 00000000 <=== notre saut et on atterit ici.

* Possible StringData Ref from Data Obj ->"Cour n"
                                  |
:00401015 6837304000              push 00403037

* Possible StringData Ref from Data Obj ->"Mon premier Crack : Le saut inconditionnel"
                                  |
:0040101A 6850304000              push 00403050

Toutes les instructions du Nag-screen ont été sautées. Bref, c'est ce que l'on voulait et en modifiant 2 bytes au lieu de 19 !
Petite chose : il vous est inutile d'utiliser NOP pour complèter l'opcode.
Je m'explique ; ici, on a :

00401000 6A00                    push 00000000
devient 
00401000 EB11                    jmp 00401013
donc 6A00 ---> EB11 parfait ( 2 bytes pour 2 bytes )

Mais si c'était push 00403012 ( 6812304000)  au lieu de push 00000000 ( 6A00 ) :
00401000 6812304000              push 00403012
On aurait 
00401000 EB11                    jmp 00401013
00401002 304000                  des instructions correspondantes à ces opcodes

Bref, on ne patche pas complètement l'opcode original puisqu'on laisse des déchets ( 304000 ).
On pourrait faire 
00401000 6812304000              push 00403012
devient
00401000 EB11                    jmp 00401013
00401002 909090                  nop ( 3 x )
Notre opcode original est complètement patché...
Mais c'est inutile !
A la lecture du programme, quand les bytes EB11 apparaissent, il n'y a pas de problèmes, cela correspond à notre saut. Peu importe qu'on est les opcodes suivants qui soient détruits, la lecture ne tombera jamais sur eux !
 

Plus d'informations

Calculer soit-même l'opcode d'un saut court.

Jumpgen le fait très bien et vous permet de choisir votre type de saut ( jmp, jnz, jz, ja, etc. )
On a vu que pour les sauts courts, on avait :

1 byte pour définir le type de saut + 1 byte pour donner la distance.
ex :
EB11 = jmp+distance
7511 = jnz+distance = jne+distance
7411 = jz+distance = je+distance
Donc pour définir notre type de saut, il faut se reporter sur le fichier help que je vous ai mis dans le package.
Reste à calculer la distance.
Si l'on reprend l'exemple d'en haut, on doit faire un saut jump ( EB ) de 401000 jusqu'en 401013.
Calculons la distance entre les 2 avec la calculatrice hexa / déci / bin d'hexworkshop.
401013 - 401000 = 13
Problème, on a vu que Jumpgen nous donnait EB11 et non pas EB13.
Il y a une différence de 2 bytes...
En fait c'est simple à comprendre.

00401000 EBXX                    jmp 00401013

Quand la lecture de l'instruction est faite et avant qu'elle soit exécutée, on est après EBXX donc en 401002 !
C'est donc à cet endroit que le saut se fait ( enfin pour être plus exacte que le registre EIP va être incrémenté de notre distance ).
Donc 401013 - 401002 = 11.

On retrouve bien EB11 de Jumpgen.
 

Lise Grim 2002 / WiA