GRAPHE AT 1.03e

By Christal

Principe général:

L'architecture d'un programme crypté/compressé va être la suivante:

1- Le Loader
2- Le code crypté ou compressé.

Le Loader, qui par la force des choses, est toujours "clean" (comprenez ni crypté, ni compressé) va s'occuper de la décompression/décryption.

Le code à décrypter pourrait se décomposer en trois types de codes:
- Les codes n'ayant aucun sens lorsque vous tombez dessus dans un Dead listing, ou ceux-ci sont interprétés au mieux, et ou les add byte ont la part belle.
- Les longues séries de add dword ptr
- Les longues séries de BYTE 10 DUP(0)

:004233B1 E9E760FEFF  jmp 0040949D
:004233B6 CC          int 03
:004233B7 CC          int 03
:004233B8 8B4DF0      mov ecx, dword ptr [ebp-10]
:004233BB E9B15BFEFF  jmp 00408F71
:004233C0 B870A44200  mov eax, 0042A470
:004233C5 E9D360FEFF  jmp 0040949D
:004233CA 0000        add byte ptr [eax], al

:0041D026 0100        add dword ptr [eax], eax
:0041D028 800000      add byte ptr [eax], 00
:0041D02B 0030        add byte ptr [eax], dh

:004064B2 00000000000000000000 BYTE 10 DUP(0)
:004064BC 00000000000000000000 BYTE 10 DUP(0)
:004064C6 00000000000000000000 BYTE 10 DUP(0)
:004064D0 00000000000000000000 BYTE 10 DUP(0)


Présence d'un compacteur ou d'un crypteur: les symptômes.

Au delà, et bien avant que vous ne puissiez accéder au dead Listing, les programmes packés/compressés se distinguent par les symptômes suivants:

- Au lancement de l'application, via le Symbol Loader de SoftIce, vous n'avez pas de break sur l'Entry point .

- Wdasm ne désassemble pas le fichier (accompagné souvent du message "the PE Files is not a Standard Window Format), ou ne désassemble que le Pe header (donc pas de codes). Vous obtiendrez quand même, dans ce cas, une information qui sera précieuse pour la suite: l'entry point du programme dans sa version cryptée/compressée

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
****************** Start of Code in Object CODE ****************
Program Entry Point = 008F4000 -> Entry point de l'exe compressé

Dans le meilleur des cas, Wdasm désassemble le fichier sans les ressources habituelles (Strings Datas, Fonctions importées et exportées, Dialog...).

- La taille de l'exécutable, sachant que les applications Windows manquent singulièrement de discrétion à ce niveau, est également un bon indicateur de la présence éventuelle d'un compresseur (une application inférieure à 100 ko, aujourd'hui, devient rare...).

- Les codes au niveau de l'Entry Point (bien éloigné de l'habituel 00401000!) ressemblent à ceci;

017F:008F4000  669C                PUSHF
017F:008F4002  60                  PUSHAD
017F:008F4003  E8CA000000          CALL    008F40D2
017F:008F4008  0300                ADD     EAX,[EAX]
017F:008F400A  0400                ADD     AL,00
017F:008F400C  0500060007          ADD     EAX,07000600
017F:008F4011  0008                ADD     [EAX],CL
017F:008F4013  0009                ADD     [ECX],CL
017F:008F4015  000A                ADD     [EDX],CL
017F:008F4017  000B                ADD     [EBX],CL

Bref! vous avez affaire à un programme compressé ou crypté.

Identification du compresseur ou du crypteur:

Suivant le crypteur/compresseur utilisé, celui ci va être plus ou moins discret et/ou repérable.
Dans les différentes solutions envisageables pour découvrir à qui vous aurez affaire, vous pouvez:

· utiliser un File Analyser (Type PE Sniffer)

· chercher dans les codes du programme soit un copyright (souvent vers la fin du fichier),

.......$Id: UPX
0.82 Copyright (
C) 1996-1999 Las
zlo Molnar & Mar
kus Oberhumer $
. ..............En
crypted by Stone
CF - PowerLame
PE-ExeEnCrypter
! :) 2nd&mi ...
... -=. PE-SHiELD v0
.2 -.- (C) Copyright
1998 by ANAKiN [DaV
inci] .=- ..........

