Reverse de W32Dasm v8.9 par TeeJi

Se définir un but

    Cela fait un petit temps que j'y pense, mais j'ai jamais eu le temps, ou plutôt jamais pris le temps pour faire ce petit Reverse. Le but de celui-ci est de pouvoir Désassembler un fichier directement par la ligne de commande ( sans passer par le menu "Open a File To Disassemble..". ). Il suffirait de faire "W32dsm89 C:\Command.Com " par exemple pour désassembler C:\Command.com, ou encore en mettant un raccourci de W32Dsm89.EXE dans le repertoire SendTo de Windows, clicker avec le bouton droit de la souris sur le fichier à désassembler et choisir Envoyer-Vers/W32Dsm89 dans le menu contextuel.

Se procurer qqes renseignements

    Avant de commencer, il faut savoir avec quoi on part. Nous devons avant tout savoir les API's qui nous intéressent :

GetOpenFileNameA ;Qui affiche la Common DialogBox pour choisir le fichier à désassembler
GetCommandLineA  ;Qui renvoit l'adresse de la ligne de commande

    Nous devons aussi savoir l'adresse de la WinProc s'occupant de WDasm. Pour cela, on recherche les appels à DispatchMessageA dans W32Dasm89.EXE :

* Reference To: USER32.DispatchMessageA, Ord:0000h
                                  |
:004919E0 E8EDD50100              Call 004AEFD2

* Reference To: USER32.DispatchMessageA, Ord:0000h
                                  |
:004944C4 E809AB0100              Call 004AEFD2

* Reference To: USER32.DispatchMessageA, Ord:0000h
                                  |
:004A5611 E8BC990000              Call 004AEFD2

    On trouve 3 références mais en mettant un bpx sur ces adresses on s'aperçois qu'il y en a qu'une qui est correcte :

:004944C3 53                      push ebx

* Reference To: USER32.DispatchMessageA, Ord:0000h
                                  |
:004944C4 E809AB0100              Call 004AEFD2

    On trouvera donc facilement la WindowProc en faisant BPX 004944C4 IF @(EBX+04)==0111, ensuite F5 et on click sur n'importe quelle fonction du menu. Normallement Softice break, le IF @(EBX+04)==0111 vérifie en fait si on est en présence d'un WMsg == WM_COMMAND. Il suffit maintenant de faire BPR 401000 4944C4 R suivit de F5. Ainsi, si la WindowProc se trouve entre 00401000 et 004944C4 elle va être exécutée et elle fera Breaker Softice. On trouve donc que la WindowProc se trouve en 004910E2 :

:004910E2 55                      push ebp ;<-- On Break Ici !
:004910E3 8BEC                    mov ebp, esp
:004910E5 FF7514                  push [ebp+14]
:004910E8 FF7510                  push [ebp+10]
:004910EB FF750C                  push [ebp+0C]
:004910EE 50                      push eax
:004910EF E807000000              call 004910FB
:004910F4 83C410                  add esp, 00000010
:004910F7 5D                      pop ebp
:004910F8 C21000                  ret 0010

    On doit aussi savoir l'ID du MenuItem "Open File To Disassemble..". Pour cela, il suffit de mettre un BPX 004910E2 IF @(esp+08)==0111, ensuite F5 et clicker sur le MenuItem en question. Si tout va bien, on break sous Sice. Un DD ESP donne l'etat de la pile qui contient le WMsg :

017F:0078C30C BFF7363B  00000944  00000111  00005F0C      ;6..D........_..
017F:0078C31C 00000000  835A1997  0000017F  0078C33C      ......Z....<.x.

    Donc LParam = 00000000 WParam = 00005F0C et WMsg = 00000111. WParam contient l'ID de l'Item = 5F0C.

    Maintenant recherchons l'appel à GetOpenFileNameA :

