How To Find HCCC6 MD5 CrackMe's Serial
A la sortie du nouvel HCCC, le 6, Kahel qui avait codé l'interface du wiever avait aussi inclu un petit exercice sympa basé sur l'algorithme de hashage MD5.
Dans les explications que Kahel donnait, il y avait beaucoup à prendre :
" Le but du crackme est tout d'abord de trouver quel est le hash prédéfini ".
" ... ensuite il faudra écrire un bruteforcer pour trouver le serial ".
" ... Maximum 5 minutes de calculs :) ".
" ... Le crackme peut etre keygennable , en effet il ne compare que les 8 premiers bytes du Hash ".
" Le serial auquel je pensais en codant ce crackme n'est composé que de chiffres... ".
Il y a donc :
- un hash prédéfini à trouver
- le texte correspondant à ce hash est forcement court, sinon les 5 minutes de recherche seront largement dépassées (comptez plusieurs heures, suivant les cas…), même pour une recherche ne portant que sur les 8 premiers bytes.
- le texte n'est composé que de chiffres
et pour nous aider, Kahel avait de plus inclu dans un zip toute la doc nécessaire, dont en voici un extrait :
" Notion de fonction de hachage
Une fonction de hachage est une fonction mathématique qui a partir d'un message (d'une donnée) génère une autre chaîne (généralement plus courte).
Terminologie: fonction de contraction, digest, empreinte digitale, ...
Exemples:
Calcul de parité verticale :
On fait le OU exclusif de tous les octets d'une chaîne de caractères.
Calcul de code polynomial :
Notion de fonction de hachage à sens unique sans clé :
C'est une fonction de hachage à sens unique qui peut être calculée par n'importe qui (MD5).
Notion de fonction de hachage à sens unique avec clé :
C'est une fonction de hachage à sens unique qui ne peut être calculée que par
une seule entité détentrice de la clé.
Signatures numériques :
Une signature manuscrite idéale est réputée posséder les propriétés suivantes:
- La signature ne peut-être imitée. Elle prouve que le signataire a délibérément signé le document.
- La signature authentifie le signataire. Seul le signataire peut avoir signé.
- La signature appartient à un seul document (elle n'est pas réutilisable).
- Le document signé ne peut être partiellement ou totalement modifié.
- La signature ne peut-être reniée.
Base de la signature numérique:
L'existence d'une fonction de hachage à sens unique avec clé :
Une solution possible: une fonctions de hachage à sens unique et une technique
classique de cryptographie (exemple le RSA)
MD5 Message Digest version 5 :
Une fonction de hachage à sens unique :
On génère une signature sur 128 bits. Le message est décomposé en blocs de 512 bits soient 16 sous-blocs Mj de 32 bits. Pour chaque bloc de 512 bits on réalise 4 séries de 16 applications successives des fonctions de base FF, GG , HH, II qui dépendent des sous-blocs Mj et de constantes a, b, c, d, ti:FF(a,b,c,d,Mj,s,ti) -> a = b + ((a = F(b, c,d) + Mj+ ti) <s) GG(a, b,c,d,Mj,s, ti) -> a = b + ((a = G(b,c,d) + Mj+ ti) <s) HH(a,b, c,d,Mj,s,ti) -> a = b + ((a = H(b,c,d) + Mj + ti) <s) II(a,b, c,d,Mj,s,ti) -> a = b + ((a = I(b,c, d) + Mj + ti) <s)Dans les formules précédentes <s désigne un décalage à gauche de <s positions les fonctions F,G, H,I sont données par:
F(X,Y,Z) = (X AND Y) OR (NOT X AND Z) G(X,Y, Z) = (X AND Z) OR (Y AND NOT Z) H(X,Y,Z) = (X XOR Y XOR Z) I(X,Y,Z) = Y XOR (X OR NOT Z) ".(Il est à noter que Kahel a aussi signé dans HCCC6 un article sur le cryptage El Gamal qui mérite vraiment d'être lu !)
Après cette introduction un peu longue, voyons ce qu'il en est du crackme de Kahel.
On peut y accéder via le viewer.
Serait ce à dire que le crackme est une dialogbox incorporé à ce wiever ?
Non !
En fermant HCCC6, la box est toujours présente, donc elle a été crée pour être indépendante du wiever.
Le plus simple est de faire une recherche sur le HDD en prenant le caption comme clé. Et effectivement, on trouve rapidement que le crackme a été copié dans C:\WINDOWS\TEMP\.
Pour faire plus compliqué, il y avait moyen d'utiliser FileMon pour l'apprendre :Ezine Open C:\WINDOWS\TEMP\CRACKME.EXE 0x50 CREATENEW READWRITEOu encore d'utiliser SoftIce pour breaker sur les APIs ShellExecute ou ShellExecuteEx, histoire de jeter un coup d'œil dans lpDirectory :
La fonction ShellExecute ouvre ou imprime un fichier spécifié. Ce fichier peut être un exécutable ou un document.
HINSTANCE ShellExecute(HWND hwnd, // handle de la fenêtre propriétaire LPCTSTR lpOperation, // pointe vers une string spécifiant l'opération à exécuter LPCTSTR lpFile, // pointe vers le fichier ou le répertoire à atteindre LPCTSTR lpParameters, // pointe vers une string spécifiant les paramètres d'exécution LPCTSTR lpDirectory, // pointe vers une string spécifiant le répertoire par défaut INT nShowCmd // indique le statut du fichier lors de son ouvertureFinalement, Wdasm donne les strings data qui vont bien (un fois HCCC6 Un-UPXé -> sensationnelle cette fonction décompress !) :
" Hccc Crackme"
"c:\windows\temp\crackme.exe"
"CRACKME"
"open"
et un chtit double clic de mulot nous envoie ici ::004015B1 6A01 push 00000001 :004015B3 6A00 push 00000000 :004015B5 6A00 push 00000000 :004015B7 68C2B14400 push 0044B1C2 ->"c:\windows\temp\crackme.exe" :004015BC 6861B14400 push 0044B161 ->"open" :004015C1 6A00 push 00000000 :004015C3 E8B40C0000 Call SHELL32.ShellExecuteABene, maintenant que l'on sait ou se trouve le crackme de kahel, voyons ce qu'il a dans le ventre :
__________________________________________________________ sections : ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ name vSize vAddress rawSize rOffset Caract UPX0 00034000h 00001000h 00000000h 00000400h E0000080h UPX1 00021000h 00035000h 00020400h 00000400h E0000040h .rsrc 00001000h 00056000h 00000C00h 00020800h C0000040h __________________________________________________________PARFAIT !
Lui aussi est compressé avec UPX, histoire de le rendre plus petit.
Kahel a vraiment été cool !
Une fois décompressé, Wdasm va encore avoir des choses à dire :
"a5ba6896"
"MD5"
"serial valide"
Si kahel n'avait pas précisé qu'il s'agissait d'un hashage MD5, la seconde string que j'ai retenue ne m'aurait peut être pas sauté au yeux.
Par contre, l'espèce de serial semble très prometteur ::00441065 mov edx, dword ptr [ebp-08] > edx = caractères entrés ... :00441087 mov eax, dword ptr [ebp-04] > eax = hash corespondant ... :004410A1 mov eax, dword ptr [ebp-04] > eax = 8 derniers bytes du hash * Possible StringData Ref from Code Obj ->"a5ba6896" :004410A4 mov edx, 004410FC > edx = a5ba6896 :004410A9 call 00403C74 > comparaison :004410AE jne 004410C8 > Pas Glop ! c'est la sortie :004410B0 push 00000000 > Glop Glop ! la MsgBox s'affiche. :004410B2 mov ecx, 00441108 * Possible StringData Ref from Code Obj ->"serial valide" :004410B7 mov edx, 0044110C > serial valideEt le tout l'un au-dessus de l'autre, il n'y a plus à hésiter !
Kahel a cependant conservé un peu de mystère…
Il avait parlé des 8 premiers bytes du hash comparés avec une clé prédéfinie, mais sans préciser qu'il en faisait la lecture de la droite vers la gauche : en fait c'est le dernier Dword du hash qui est comparé avec la clé !
Il ne reste plus qu'à trouver un texte de quelques caractères numériques (disons 5) dont le hash donnerait une série se finissant par a5ba6896.
Je ne sais pas s'il existe un Un_hasher, capable de reverser MD5 pour en donner le serial (je crois que DAMN et TMG en ont réalisé), mais j'ai découvert, pour l'avoir testé, qu'il faut environ deux heures pour calculer une série allant de 1 à 99999999h. En incluant des caractères alphabétiques, le temps augmente considérablement…
Voici le source que je propose comme solution à l'exercice de Kahel , basé sur un source de roy|crisiscrackers pour le calcul du Hash MD5:
.386 .model flat, stdcall option casemap :none ; case sensitive ; déclaration des procédures DlgProc proto :dword,:dword,:dword,:dword FF proto :dword,:dword,:dword,:dword,:dword,:byte,:dword GG proto :dword,:dword,:dword,:dword,:dword,:byte,:dword HH proto :dword,:dword,:dword,:dword,:dword,:byte,:dword II proto :dword,:dword,:dword,:dword,:dword,:byte,:dword procMD5hash proto :dword,:dword,:dword StaticImage PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD Str2Hex PROTO :DWORD, :DWORD OpenDialog PROTO :DWORD ; récupération des Dll et des fonctions include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc include \masm32\include\comdlg32.inc include \masm32\include\comctl32.inc include \masm32\include\masm32.inc include \masm32\include\shell32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\comdlg32.lib includelib \masm32\lib\comctl32.lib includelib \masm32\lib\masm32.lib includelib \MASM32\LIB\shell32.lib ; déclaration de la structure MD5 MD5RESULT STRUCT dtA dd ? dtB dd ? dtC dd ? dtD dd ? MD5RESULT ENDS .const IDC_ABOUT equ 101 IDC_EDITTEXT equ 102 IDC_EDITHASH equ 103 IDD_DIALOG equ 100 IDI_ICON equ 200 IDC_progress equ 130 ID_Fond equ 500 IDC_STATIC2 equ 1004 IDC_Search equ 106 IDC_Exit equ 108 IDC_Result equ 123 IDC_Open equ 107 IDC_mini equ 113 IDC_maxi equ 114 IDC_h1 equ 118 IDC_h2 equ 120 IDC_h3 equ 121 IDC_h4 equ 122 MAXSIZE equ 260 .data bfBuffer db MAXSIZE dup (0) buffer1 db MAXSIZE dup (0) buffer2 db MAXSIZE dup (0) buffer3 db 10 dup (0) buffer4 db 10 dup (0) buffer5 db 10 dup (0) buffer6 db 10 dup (0) brut dd 20 dup (0) szAboutCaption db 'about HCCC6 md5 hasher',0 szAboutText db 'md5hasher',13,10,'basé sur un source de' db 13,10,'roy|crisiscrackers.',13,10 db 13,10,"La recherche ne porte que" db 13,10,"sur un seul Dword du hash" db 13,10,"dans le cadre mini/maxi," db 13,10,"que vous aurez indiqué." db 13,10,13,10,"Coded by Christal",0 szMD5Format db '%.8x%.8x%.8x%.8x',0 serialformat db "%d",0 format2 db "8x%",0 dlgname db "dialogbox",0 good db "Serial trouvé",0 nogood db "Serial non trouvé",0 error_1 db "Erreur entre valeurs mini et maxi",0 error_2 db "valeur de hash non valide",0 open db "open",0 crackme db "crackme.exe",0 slash db "C:\WINDOWS\TEMP\CRACKME.EXE",0 cible_ok db "Crackme trouvé",0 TimerID dd 0 hBmp dd 0 lg_mini dd 0 lg_maxi dd 0 rang dd 0 StaticClass db "static",0 FilterString db "HCCC6 Crackme",0,"crackme.exe",0 db "Tous les Fichiers",0,"*.*",0,0 ofn OPENFILENAME <> .data? hInstance HINSTANCE ? stMD5Result MD5RESULT <?> hwndProgress dd ? hwndResult dd ? hwndStatus dd ? hStatImage dd ? CurrentStep dd ? Directory db 512 dup (?) .code start: invoke GetModuleHandle,0 mov hInstance,eax ; appel de la dialgBox crée dans les ressources invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR DlgProc,0 invoke ExitProcess,eax DlgProc proc uses ebx edi esi,hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM cmp uMsg,WM_INITDIALOG jz initdialog cmp uMsg,WM_CLOSE jz close cmp uMsg,WM_COMMAND jz command ret bruteforcer: ; saisie du 1er dword du hash. Si absent passe au suivant, etc... invoke GetDlgItemText,hWnd,IDC_h1,addr buffer3,9 mov dword ptr [rang],0 cmp eax,8 je @F invoke GetDlgItemText,hWnd,IDC_h2,addr buffer3, mov dword ptr [rang],8 cmp eax,8 je @F invoke GetDlgItemText,hWnd,IDC_h3,addr buffer3,9 mov dword ptr [rang],16 cmp eax,8 je @F invoke GetDlgItemText,hWnd,IDC_h4,addr buffer3,9 mov dword ptr [rang],24 cmp eax,8 je @F invoke SetWindowTextA,hwndProgress, addr error_2 ret ; saisie de la plus petite et de la plus grande valeur qui serviront ; de fourchette de recherche @@: invoke GetDlgItemText,hWnd,IDC_mini,addr buffer5,9 cmp eax,0 jle error1 mov dword ptr [lg_mini],eax invoke GetDlgItemText,hWnd,IDC_maxi,addr buffer6,9 cmp eax,0 jle error1 mov dword ptr [lg_maxi],eax ; les valeurs mini et maxi sont transformées d'une string en une valeur hexadécimale invoke Str2Hex, addr buffer5,dword ptr [lg_mini] mov dword ptr [buffer5],eax invoke Str2Hex, addr buffer6,dword ptr [lg_maxi] mov dword ptr [buffer6],eax sub eax, dword ptr [buffer5] jle error1 invoke SetWindowTextA,hwndProgress, NULL mov eax, dword ptr [buffer5] mov dword ptr [brut],eax loop1: invoke wsprintfA,addr buffer1,addr serialformat, dword ptr [brut] invoke wsprintfA,addr buffer2,addr serialformat, dword ptr [brut] invoke lstrlen,addr buffer1 invoke procMD5hash,addr buffer1,eax,addr stMD5Result mov eax, dword ptr [buffer3] mov esi, dword ptr [rang] cmp dword ptr [buffer1+esi], eax je trouve1 inc dword ptr [brut] mov eax, dword ptr [buffer6] cmp dword ptr [brut], eax jle loop1 Pas_Glop: invoke SetWindowTextA,hwndResult, NULL invoke SetWindowTextA,hwndProgress, addr nogood ret trouve1: mov eax, dword ptr [buffer3+4] mov esi, dword ptr [rang] add esi,4 cmp dword ptr [buffer1+esi], eax je trouve2 inc dword ptr [brut] mov eax, dword ptr [buffer5] cmp dword ptr [brut], eax jle loop1 jmp Pas_Glop trouve2: invoke SetWindowTextA,hwndResult, addr buffer2 invoke SetWindowTextA,hwndProgress, addr good ret error1: invoke SetWindowTextA,hwndProgress, addr error_1 ret endcheck: mov eax,1 ret command: mov eax,wParam mov edx,wParam .if ax == IDC_Search invoke SetWindowTextA,hwndProgress, NULL jmp bruteforcer .endif .if ax == IDC_Exit invoke ExitProcess,0 .endif .if ax == IDC_Open invoke ShellExecuteA,hWnd,addr open,addr crackme,NULL,NULL,01 cmp eax,32 jnle @F invoke ShellExecuteA,hWnd,addr open,addr slash,NULL,NULL,01 cmp eax,32 jnle @F invoke OpenDialog, hWnd @@: .endif shr edx,16 cmp edx,BN_CLICKED jnz @f cmp ax,IDC_ABOUT jnz endcheck invoke MessageBoxA,hWnd,addr szAboutText,addr szAboutCaption,MB_OK or MB_ICONASTERISK ret @@: cmp edx,EN_CHANGE jnz endcheck cmp ax,IDC_EDITTEXT jnz endcheck invoke GetDlgItemText,hWnd,IDC_EDITTEXT,addr bfBuffer,MAXSIZE invoke procMD5hash,addr bfBuffer,eax,addr stMD5Result invoke SendDlgItemMessageA,hWnd,IDC_EDITHASH,WM_SETTEXT,0,addr bfBuffer ret initdialog: invoke LoadIconA,hInstance,IDI_ICON invoke SendMessageA,hWnd,WM_SETICON,1,eax invoke SendDlgItemMessageA,hWnd,IDC_EDITTEXT,WM_SETTEXT,0,0 ; load bitmap invoke StaticImage,NULL,hWnd,10,10,121,44,IDC_STATIC2 mov hStatImage, eax invoke LoadBitmap,hInstance,ID_Fond mov hBmp, eax ; place l'image dans static control invoke SendMessage,hStatImage,STM_SETIMAGE,IMAGE_BITMAP,hBmp invoke GetDlgItem, hWnd, IDC_progress mov hwndProgress, eax invoke GetDlgItem, hWnd, IDC_Result mov hwndResult, eax ret close: invoke EndDialog,hWnd,0 ret DlgProc endp procMD5hash proc ptBuffer:dword,dtBufferLength:dword,ptMD5Result:dword local dta:dword,dtb:dword,dtc:dword,dtd:dword ; phase I · padding mov edi,ptBuffer mov eax,dtBufferLength inc eax add edi,eax mov byte ptr [edi-1],080h xor edx,edx mov ebx,64 div ebx neg edx add edx,64 cmp edx,8 jae @f add edx,64 @@: mov ecx,edx xor al,al rep stosb mov eax,dtBufferLength inc edx add dtBufferLength,edx xor edx,edx mov ebx,8 mul ebx mov dword ptr [edi-8],eax mov dword ptr [edi-4],edx mov edx,dtBufferLength mov edi,ptBuffer ; phase II · chaining variables initialization mov esi,ptMD5Result assume esi:ptr MD5RESULT mov [esi].dtA,067452301h mov [esi].dtB,0efcdab89h mov [esi].dtC,098badcfeh mov [esi].dtD,010325476h ; phase III · hashing hashloop: mov eax,[esi].dtA mov dta,eax mov eax,[esi].dtB mov dtb,eax mov eax,[esi].dtC mov dtc,eax mov eax,[esi].dtD mov dtd,eax ; round 1 invoke FF,dta,dtb,dtc,dtd,dword ptr [edi+00*4],07,0d76aa478h mov dta,eax invoke FF,dtd,dta,dtb,dtc,dword ptr [edi+01*4],12,0e8c7b756h mov dtd,eax invoke FF,dtc,dtd,dta,dtb,dword ptr [edi+02*4],17,0242070dbh mov dtc,eax invoke FF,dtb,dtc,dtd,dta,dword ptr [edi+03*4],22,0c1bdceeeh mov dtb,eax invoke FF,dta,dtb,dtc,dtd,dword ptr [edi+04*4],07,0f57c0fafh mov dta,eax invoke FF,dtd,dta,dtb,dtc,dword ptr [edi+05*4],12,04787c62ah mov dtd,eax invoke FF,dtc,dtd,dta,dtb,dword ptr [edi+06*4],17,0a8304613h mov dtc,eax invoke FF,dtb,dtc,dtd,dta,dword ptr [edi+07*4],22,0fd469501h mov dtb,eax invoke FF,dta,dtb,dtc,dtd,dword ptr [edi+08*4],07,0698098d8h mov dta,eax invoke FF,dtd,dta,dtb,dtc,dword ptr [edi+09*4],12,08b44f7afh mov dtd,eax invoke FF,dtc,dtd,dta,dtb,dword ptr [edi+10*4],17,0ffff5bb1h mov dtc,eax invoke FF,dtb,dtc,dtd,dta,dword ptr [edi+11*4],22,0895cd7beh mov dtb,eax invoke FF,dta,dtb,dtc,dtd,dword ptr [edi+12*4],07,06b901122h mov dta,eax invoke FF,dtd,dta,dtb,dtc,dword ptr [edi+13*4],12,0fd987193h mov dtd,eax invoke FF,dtc,dtd,dta,dtb,dword ptr [edi+14*4],17,0a679438eh mov dtc,eax invoke FF,dtb,dtc,dtd,dta,dword ptr [edi+15*4],22,049b40821h mov dtb,eax ; round 2 invoke GG,dta,dtb,dtc,dtd,dword ptr [edi+01*4],05,0f61e2562h mov dta,eax invoke GG,dtd,dta,dtb,dtc,dword ptr [edi+06*4],09,0c040b340h mov dtd,eax invoke GG,dtc,dtd,dta,dtb,dword ptr [edi+11*4],14,0265e5a51h mov dtc,eax invoke GG,dtb,dtc,dtd,dta,dword ptr [edi+00*4],20,0e9b6c7aah mov dtb,eax invoke GG,dta,dtb,dtc,dtd,dword ptr [edi+05*4],05,0d62f105dh mov dta,eax invoke GG,dtd,dta,dtb,dtc,dword ptr [edi+10*4],09,002441453h mov dtd,eax invoke GG,dtc,dtd,dta,dtb,dword ptr [edi+15*4],14,0d8a1e681h mov dtc,eax invoke GG,dtb,dtc,dtd,dta,dword ptr [edi+04*4],20,0e7d3fbc8h mov dtb,eax invoke GG,dta,dtb,dtc,dtd,dword ptr [edi+09*4],05,021e1cde6h mov dta,eax invoke GG,dtd,dta,dtb,dtc,dword ptr [edi+14*4],09,0c33707d6h mov dtd,eax invoke GG,dtc,dtd,dta,dtb,dword ptr [edi+03*4],14,0f4d50d87h mov dtc,eax invoke GG,dtb,dtc,dtd,dta,dword ptr [edi+08*4],20,0455a14edh mov dtb,eax invoke GG,dta,dtb,dtc,dtd,dword ptr [edi+13*4],05,0a9e3e905h mov dta,eax invoke GG,dtd,dta,dtb,dtc,dword ptr [edi+02*4],09,0fcefa3f8h mov dtd,eax invoke GG,dtc,dtd,dta,dtb,dword ptr [edi+07*4],14,0676f02d9h mov dtc,eax invoke GG,dtb,dtc,dtd,dta,dword ptr [edi+12*4],20,08d2a4c8ah mov dtb,eax ; round 3 invoke HH,dta,dtb,dtc,dtd,dword ptr [edi+05*4],04,0fffa3942h mov dta,eax invoke HH,dtd,dta,dtb,dtc,dword ptr [edi+08*4],11,08771f681h mov dtd,eax invoke HH,dtc,dtd,dta,dtb,dword ptr [edi+11*4],16,06d9d6122h mov dtc,eax invoke HH,dtb,dtc,dtd,dta,dword ptr [edi+14*4],23,0fde5380ch mov dtb,eax invoke HH,dta,dtb,dtc,dtd,dword ptr [edi+01*4],04,0a4beea44h mov dta,eax invoke HH,dtd,dta,dtb,dtc,dword ptr [edi+04*4],11,04bdecfa9h mov dtd,eax invoke HH,dtc,dtd,dta,dtb,dword ptr [edi+07*4],16,0f6bb4b60h mov dtc,eax invoke HH,dtb,dtc,dtd,dta,dword ptr [edi+10*4],23,0bebfbc70h mov dtb,eax invoke HH,dta,dtb,dtc,dtd,dword ptr [edi+13*4],04,0289b7ec6h mov dta,eax invoke HH,dtd,dta,dtb,dtc,dword ptr [edi+00*4],11,0eaa127fah mov dtd,eax invoke HH,dtc,dtd,dta,dtb,dword ptr [edi+03*4],16,0d4ef3085h mov dtc,eax invoke HH,dtb,dtc,dtd,dta,dword ptr [edi+06*4],23,004881d05h mov dtb,eax invoke HH,dta,dtb,dtc,dtd,dword ptr [edi+09*4],04,0d9d4d039h mov dta,eax invoke HH,dtd,dta,dtb,dtc,dword ptr [edi+12*4],11,0e6db99e5h mov dtd,eax invoke HH,dtc,dtd,dta,dtb,dword ptr [edi+15*4],16,01fa27cf8h mov dtc,eax invoke HH,dtb,dtc,dtd,dta,dword ptr [edi+02*4],23,0c4ac5665h mov dtb,eax ; round 4 invoke II,dta,dtb,dtc,dtd,dword ptr [edi+00*4],06,0f4292244h mov dta,eax invoke II,dtd,dta,dtb,dtc,dword ptr [edi+07*4],10,0432aff97h mov dtd,eax invoke II,dtc,dtd,dta,dtb,dword ptr [edi+14*4],15,0ab9423a7h mov dtc,eax invoke II,dtb,dtc,dtd,dta,dword ptr [edi+05*4],21,0fc93a039h mov dtb,eax invoke II,dta,dtb,dtc,dtd,dword ptr [edi+12*4],06,0655b59c3h mov dta,eax invoke II,dtd,dta,dtb,dtc,dword ptr [edi+03*4],10,08f0ccc92h mov dtd,eax invoke II,dtc,dtd,dta,dtb,dword ptr [edi+10*4],15,0ffeff47dh mov dtc,eax invoke II,dtb,dtc,dtd,dta,dword ptr [edi+01*4],21,085845dd1h mov dtb,eax invoke II,dta,dtb,dtc,dtd,dword ptr [edi+08*4],06,06fa87e4fh mov dta,eax invoke II,dtd,dta,dtb,dtc,dword ptr [edi+15*4],10,0fe2ce6e0h mov dtd,eax invoke II,dtc,dtd,dta,dtb,dword ptr [edi+06*4],15,0a3014314h mov dtc,eax invoke II,dtb,dtc,dtd,dta,dword ptr [edi+13*4],21,04e0811a1h mov dtb,eax invoke II,dta,dtb,dtc,dtd,dword ptr [edi+04*4],06,0f7537e82h mov dta,eax invoke II,dtd,dta,dtb,dtc,dword ptr [edi+11*4],10,0bd3af235h mov dtd,eax invoke II,dtc,dtd,dta,dtb,dword ptr [edi+02*4],15,02ad7d2bbh mov dtc,eax invoke II,dtb,dtc,dtd,dta,dword ptr [edi+09*4],21,0eb86d391h mov dtb,eax mov eax,dta add [esi].dtA,eax mov eax,dtb add [esi].dtB,eax mov eax,dtc add [esi].dtC,eax mov eax,dtd add [esi].dtD,eax add edi,64 sub edx,64 jnz hashloop ; phase IV · results mov ecx,4 @@: mov eax,dword ptr [esi] xchg al,ah rol eax,16 xchg al,ah mov dword ptr [esi],eax add esi,4 loop @b mov esi,ptMD5Result invoke wsprintfA,ptBuffer,addr szMD5Format,[esi].dtA,[esi].dtB,[esi].dtC,[esi].dtD ret procMD5hash endp FF proc dta,dtb,dtc,dtd,x,s:byte,t ; a = b + ((a + F(b,c,d) + x + t) << s ) mov eax,dtb mov ebx,dtc mov ecx,dtd ; F(x,y,z) = (x and y) or ((not x) and z) and ebx,eax not eax and eax,ecx or eax,ebx add eax,dta add eax,x add eax,t mov cl,s rol eax,cl add eax,dtb ret FF endp GG proc dta,dtb,dtc,dtd,x,s:byte,t ; a = b + ((a + G(b,c,d) + x + t) << s) mov eax,dtb mov ebx,dtc mov ecx,dtd ; G(x,y,z) = (x and z) or (y and (not z)) and eax,ecx not ecx and ecx,ebx or eax,ecx add eax,dta add eax,x add eax,t mov cl,s rol eax,cl add eax,dtb ret GG endp HH proc dta,dtb,dtc,dtd,x,s:byte,t ; a = b + ((a + H(b,c,d) + x + t) << s) mov eax,dtb mov ebx,dtc mov ecx,dtd ; H(x,y,z) = x xor y xor z xor eax,ebx xor eax,ecx add eax,dta add eax,x add eax,t mov cl,s rol eax,cl add eax,dtb ret HH endp II proc dta,dtb,dtc,dtd,x,s:byte,t ; a = b + ((a + I(b,c,d) + x + t) << s) mov eax,dtb mov ebx,dtc mov ecx,dtd ; I(x,y,z) = y xor (x or (not z)) not ecx or eax,ecx xor eax,ebx add eax,dta add eax,x add eax,t mov cl,s rol eax,cl add eax,dtb ret II endp ;========================================================================= ; affichage BitMap ;========================================================================= StaticImage proc lpText:DWORD,hParent:DWORD, a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD invoke CreateWindowEx,WS_EX_STATICEDGE,\ ADDR StaticClass ,lpText,\ WS_CHILD or WS_VISIBLE or SS_BITMAP,\ a,b,wd,ht,hParent,ID,\ hInstance,NULL ret StaticImage endp ;========================================================================= ; conversion string en val hex ;========================================================================= Str2Hex PROC uses ebx ecx edx Buff:DWORD, Lenght:DWORD mov ebx,Buff mov ecx,Lenght xor eax,eax xor edx,edx CHC_pour1: mov dl,byte ptr[ebx+ecx-1] cmp dl,'A' jge CHC_sinon1 sub dl,'0' jmp CHC_fsi1 CHC_sinon1: sub dl,'A'-10 CHC_fsi1: or al,dl ror eax,04 loop CHC_pour1 CHC_fpour1: mov ecx, Lenght neg ecx add ecx, 8 shl ecx, 2 ror eax, cl ret Str2Hex endp ;========================================================================= ; Brownse ;========================================================================= OpenDialog PROC hWin:DWORD mov [Directory],00 mov ofn.lStructSize,SIZEOF ofn mov ofn.lpstrFilter, OFFSET FilterString mov ofn.lpstrFile, OFFSET Directory mov ofn.nMaxFile,512 mov ofn.Flags, OFN_FILEMUSTEXIST or \ OFN_PATHMUSTEXIST or OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY invoke GetOpenFileName, offset ofn cmp eax, FALSE jz EndOD invoke SetWindowTextA,hwndProgress, ADDR cible_ok invoke ShellExecuteA,hWin,addr open,addr Directory,NULL,NULL,01 EndOD: ret OpenDialog ENDP end start
Bonne Journée