Soit des noms de sections que vous identifierez comme étant liés à un packer/crypteur (en début de fichier, au niveau des informations du PE Header), en utilisant un Snooper pour récupérer toutes les chaînes alphanumériques du fichier, ou plus simplement un éditeur hexadécimal (avec correspondance ASCII, mais il me semble qu'ils le font tous...).

....PESHiELD........
.V..................
@...PESHiELD........
.....Z..............
@...ANAKIN98.0......

ou avec ProcDump,

UPX0  00038000 00001000 00000000 00000400 E0000080 
UPX1  00023000 00039000 00022600 00000400 E0000040 
.rsrc 00001000 0005C000 00000C00 00022A00 C0000040 

· Identifier la signature du packer/compresseur, c'est à dire le code qui permettra de reconnaître tel ou tel packer, à partir d'une suite de mnémoniques caractéristiques (ex 61 FF E0 = POPAD JMP EAX) et bien sûr situé dans une zone non compressée/packée (clean) .

Dans le cas de GrapheAt, on ne retouve aucune trace de CopyRight. Pour autant ce n'est pas obligatoirement une compression maison, mais le packer n'étant pas facilement identifiable, il faudra procéder à la réalisation d'un Dump manuel.

Utiliser Wdasm et SoftIce:

Modifier les caractéristiques des sections:

Pour pouvoir utiliser l'un et/ou l'autre au mieux, il va falloir faire une modification au niveau de la sections .CODE. Pour cela, vous pouvez utiliser un outil comme ProcDump.

Name                Virt Size           Virt Offset          Raw Size         Raw Offset    Characteristics
CODE        00062000    00001000    00033A00    00001C00   E0000060
BSS         00476000    00063000    00000000    00000000   C0000000
.idata      00002000    004D9000    00002000    00035600   C0000040
.tls        00001000    004DB000    00000000    00000000   C0000000
.rdata      00001000    004DC000    00000200    00037600   D0000040
.reloc      00007000    004DD000    00000000    00000000   C0000040
.rsrc       00010000    004E4000    000053E0    00037800   C0000040
.rsrcgr     0000D2DC    004F4000    00001800    00000400   E2000060

C'est par la section .rsrcgr que va attaquer le Soft. Or si les autres sections ont des noms " honorables " celle ci fait louche…
Et puis des caractéristiques de sections du type E0000060…

Vous aurez probablement remarqué que dans cet exemple, toutes les sections ont des caractéristiques différentes ( il faut que certaines sections soient Executable, Readable, Writable et Data! ainsi, le programme peut lire le code compressé, et le décompresser dans la même section sans provoquer d'erreur fatale dans Windows), ce qui, normalement, vous empêche souvent de désassembler l'exécutable, ou d'obtenir un break en passant par le Symbol Loader de SoftIce.
En modifiant la première section (.text), et en remplaçant E0000060 par E0000020 à l'aide de ProcDump, vous pourrez reprendre la main avec SoftIce, et obtenir un listing, sans les ressources (Strings Data...) dans Wdasm.

Voici quelques explications rapides et très succinctes sur les attributs des sections:
================
0x20...... : signifie eXecutable
0x40...... : signifie Readable
0x80...... : signifie Writeable

exemple 0x60.. -> eXecutable + Readable
0x60... -> R-X-.
0xC0... -> R-.-W
0xE0... -> R-X-W
=================
0x......20 : signifie contains Code
0x......40 : signifie Initialized data
0x......80 : signifie Unitialized data

0x......40 : la plupart des sections peuvent avoir cette valeur excepté les sections CODE et .BSS
=================

Et plus simplement:

   0x00000020 IMAGE_SCN_CNT_CODE 
   0x20000000 IMAGE_SCN_MEM_EXECUTE 
   0x40000000 IMAGE_SCN_MEM_READ 
OR 0x80000000 IMAGE_SCN_MEM_WRITE
----------------------------------- 
   0xE0000020 


Pour modifier les caractéristiques des sections:

Dans ProcDump, en cliquant sur le bouton PE EDITOR, vous allez obtenir des informations sur le Soft compressé :
L'image base qui semble toujours être 400000 et la valeur de l'Entry point.

Header Infos
Entry Point :        004F4000
Size Of Image :      005012DC
Image Base :         00400000

En cliquant sur le bouton " Sections ", vous obtiendrez le tableau vu ci dessus.
Un right-clic sur l'une d'entre elles va vous permettre d'accéder à un nouvel écran où vous pourrez modifier les sections.

Création d'un Dump:

Pour pouvoir disposer d'un listing avec les ressources, il va falloir créer un dump manuel de l'exécutable compacté.

La première étape va être de tracer l'exécutable à partir de l'Entry Point, et trouver le moment où la décompression est terminée.

017F:008F561D  6A05                PUSH    05
017F:008F561F  59                  POP     ECX
017F:008F5620  F3A4                REPZ MOVSB
017F:008F5622  61                  POPAD             > Classique!
017F:008F5623  669D                POPF
017F:008F5625  E95AC5B6FF          JMP     00461B84  > OEP

C'est le passage de relais vers le programme d'origine. Il est possible d'en être à peu prés certain, car on passe brutalement des adresses 008F5XXX à 00461XXX

017F:00461B84  55                  PUSH    EBP
017F:00461B85  8BEC                MOV     EBP,ESP
017F:00461B87  83C4F4              ADD     ESP,-0C
017F:00461B8A  53                  PUSH    EBX
017F:00461B8B  E86818FAFF          CALL    004033F8
017F:00461B90  E88F2EFAFF          CALL    00404A24

Et qu'ensuite le PUSH EBP est un classique des débuts de programmes, bien que ce ne soit pas une règle absolue.
Dans les cas ou, malgré la modification des caractéristiques des sections, vous n'arrivez pas à prendre la main, il y a d'autres solutions: si Wdasm vous a livré l'entry point de l'exécutable, vous pouvez utiliser un éditeur hexadécimal (type Hiew) pour vous caler sur la première instruction de l'exécutable,et

Prendre la main grâce à l'Interruption 3 :

L'idée étant d'obliger SoftIce à marquer un break, à l'aide de Hiew remplacez la valeur qui se trouve à l'Entry Point.(Souvent un opcode 60 qui correspond au mnémonique PUSHAD) par CC, le code pour INT 3.
Posez ensuite un BPINT 3 dans SoftIce, et lancez le programme

Remplacez immédiatement le code CC par sa valeur d'origine, (par exemple PUSHAD) sinon c'est le plantage assuré :

017F:008F4000  669C                PUSHF
017F:008F4002  60                  PUSHAD
017F:008F4003  E8CA000000          CALL    008F40D2
017F:008F4008  0300                ADD     EAX,[EAX]

Et passez à l'étape suivante.

Un autre solution:

BPX GetProcAddress
Une majorité d'applications font appel à cette API dés leur lancement.
Dans la majorité des cas, vous allez pouvoir vous retrouvez dans SoftIce grâce à ce breakpoint …

Trouver le moment où la décompression est terminée.

Un grand nombre d'encrypteurs/compresseurs commencent par sauvegarder le contenu des registres (Pushad) avant de commencer leur boulot, et les restituent à la fin de celui ci (Popad). Bien souvent, dans ce cas, vous aurez le passage de relais du Loader à l'application d'origine, dans les parages.

PEPack

61 POPAD            > restauration
FFEO JMP EAX        > passe la main
8D85CE050000 LEA EAX,[EBP+000005CE]

PE-ExeEnCrypter

5F POP EDI          > restauration
5D POP EBP          > restauration 
FFE0 JMP EAX        > passe la main 

Voici une variante du POPAD, ou les registres sont récupérés un à un:

STNE 1.13

015f:0040e090 pop ebx ------on récupère 
015f:0040e091 pop ecx ------tous les
015f:0040e092 pop edx ------registres
015f:0040e093 pop esi 
015f:0040e094 pop edi 
015f:0040e095 pop ebp 
015f:0040e096 jmp eax ----- et on saute vers le prog décrypté...

VG Crypt

61 POPAD                                      > restauration 
9D POPFD 
8B9A09274000 MOV EBX,[EDX+00402709] 
898A09274000 MOV [EDX+00402709],ECX 
FFE3         JMP EBX        variante du EAX!  > passe la main

Avec un peu d'habitude, on en sait assez: Le JMP EAX (ou plus rarement EBX) est très couramment utilisé pour brancher vers les codes du programme original (OEP).

Toujours dans les variantes, vous avez le call EAX, parfois déguisé, comme dans le cas de
Shrinker:

8945E0 mov  dword ptr [ebp-20], eax  (le fameux EAX!)
FF7510 push [ebp+10]
FF750C push [ebp+0C]
FF7508 push [ebp+08]
FF55E0 call [ebp-20]                 > passe la main à l'OEP 
8945E4 mov  dword ptr [ebp-1C], eax
EB07   jmp  0063E4EE

Là aussi, il y a des variantes: le push EAX (qui va pousser une valeur sur la pile) et le Ret (qui récupère cette adresse sur la pile) vont simuler un retour sur call appelant.

Aspack

LEA EAX,[EBP+00444C37]
50 push eax 
C3 ret 

Il y a aussi les cas ou plus simplement le programme se branche sur l'Entry Point du programme décompressé/décrypté par un tout bête JMP OEP (Original Entry Point)

UPX:

61                   popad
E98EF7CAFF           jmp     004CAD80 > jump sur l'OEP
00000000000000000000 BYTE 10 DUP(0)
00000000000000000D42 BYTE 10 DUP(0)

(Il n'est pas très difficile de mettre la main sur la signature d'UPX. Toutes les versions que j'ai pu en voir permettent de la trouver à la fin du listing désassemblé). Dans le cas de GrapheAT, vous trouverez un cas de figure identique.

Neolite

5D          pop ebp 
5B          pop ebx 
E9673DFFFF  jmp 00401000 > jump sur l'OEP

Il y a bien sur des cas particuliers...


Dumper le programme en mémoire:

Mais dans le cas de GrapheAT, le codage est simple (pas d'Overlapping), et ne présente aucun problème lors du traçage.

Pour obtenir une copie du programme décompressé en mémoire on peut utiliser au choix IceDump (pagein D 400000 longeur_du_code c:\dump.exe) ou ProcDump. Dans les deux cas, il faudra s'arréter en 008F5625.
Lancez le programme/cible via le Symbol Loader de Softice . De cette façon SoftIce pourra prendre la main.
Posez un BPM X (Memory BreakPoint on eXecution) sur le jmp
008F5625, et faites [F5] pour relancer le programme. Au break, passez en mode assemblage, et changez le jmp 008F5625 par un jmp eip. Ainsi, vous obligerez le programme à boucler sur lui-même.
Rouvrez ProcDump, et cliquez sur " Options " pour choisir " Rebuilt Import Table ", puis sélectionnez l'application dans la liste des taches actives de la fenêtre de ProcDump. Après quelques instants, vous pourrez sauver un joli dump du nouvel exécutable avec du beau code tout clean.

Rendre le fichier obtenu exécutable:

Le zoli exécutable obtenu ne va pas pour autant fonctionner. Il faut encore lui indiquer quel va être son nouvel Entry Point. C'est encore ProcDump qui va nous permettre de réaliser facilement cette modification.
Ouvrez ProcDump, et choisissez "PE EDITOR". Vous obtiendrez ceci:

Header Infos
Entry Point :        004F4000  > entry point à modifier
Size Of Image :      005012DC
Image Base :         00400000

Il va falloir modifier l'Original Entry Point pour que le programme puisse commencer en 00461B84, et lui soustraire la valeur de l'imagebase (00400000): 00461B84 (OEP) - 400000 (IB) = 61B84 (Entry Point à entrer dans le champ de ProcDump, ou en utilisant un éditeur hexadécimal).
Si tout c'est bien passé, votre exécutable est maintenant Runnable!

0000011C        00060E00       Taille de la section Code 
00000120        00019200       Taille des Initialized Data 
00000124        00000000       Taille des Uninitialized Data
00000128        004F4000       Entry Point (RVA)
0000012C        00001000       Base du Code

00000100 5045 0000 4C01 0800 195E 422A 0000 0000 PE..L....^B*....
00000110 0000 0000 E000 8E81 0B01 0219 000E 0600 ................
00000120 0092 0100 0000 0000 0040 4F00 0010 0000 .........@O.....

Une fois obtenu un Dump exécutable du programme, vous aurez une copie de ce qu'il pouvait être avant de passer dans le compresseur, avec un exéctable plus gros du fait de la présence du loader dans les codes, même si celui ci a été shunté. Rien de plus facile alors que de patcher l'exécutable obtenu.

Comme Cracker le programme:

Après avoir entré un sérial, avec un BPX HmemCpy, on arrive presque immédiatement ici :

017F:0045115A  83F810              CMP     EAX,10   > 10 caractères ?
017F:0045115D  741A                JZ      00451179 > Go Away

En regardant un peu plus bas dans les codes du programmes, on voit ceci :

017F:004511E3  6A00                        PUSH    00
017F:004511E5  668B0D90124500              MOV     CX,[00451290]
snips snips ------------------
017F:00451226  C70510917B0001000000MOV     DWORD   PTR [007B9110],00000001

Histoire de voir si ce que vous avez soupçonné est good, un jmp 004511E3 à la place du JZ en 0045115D, et n'importe quel sérial peut être accepté

Mieux, on a même le flag Utilisateur enregistré.
En posant un BPM dessus et en relançant le programme, on a aussitôt un break sur:

017F:0045EF8A C70510917B00FFFFFFFFMOV DWORD PTR [007B9110],FFFFFFFF

Où il n'y a qu'a remplacer le -1 par 1, et bye bye la protection...

L'adresse à patcher est donc 0045EF8A, en remplaçant FFFFFFFF par 00000001


Patcher l'exécutable:

Vous pouvez opter pour l'utilisation d'un Memory Patcher, si vous souhaitez laisser le fichier compressé en l'état:

R!SC's Process Patcher v1.2 :

R!SC est un Memory Patcher qui utilise un script pour créer un fichier exécutable de 8 ko, et qui permettra de lancer l'exécutable sans le modifier " physiquement " (et donc sans avoir à s'inquiéter d'éventuel Checksum), mais qui interviendra quand le programme sera décompressé en mémoire.
Voici un exemple de script qu'il serait possible d'écrire:

T=2000:                           ; temps accordé pour trouver les bytes à modifier
F=grapheat.exe:                   ; nom du programme à patcher
O=loader_grapheat.exe:            ; nom du fichier exe que vous allez créer
P=45EF90/FF,FF,FF,FF/00,00,00,01: ; modifications à apporter en 0045EF90
$                                 ; ordre de fin de script

Mais les puristes vous diront que ce n'est pas encore suffisant. Il va falloir réussir à patcher le programme compressé et/ou crypté. Pour y arriver, vous devez commencer par:

Ecrire le Patch

La trame des modifications à apporter, dans le cas de programmes compressés sont les suivantes:

1- A partir d'une zone clean, après décompresion, et en général avant ou sur le JMP ADDRESSE: Saut vers le patch
2- Au besoin, vérification que l'adresse (ou les adresses) visée est bien decompressée
3- Modification des octets (attention: une inscription en mémoires supérieure à 8 bits se fait " à l'envers ", d'ou par exemple un B001 (mov bl,01) s'écrirai 01B0).
4- Restauration des octets écrasés par le saut_vers_le_patch, et reprendre le cours des choses...

803D90EF4500FF       CMP     BYTE PTR [0045EF90],FF        > adresse visée decompréssée?
750A                 JNZ     00XXXXXX                      > non-> continue
C70590EF450001000000 MOV     DWORD PTR [0045EF90],00000001 > oui -> modifie la cible
E980FEFFFF           JMP     00XXXXXX                      > retour à la normale

Une fois que vous connaissez la taille du patch, il ne reste plus qu'à:

Trouver de la place

Pour pouvoir y glisser les quelques lignes de votre patch.
Bien souvent, par facilité, je m'installe sur un petit bout de l'icône, ou à la place des informations de versions ou de copyright. Dans certain cas, même ceux ci ont été codés, et un outil comme les Borland Ressources WorkShop ne pourra pas vous aider à trouver la chaîne correspondant à l'icône convoitée. La seconde solution va consister à trouver un espace disponible.

Partant du principe qu'un compileur complète toujours la fin d'une section par des octets nuls (00 00), vous allez descendre dans le listing de SoftIce avec l'ascenseur de la fenêtre des codes, ou regarder si vous avez de la place à la fin de la dernière section de l'exécutable avec un Hex-éditeur, à la recherche de ce type de codes:

 0000         ADD       [EAX],AL  > octets nuls
 0000         ADD       [EAX],AL
 0000         ADD       [EAX],AL
 0000         ADD       [EAX],AL
 00FF         ADD       BH,BH
 FFFF         INVALID
 FFFF         INVALID             > fin de la section

Il faudra, avant tout, vous assurez qu'à aucun moment le compresseur/crypteur ne va venir y écrire quoi que ce soit, ou l'utiliser pour Dieu sait quoi, en posant quelques BPM sur les adresses repérées.

Mais les "méthodes" abordées ci dessus, même si elles se révèlent souvent suffisantes, sont assez empiriques, sinon hasardeuses…
Pour faire "plus sérieux", voici quelques autres solutions:

· pour rajouter le code à la fin du code du programme compressé, vous devrez retourner dans le PE Header:
Pour rappel, tout programme est divisé en sections, et chaque section possède une entrée dans le PE Header, ca veut dire que le loader possède une section dans le PE Header. ProcDump va nous permettre de connaître les détails de cette section ( celle contenant l'entry point):
Par exemple : (
.rsrcgr étant la section qui comprend l'EntryPoint et donc le Loader )

Name                   Virt Size            Virt Offset           Raw Size          Raw Offset    Characteristics

.rsrcgr     0000D2DC    004F4000    00001800    00000400   E2000060

La Virtual size de la section est 0000D2DC, ce qui veut dire que la mémoire qui sera allouée pour cette section sera de 0000D2DC bytes. Le Virtual Offset de la section, et du code appartenant au loader, est de 004F4000, additionné à l'Image base qui vaut 00400000, ca nous donne une adresse virtuelle de 004F4000 + 00400000 = 008F4000.
La taille sur disque (Raw Size) est de 00001800, ce qui veut dire que le code n'utilise que 00001800 bytes dans le fichier GrapheAT.exe. Autrement dit le code s'étale de l'adresse 008F4000 jusqu'à 008F4000 + 00001800 = 008F5C00.
Il est probable que vous pourrez disposer de place avant l'adresse 008F5C00, si le loader ne monopolise pas l'ensemble de l'espace qui lui est réservé pour la décompression du programme.

Rem: Vu que la taille doit être un multiple, cela veut dire que le compilateur rajoute des 00 pour que la section ait la bonne taille, c'est le padding.
Généralement il y a beaucoup de 00 que vous pouvez modifier. Mais il faut faire attention à une chose quand vous faites cela : Il faut bien vérifier que l'adresse où vous allez écrire le code de votre patcher fait toujours partie de la section que vous voulez modifier.
Rem: Il vaut mieux écrire le patch à la place de 00 que sur du code, même si celui-ci semble inutile au premier coup d'śil.

A l'aide de SoftIce, vous allez pouvoir contrôler qu'il y a bien une série de 00 00 (place "disponible") à la fin de la section .rsrcgr, quand le loader aura fini son travail, c'est à dire quand vous serez à l'adresse 008F5625. Un BPR sur la longeur des octets que vous voulez réserver pour votre patch va vous assurer que la zone convoitée est bien disponible, et vous pourrez vous installer en 00856B3 par exemple.

Dans le projet sur les PE Packed, il est parfois impossible d'insérer un patch. Il faut alors rajouter du code ou, en d'autre terme, augmenter la grandeur d'une section, voir rajouter une section. Comme ce n'est pas le cas içi, nous en parlerons un prochaine fois.

Voici le patch en lui même:

:008F56B3  803D90EF4500FF      CMP     BYTE PTR [0045EF90],FF  > adresse visée decompréssée?
:008F56BA  750A                JNZ     008F56C6                > non-> continue
:008F56BC  C70590EF450001000000MOV     DWORD PTR [0045EF90],01 > oui -> modifie
:008F56C6  8B86E0B50000        MOV     EAX,[ESI+0000B5E0]      > retauration
:008F56CC  E980FEFFFF          JMP     008F5551                > retour à la normale


Ré-adressage vers le patch:

Le choix de l'adresse à patcher en premier pour ré-adresser vers le patch est lié à la fin de la décompression de la zone ciblée. Un BPM sur l'adresse 0045EF90 va permettre de trouver l'endroit du code dans le loader qui va s'occuper de decompresser cette partie du programme. Il n'y a plus qu'à trouver ensuite une place pour y glisser un JUMP vers_le_patch. Suivant les cas, il vous faudra respecter la place occupée par les codes d'origines situés dans la zone clean du programme et trouvable par un hex éditeur, comme c'est le cas içi:

Codes d'origines:
017F:008F5543  E834ECFFFF    CALL    008F417C           > decompression de l'adresse visée
017F:008F5548  017D0C        ADD     [EBP+0C],EDI 
017F:008F554B  8B86E0B50000  MOV     EAX,[ESI+0000B5E0] > place à prendre?!
017F:008F5551  017DFC        ADD     [EBP-04],EDI

Ré-adressage:
017F:008F5543  E834ECFFFF          CALL    008F417C
017F:008F5548  017D0C              ADD     [EBP+0C],EDI
017F:008F554B  E963010000          JMP     008F56B3     > jump vers le patch
017F:008F5550  90                  NOP
017F:008F5551  017DFC              ADD     [EBP-04],EDI > retour içi

Dans ce cas précis, il faudra que le patch réécrive les MOV EAX,[ESI+0000B5E0]. Après que les modifications voulues aient été faites, vous redirigerez vers l'adresse 008F5551 pour que l'application continue, comme si de rien n'était.

Bonne Journée

Christal