:0043E23A 8B9333E16300            mov edx, dword ptr [ebx+0063E133]
:0043E240 C60200                  mov byte ptr [edx], 00
:0043E243 C78394EB01004C000000    mov dword ptr [ebx+0001EB94], 0000004C
:0043E24D 8B8B8C116F00            mov ecx, dword ptr [ebx+006F118C]
:0043E253 8B410C                  mov eax, dword ptr [ecx+0C]
:0043E256 898398EB0100            mov dword ptr [ebx+0001EB98], eax
:0043E25C 8B9337E16300            mov edx, dword ptr [ebx+0063E137]
:0043E262 8993A0EB0100            mov dword ptr [ebx+0001EBA0], edx
:0043E268 33C9                    xor ecx, ecx
:0043E26A 898BA4EB0100            mov dword ptr [ebx+0001EBA4], ecx
:0043E270 8B8319E16300            mov eax, dword ptr [ebx+0063E119]
:0043E276 8983ACEB0100            mov dword ptr [ebx+0001EBAC], eax
:0043E27C 8B9333E16300            mov edx, dword ptr [ebx+0063E133]
:0043E282 8993B0EB0100            mov dword ptr [ebx+0001EBB0], edx
:0043E288 C783B4EB010050000000    mov dword ptr [ebx+0001EBB4], 00000050
:0043E292 8B8B33E16300            mov ecx, dword ptr [ebx+0063E133]
:0043E298 898BB8EB0100            mov dword ptr [ebx+0001EBB8], ecx
:0043E29E C783BCEB010050000000    mov dword ptr [ebx+0001EBBC], 00000050
:0043E2A8 8D8514FFFFFF            lea eax, dword ptr [ebp+FFFFFF14]
:0043E2AE 8983C0EB0100            mov dword ptr [ebx+0001EBC0], eax
:0043E2B4 89BBC4EB0100            mov dword ptr [ebx+0001EBC4], edi
:0043E2BA 8B932BE16300            mov edx, dword ptr [ebx+0063E12B]
:0043E2C0 8993C8EB0100            mov dword ptr [ebx+0001EBC8], edx
:0043E2C6 8D8B94EB0100            lea ecx, dword ptr [ebx+0001EB94]
:0043E2CC 51                      push ecx

* Reference To: COMDLG32.GetOpenFileNameA, Ord:0000h
                                  |
:0043E2CD E8B20F0700              Call 004AF284

* Reference To: COMDLG32.GetOpenFileNameA, Ord:0000h
                                  |
:004AF284 FF25104B4D00            Jmp dword ptr [004D4B10]


    Je désassemble le fichier Psapi.dll. Ensuite je met un Breakpoint sur le call et je désassemble W32Dsm89.EXE.
    Voici l'état de la Structure OPENFILENAME avant et après le call :

 
Avant le Call :
017F:007AB120 0000004C  00000948  00000000  00E92B3C      L...H.......<+..
017F:007AB130 00000000  00000000  0000000F  00E92710      .............'..
017F:007AB140 00000050  00E92710  00000050  0078BF58      P....'..P...X.x.
017F:007AB150 004BCBAF  00001006  002C0026  00000000      ..K.....&.,.....
017F:007AB160 00000000  00000000  00000000                ............

    DWORD         lStructSize; 0000004C
    HWND          hwndOwner; 00000948
    HINSTANCE     hInstance; 00000000
    LPCTSTR       lpstrFilter; 00E92B3C
    LPTSTR        lpstrCustomFilter; 00000000
    DWORD         nMaxCustFilter; 00000000
    DWORD         nFilterIndex; 0000000F
    LPTSTR        lpstrFile; 00E927100; 0,"sapi.dll",0
    DWORD         nMaxFile; 00000050
    LPTSTR        lpstrFileTitle; 00E92710; 0,"sapi.dll",0
    DWORD         nMaxFileTitle; 00000050
    LPCTSTR       lpstrInitialDir; 0078BF58
    LPCTSTR       lpstrTitle; 004BCBAF; "C:\WINDOWS\Bureau\W32Dasm v8.93 Fixed",0
    DWORD         Flags; 00001006

    WORD          nFileOffset; 0026
    WORD          nFileExtension; 002C
    LPCTSTR       lpstrDefExt; 00000000
    DWORD         lCustData; 00000000
    LPOFNHOOKPROC lpfnHook; 00000000
    LPCTSTR       lpTemplateName; 00000000

 
Après le Call :
017F:007AB120 0000004C  00000948  00000000  00E92B3C      L...H.......<+..
017F:007AB130 00000000  00000000  0000000F  00E92710      .............'..
017F:007AB140 00000050  00E92710  00000050  0078BF58      P....'..P...X.x.
017F:007AB150 004BCBAF  00001806  002F0026  00000000      ..K.....&./.....
017F:007AB160 00000000  00000000  00000000                ............

    DWORD         lStructSize; 0000004C
    HWND          hwndOwner; 00000948
    HINSTANCE     hInstance; 00000000
    LPCTSTR       lpstrFilter; 00E92B3C
    LPTSTR        lpstrCustomFilter; 00000000
    DWORD         nMaxCustFilter; 00000000
    DWORD         nFilterIndex; 0000000F
    LPTSTR        lpstrFile; 00E92710; "W32dsm89.exe",0
    DWORD         nMaxFile; 00000050
    LPTSTR        lpstrFileTitle; 00E92710; "W32dsm89.exe",0
    DWORD         nMaxFileTitle; 00000050
    LPCTSTR       lpstrInitialDir; 0078BF58; "C:\WINDOWS\Bureau\W32Dasm v8.93 Fixed",0
    LPCTSTR       lpstrTitle; 004BCBAF
    DWORD         Flags; 00001806

    WORD          nFileOffset; 0026
    WORD          nFileExtension; 002F
    LPCTSTR       lpstrDefExt; 00000000
    DWORD         lCustData; 00000000
    LPOFNHOOKPROC lpfnHook; 00000000
    LPCTSTR       lpTemplateName; 00000000

Idée intuitive de la situation

    Maintenant il faut se demander ce que nous allons faire, comment nous allons procéder. Voici mon idée :

    On attend le WMsg WM_SHOWWINDOW ( = 0x018 ). Lorsque celui-ci est envoyé à la WindowProc, on vérifie si il y a un paramètre passé par la CommandLine grâce à GetCommandLineA. Si c'est le cas, on Hook la fonction API GetOpenFileNameA. La HookProc mettra les paramètres relatifs au nom de fichier passé par la ligne de commande et enlèvera ensuite le hook sur GetOpenFileNameA. On envoit ensuite le Wmsg WM_COMMAND avec LParam = 00 et WParam = 00005F0C. On émule ainsi un click sur "Open File To Disassemble..". La procédure va donc ce déroulée normallement et arriver à GetOpenFileNameA, c'est notre HookProc qui va prendre le relais, modifier la structure OPENFILENAME, et redonner la main au programme après avoir enlevé le Hook. Le fichier va se désassembler et tout sera comme avant.

Mise en pratique

    J'ai mis un BPX 004910E2 IF @(ESP+08)==018 et j'ai remarqué qu'il y avait 4 Break avant l'affichage de WDasm.
    J'utiliserai donc un compteur et nous ferons nos modifications à la 4ème passe.

:004910E2 55                      push ebp ;<-- On Break Ici !
:004910E3 8BEC                    mov ebp, esp
:004910E5 FF7514                  push [ebp+14]
:004910E8 FF7510                  push [ebp+10]
:004910EB FF750C                  push [ebp+0C]
:004910EE 50                      push eax
:004910EF E807000000              call 004910FB
:004910F4 83C410                  add esp, 00000010
:004910F7 5D                      pop ebp
:004910F8 C21000                  ret 0010

    On va modifier le call 004910FB par call Addr_Notre_proc. Il faut trouver un peu d'espace libre et non utilisé (vérifier avec un BPR !) :

:004AF2B4 00000000000000000000    BYTE 10 DUP(0)
...
:004AF3F4 00000000000000000000    BYTE 10 DUP(0)

    Voici Notre_proc :

.004AF2B4: 837C240818                   cmp       d,[esp][00008],018 ;WMsg = WM_SHOWWINDOW ?
.004AF2B9: 0F853C1EFEFF                 jne      .0004910FB          ;Sinon on redonne la main
.004AF2BF: FE05F4F34A00                 inc       b,[0004AF3F4]      ;on incrémente le cmpt
.004AF2C5: 803DF4F34A0004               cmp       b,[0004AF3F4],004  ;4ème passe ?
.004AF2CC: 0F85291EFEFF                 jne      .0004910FB          ;Sinon on redonne la main
.004AF2D2: 803DF5F34A0000               cmp       b,[0004AF3F5],000  ;Flag pour savoir si on a déjà fait les modifs
.004AF2D9: 0F851C1EFEFF                 jne      .0004910FB          ;Sinon on redonne la main

    Rem : Il faut modifier les caracteristiques de la section pour autoriser l'acces en ecriture !!

    On doit faire appel à GetCommandLineA qui n'est pas dans l'IAT. Il faut donc récupérer l'adresse avec GetProcAddress ainsi que l'Handle de Kernel32 par GetModuleHandleA.

* Reference To: KERNEL32.GetModuleHandleA, Ord:0000h
                                  |
:004AEC0C FF25B4464D00            Jmp dword ptr [004D46B4]
 

* Reference To: KERNEL32.GetProcAddress, Ord:0000h
                                  |
:004AEAD4 FF25E4454D00            Jmp dword ptr [004D45E4]

    On écris les Strings que nous allons utiliser :

.004AF3D0:  4B 65 72 6E-65 6C 33 32-00 47 65 74-43 6F 6D 6D  Kernel32 GetComm
.004AF3E0:  61 6E 64 4C-69 6E 65 41-00 00 00 00-00 00 00 00  andLineA

On peut à présent récupérer l'adresse de GetCommandLineA :

.004AF2E4: 50                           push      eax              ;Sauve le registre
.004AF2E5: 68D0F24A00                   push      0004AF2D0        ;push addr "Kernel32"
.004AF2EA: FF15B4464D00                 call      GetModuleHandleA
.004AF2F0: 68D9F34A00                   push      0004AF3D9        ;push addr "GetCommandLineA"
.004AF2F5: 50                           push      eax              ;Push Kernel32 Handle
.004AF2F6: FF15E4454D00                 call      GetProcAddress
.004AF2FC: FFD0                         call      eax              ;Call GetCommandLineA

    Maintenant, il faut isoler le paramètre. Si le paramètre est NULL, il faut redonner la main, sinon on peut hooker GetOpenFileNameA. Regardons le format de la CommandLine :

"D:\Crack\W32dsm89\Reversed.EXE" D:\CRACK\W32DSM89\PSAPI.DLL ;NULL Terminated String !

Bon, il suffit de rechercher le 1er espace ( = 0x20 ). Si le 1er caractère après est 0x00 c'est qu'il n'y a pas de paramètre.

.004AF2FE: 40                           inc       eax                ;On se positionne après le premier '"'
.004AF2FF: 803822                       cmp       b,[eax],020        ;Est-on sur un espace
.004AF302: 75FA                         jne      .0004AF2FE          ;Sinon on boucle
.004AF304: 80780100                     cmp       b,[eax+01],000     ;Si oui, Y a-t-il un paramètre ?
.004AF308: 7506                         jne      .0004AF310          ;Si oui, on continue
.004AF30A: 58                           pop       eax                ;Sinon On restaure EAX
.004AF30B: E9EB1DFEFF                   jmp      .0004910FB          ;On redonne la main

    Je sauve l'adresse et Hook la fonction GetOpenFileNameA avant d'envoyer le WMsg et redonner la main.

.004AF3F8:  00 00 00 00 ;Addr_Param
.004AF3FC:  00 00 00 00 ;Addr_GetOpenFileNameA Original

.004AF310: 83C002                       add       eax,001                 ;Le Param est en [eax+01]
.004AF313: A3F8F34A00                   mov       [0004AF3F8],eax         ;On sauve l'adresse
.004AF318: A1104B4D00                   mov       eax,[0004D4B10]         ;Eax = addr de GetOpenFileNameA
.004AF31D: C705104B4D0027F34A00         mov       d,[0004D4B10],0004AF327 ;Et on remplace par l'addr de l'HookProc

    Rem : 004AF327 n'est pas l'addr de la hook_proc, il va donc falloire la changer quand nous connaîtrons la bonne addr.

    Il faut maintenant envoyer le WMsg WM_COMMAND ( 0x0111 ) avec LParam = 0 et WParam = 00005F0C.
    On utilise pour cela SendMessageA :

* Reference To: USER32.SendMessageA, Ord:0000h
                                  |
:004AF12E FF25284A4D00            Jmp dword ptr [004D4A28]

    Avec comme paramètre :

    HWND hWnd, // handle of destination window
    UINT Msg, // message to send
    WPARAM wParam, // first message parameter
    LPARAM lParam  // second message parameter

    L'handle de la fenêtre de destination se trouve en [ESP+28]. On a donc tout ce qu'il faut :

.004AF328: 6A00                         push      000            ;LParam
.004AF32A: 680C5F0000                   push      000005F0C      ;WParam
.004AF32F: 6811010000                   push      000000111      ;WMsg
.004AF334: FF742428                     push      d,[esp+028]    ;Hwnd
.004AF338: FF15284A4D00                 call      SendMessageA
.004AF33E: E9B81DFEFF                   jmp      .0004910FB      ;Et on redonne la main
.004AF343: 0000                         add       [eax],al

    Donc notre Hook_proc va commencer en :004AF343. On peut modifier l'instruction en :004AF31D :

.004AF31D: C705104B4D0043F34A00         mov       d,[0004D4B10],0004AF343 ;Et on remplace par l'addr de l'HookProc

    Maintenant attaquons-nous à la Hook_proc. Il faut qu'elle modifie 5 éléments de la structure OPENFILENAME qui se trouve en [[ESP+04]] ou en ECX car, rappelez-vous :

:0043E2CC 51                      push ecx ; Addr de la structure

* Reference To: COMDLG32.GetOpenFileNameA, Ord:0000h
                                  |
:0043E2CD E8B20F0700              Call 004AF284

    Les éléments à modifier sont :

    [Struc+1C] LPTSTR        lpstrFile; 00E92710; "W32dsm89.exe",0
    [Struc+24] LPTSTR        lpstrFileTitle; 00E92710; "W32dsm89.exe",0
    [Struc+2C] LPCTSTR       lpstrInitialDir; 0078BF58; "C:\WINDOWS\Bureau\W32Dasm v8.93 Fixed",0
    [Struc+38] WORD          nFileOffset; 0026
    [Struc+3A] WORD          nFileExtension; 002F

    Voici la Hook_proc que je vous ai concocté :

.004AF343: A1F8F34A00                   mov       eax,[0004AF3F8] ;Récupère l'Addr du Param
.004AF348: 803800                       cmp       b,[eax],000     ;Recherche la fin du Param
.004AF34B: 7403                         je       .0004AF350       ;Si c'est la fin on continue
.004AF34D: 40                           inc       eax
.004AF34E: EBF8                         jmps     .0004AF348       ;Sinon on boucle
.004AF350: 48                           dec       eax             ;On se positionne à la fin
.004AF351: 80385C                       cmp       b,[eax],05C     ;On recherche le '\'
.004AF354: 75FA                         jne      .0004AF350       ;Si c'est pas, on boucle
.004AF356: 40                           inc       eax             ;Sinon on se positionne juste après
.004AF357: 2B05F8F34A00                 sub       eax,[0004AF3F8] ;Déplacement /r au début du param
.004AF35D: 66894138                     mov       [ecx+038],ax    ;nFileOffset = eax
.004AF361: 0305F8F34A00                 add       eax,[0004AF3F8] ;Addresse du nom du fichier
.004AF367: 57                           push      edi             ;Sauvegarde les registres
.004AF368: 56                           push      esi
.004AF369: 8B791C                       mov       edi,[ecx+01C]   ;edi = lpstrFile
.004AF36C: 8BF0                         mov       esi,eax         ;esi = addr du nom du fichier
.004AF36E: A4                           movsb                     ;On copie le nom dans lpstrFile
.004AF36F: 803E00                       cmp       b,[esi],000
.004AF372: 75FA                         jne      .0004AF36E
.004AF374: A4                           movsb
.004AF375: 4E                           dec       esi             ;On recherche la position de l'extension
.004AF376: 803E2E                       cmp       b,[esi],02E     ;On recherche donc le '.'
.004AF379: 75FA                         jne      .0004AF375
.004AF37B: 2B35F8F34A00                 sub       esi,[0004AF3F8]
.004AF381: 6689713A                     mov       [ecx+03A],si    ;On sauve la position
.004AF385: 33C0                         xor       eax,eax
.004AF387: 668B4138                     mov       ax,[ecx+038]    ;nFileOffset = longueur du path
.004AF38B: 51                           push      ecx
.004AF38C: 8B492C                       mov       ecx,[ecx+02C]   ;lpstrInitialDir
.004AF38F: 87CF                         xchg      ecx,edi         ;edi = lpstrInitialDir
.004AF391: 8B35F8F34A00                 mov       esi,[0004AF3F8] ;esi = addr du param
.004AF397: F2A4                         repne     movsb           ;met le path dans lpstrInitialDir
.004AF39B: C647FF00                     mov       b,[edi-01],000  ;Remplace le '\' de fin par NULL
.004AF39F: 59                           pop       ecx             ;Restaure les registres
.004AF3A0: 5E                           pop       esi
.004AF3A1: 5F                           pop       edi
.004AF3A2: A1FCF34A00                   mov       eax,[0004AF3FC]
.004AF3A7: A3104B4D00                   mov       [0004D4B10],eax ;Enlève le Hook sur GetOpenFileNameA
.004AF3AC: B801000000                   mov       eax,000000001   ;Met 1 dans EAX pour dire qu'un fichier est choisi
.004AF3B1: C3                           retn                      ;Merci :)

    Maintenant il faut régler les problèmes :) Le debuggage... Tout d'abord,

.004AF318: A1104B4D00                   mov       eax,[0004D4B10]         ;Eax = addr de GetOpenFileNameA
.004AF31D: C705104B4D0027F34A00         mov       d,[0004D4B10],0004AF327 ;Et on remplace par l'addr de l'HookProc

    J'ai oublié de sauver l'addresse de GetOpenFileNameA. Il suffit de mettre un call vers :004AF3B2 et de régler cela.

.004AF318: E895000000                   call     .0004AF3B2
...
.004AF3B2: A1104B4D00                   mov       eax,[0004D4B10]
.004AF3B7: A3FCF34A00                   mov       [0004AF3FC],eax
.004AF3BC: C3                           retn

    Ensuite, il dit que "Could Not Get File Handle". C'est surement parceque le répertoire courant n'est pas le répertoire du fichier que nous voulons désassembler. Pour corriger cela, il va falloir appeler SetCurrentDirectoryA avec lpstrInitialDir comme paramètre. On va mettre un jmp en :004AF39F :

* Reference To: KERNEL32.SetCurrentDirectoryA, Ord:0000h
                                  |
:004AEC36 FF25D0464D00            Jmp dword ptr [004D46D0]

.004AF39F: EB1C                         jmps     .0004AF3BD
...
.004AF3BD: 59                           pop       ecx
.004AF3BE: 5E                           pop       esi
.004AF3BF: FF712C                       push      d,[ecx+02C]
.004AF3C2: FF15D0464D00                 call      SetCurrentDirectoryA
.004AF3C8: EBD7                         jmps     .0004AF3A1

    Voilà ce qui corrige ce problème. Un autre problème est maintenant visible. Si on désassemble un fichier de format reconnu par WDasm, il y a des erreurs d'exception et si, par contre, il ne connait pas le format, il désassemble le fichier mais l'affichage déconne. Pour corriger cela, je crois qu'il faut modifier le moment où on envoit le Message WM_COMMAND qui émule l'appuis sur le bouton "Open File To Disassemble..". Une idée, qui normallement réglera les 2 problèmes, serait d'utiliser un autre WMsg, par Exemple WM_PAINT ( = 0x0F ) pour détecter la fin de l'affichage de WDasm. Comme pour WM_SHOWWINDOW, WM_PAINT est envoyé 4 fois avant que WDasm soit totallement affiché. Il suffit donc de remplacer ainsi :

.004AF2B4: 837C240818                   cmp       d,[esp][00008],0F  ;WMsg = WM_PAINT ?
.004AF2B9: 0F853C1EFEFF                 jne      .0004910FB          ;Sinon on redonne la main
.004AF2BF: FE05F4F34A00                 inc       b,[0004AF3F4]      ;on incrémente le cmpt
.004AF2C5: 803DF4F34A0004               cmp       b,[0004AF3F4],004  ;4ème passe ?
.004AF2CC: 0F85291EFEFF                 jne      .0004910FB          ;Sinon on redonne la main
.004AF2D2: 803DF5F34A0000               cmp       b,[0004AF3F5],000  ;Flag pour savoir si on a déjà fait les modifs
.004AF2D9: 0F851C1EFEFF                 jne      .0004910FB          ;Sinon on redonne la main

    Remarquez aussi que j'avais mis un flag pour vérifier qu'on avait déjà fait les modifs ( en effet, si WM_PAINT est envoyé FF fois, après le cmpt va boucler 00, 01, 02, 03 et 04 ce qui desassemblera à nouveau le fichier ). Il suffit donc de modifier ce flag après l'exécution de notre Hook_proc, par exemple :

    Nous avions ceci :

.004AF3C4: FF15D0464D00                 call      SetCurrentDirectoryA
.004AF3CA: EBD5                         jmps     .0004AF3A1

    On modifie ainsi :

.004AF3CA: EB1F                         jmps     .0004AF3EB
...
.004AF3EB: FE05F5F34A00                 inc       b,[0004AF3F5]
.004AF3F1: EBAE                         jmps     .0004AF3A1

    En vérifiant bien de laisser le cmpt ( 004AF3F4 ) et le flag ( 004AF3F5 ) à 00 avant l'exécution.

.004AF3F3: 0000
.004AF3F5: 0000

    Maintenant, tout est fonctionnel ! Evidemment, ce cours à été fait en même temps que le Reverse et c'est le pourquoi des erreurs et de la non-optimisation du code ! De cette manière, vous pouvez voir qu'il n'est pas toujours nécessaire de tout recommencer. Par ce Reverse, je vous ai montré aussi qu'il ne faut pas connaître les adresses des fonctions que nous voulons utiliser dans le Reverse et qu'en nous aidant d'artifices comme l'API Hooking, tout devient possible... Maintenant, laissez votre imagination s'envoler et modifiez ( améliorez ) tout les programmes qui ne vous sembleront pas ou mal fini, c'est le meilleurs moyen de progresser.

    Un merci tout spécial à Christal qui entretient si bien la scène francophone... Courage et MERCI !
 
    Merci aussi à tout les crackers, crackeuses, non-crackeurs et non-crackeuses
    sans qui cela n'aurait jamais pu être possible.

    Amicalement
    TeeJi