Crackme de Zone 14
Seconde Release
By Christal |
Octobre 2000 |
Crackme de Zone 14 Seconde Release * Possible StringData Ref from Code 0bj ->"\\.\SICE" :00408F69 68A46D4000 push 00406DA4 :00408F6E 51 push ecx La détection de SoftIce, sollicité lors du clic sur GO et à la sortie du CrackMe, peut être très facilement shuntée en modifiant la string contenue en 00406DA4 : 00406DA0: 10 00 00 00-5C 00 5C 00-2E 00 5C 00-53 00 49 00 \ \ . \ S I 00406DB0: 43 00 45 00-00 00 00 00-23 3D FB FC-FA A0 68 10 C E En remplaçant par exemple SICE par... FUCK comme le fait si joliment FrogSice
! lblmenu(3)_Click CreateFileA(LPSTR:004174D0,FLAGS:00, FLAGS:00, PTR:0063F84C,DWORD:00, FLAGS:00, HAND OLE1.DoVerb End() .... signed char * lpFileName = 004174D0 .... = "\\.\SICE" .... unsigned long dwDesiredAccess = 0 .... unsigned long dwShareMode = 0 En fait l'appel à CreateFileA se fait ainsi : :00408FA6 push eax > \\.\SICE :00408FA7 cal1 00406C8C > call CreateFileA :00408FAC mov dword ptr [ebp+FFFFFF40], eax > Résultat dans [ebp-BF] * Reference To: MSVBVM50. vbaSetSystemError, 0rd:0000h :00408FB2 Call dword ptr [0040D168] :00408FB8 mov edi, dword ptr [ebp+FFFFFF40] > puis transvasé dans esi :00408FBE lea ecx, dword ptr [ebp-2C] * Reference To: MSVBVM50. vbaFreeStr, 0rd:0000h :00408FC1 Call dword ptr [0040D238] :00408FC7 cmp edi, FFFFFFFF > et finalement comparé à -1 :00408FCA je 00408FD2 > si égale, on continue Ben, ca doit pas être bien rapide le VB, comparativement aux mêmes routines
écrites en C ou Delphi... * Referenced by a (U)nconditional or (C)onditiona1 Jump at Address: |:00409E8F(C) :00409EA3 mov ecx, dword ptr [ebp-34] > pousse le serial entré :00409EA6 push ecx :00409EA7 mov edx, dword ptr [ebp-38] > pousse le serial généré :00409EAA push edx * Reference To: MSVBVM50. vbaStrCmp, Ord:0000h :00409EAB Call dword ptr [0040D1A8] > les compare :00409EB1 mov esi, eax :00409EB3 neg esi :00409EB5 sbb esi, esi :00409EB7 neg esi :00409EB9 neg esi :00409EBB lea ecx, dword ptr [ebp-38] * Reference To: MSVBVM50. vbaFreeStr, 0rd:0000h :00409EBE Call dword ptr [0040D238] :00409EC4 lea ecx, dword ptr [ebp-3C] * Reference To: MSVBVM50. vbaFree0bj, 0rd:0000h :00409EC7 Call dword ptr [0040D234] :00409ECD test si, si > et si SI est <> de 0 :00409EDO jne 00409FDl > Goto Pas Glop! :00409ED6 mov ecx, 80020004 > début de la routine Glop! Glop! :00409EDB mov dword ptr [ebp-74], ecx :00409EDE mov eax, 0000000A :00409EE3 mov dword ptr [ebp-7C], eax :00409EE6 mov dword ptr [ebp-64], ecx :00409EE9 mov dword ptr [ebp-6C], eax * Possible StringData Ref from Code 0bj ->"Gr3tzzzz" L'autre réponse obtenue pour vbaStrCmp ne sert qu'à vérifier
si un Nom et un Serial ont bien été entré dans la boite d'enregistrement, et en fonction du
résultat branchera vers l'affichage de la MsgBox " Tous les champs sont obligatoires " (au passage
: l'ensemble des messages qui apparaissent dans ce crackme sont passés par MsgBox, et les paramètres
sont toujours poussés très longtemps avant l'affichage en lui-même). * Referenced by a (U)nconditional or (C)onditiona1 Jump at Addresses: |:00409E2D(C), :00409ED0(C) :00409FDl mov ecx, 80020004 :00409FD6 mov dword ptr [ebp-74], ecx :00409FD9 mov eax, 0000000A :00409FDE mov dword ptr [ebp-7C], eax :00409FE1 mov dword ptr [ebp-64], ecx :00409FE4 mov dword ptr [ebp-6C], eax * Possibleo Code 0bj ->"Erreur" Il y a deux sauts conditionnels qui branchent sur cette routine. Allons voir l'allure du second : :00409E0F mov word ptr [ebp+FFFFFF40], ax > ax dans ebp+FFFFFF40 :00409E16 lea edx, dword ptr [ebp-5C] :00409E19 push edx :00409E1A lea eax, dword ptr [ebp-4C] :00409E1D push eax > puis poussé sur la pile :00409E1E push 00000002 :00409E20 call edi :00409E22 add esp, 0000000C :00409E25 cmp word ptr [ebp+FFFFFF40], 00 > si ebp+FFFFFF40 = 0 :00409E2D jne 00409FD1 > Goto Pas Glop ! La seconde routine étant placée au-dessus de la première, il est facile d'émettre l'hypothèse suivante :
Donc au-dessus de l'item 2, on doit trouver quelque chose qui permette de générer
le serial... Mid(VARIANT: "christal", long:1, VARIANT:Integer:1) > récupère la 1ère lettre du Name Asc(String:"h") returns Integer:99 > conversion ASCII Str(VARIANT:Long:122) > Tiens ! d'où il sort celui là... Puis mon serial entré va apparaître : .. string (variant) _ .. unsigned short * * .pbstrVal = 0063F744 _ .. String = 00417788 .... = "489999" > mon serial .... Long length = 1 0x00000001 _ .. start (variant) .... Long .lVal = 3 0x00000003 Et trois caractères de celui ci vont être "prélevés " : _ vbaVarTstNe(VARIANT:Const String:"", VARIANT:String:"489") returns DWORD:FFFFFFFF .. lhs (variant) .... unsigned short .vt = 32776 0x8008 _ .. rhs (variant) _ .. unsigned short * .bstrVal = 004177D0 .... = "489" Ensuite le programme récupère le " 122 " qui m'avais surpris,
et le message d'erreur " désolé... " apparaît. :00409E25 cmp word ptr [ebp+FFFFFF40], 00 > si ebp+FFFFFF40 = 0 :00409E2D jne 00409FD1 > Goto Pas Glop ! En Noppant purement et simplement ce saut, je vais me rendre compte que ce petit
Mic-Mac va être appliqué à chacune des lettres du Name entré. _ vbaStrMove(String:"12211310...", LPBSTR:0063F740) returns DWORD:4178A8 En cliquant sur cette ligne, la fenêtre de droite du débuggeur VB va me donner : .. unsigned short * pSource = 004178A8 .... = "122113107112106109120117" A la ligne d'en dessous, il récupère mon serial entré, et aussitôt
après je vois les strings de la MsgBox "Désolé...". :00409C87 mov dword ptr [ebp+FFFFFF7C], ecx > D * ECX = Name entré puis : * Reference To: MSVBVM50.__vbaStrVarVal, Ord:0000h :00409CB8 Call dword ptr [0040D1E0] :00409CBE push eax > pousse un caractère ASCII du Name > par exemple 63 pour " c " * Reference To: MSVBVM50.rtcAnsiValueBstr, Ord:0204h :00409CBF Call dword ptr [0040D15C] :00409CC5 push eax > le transforme en Unicode " 6.3 " Plus loin (ca ne donne vraiment pas une idée de langage optimisé tout ca, à moins que ca ne soit une manière de noyer le poisson) : :00409CEE push ecx > rappel " 6.3 " * Reference To: MSVBVM50.__vbaI4Str, Ord:0000h :00409CEF Call dword ptr [0040D1FC] :00409CF5 xor eax, 00000019 > 63 Xor 19 = 7A ! :00409CF8 mov dword ptr [ebp-44], eax Et la valeur décimale de 7Ah est 122 !
Rien de plus facile, maintenant que de bidouiller un petit KeyGenerator. ;========================================================================= ; KeyGenerator ; la bonne clé se trouve dans Serial à la fin de la routine ;========================================================================= invoke GetWindowTextA,hwndEdit1,ADDR buffer,12 > saisie le Name entré (placé dans buffer) mov dword ptr [Serial+00],0000 > pas très élégant, mais j'ai eu mov dword ptr [Serial+04],0000 > la flemme de trouver mieux pour mov dword ptr [Serial+08],0000 > effacer un précédent serial cmp eax, 04 > le Name est < à 4 caractères ? jl Trop_court > c'est pas good -> affiche Erreur cmp eax, 10 > il est supérieur à 10 caractères ? jng Long_OK > pas good non plus... A ce sujet, le crackme ne limite absolument pas le nombre de caractères du Name. C'est simplement pour que le résultat obtenu puisse s'afficher dans le second champ de mon KeyGen que j'ai restreint sa longueur à 10 caractères. Pour des noms plus long, utilisez le patch joint au Zip. invoke MessageBoxA, NULL,addr TextAbout, addr Caption, 040h jmp Fin Long_OK: Xor ebx,ebx ; compteur des caractères boucle: Xor eax,eax ; ré-initialise EAX mov al, byte ptr [ebx+buffer] ; prend 1 caractère dans Buffer test al, al ; il y en a encore? je Affiche ; c'est good, on affiche xor al, 19h ; création clé n°1 mov esi,eax ; met la clé 1 calculé dans ESI call decimal ; conversion hexa -> décimal mov eax, Key ; Key contient l'élément du serial xor esi, esi ; ré-initialise ESI place_libre: cmp byte ptr [Serial+esi],00 ; cherche de la place libre je ecrit_serial ; si trouvé va placer la Key inc esi ; sinon passe à l'octet suivant jmp place_libre ; et cherche à nouveau ecrit_serial: mov dword ptr [Serial+esi],eax ; écrit la Key à la suite des autres inc ebx ; passe au caractère suivant du Name jmp boucle ; et recommence le Process La Key obtenu peut être de 2 ou 3 caractères de long, en fonction des
Majuscules, Minuscules, Chiffres et autres Symboles que vous aurez entré comme Name. La petite routine ci
dessus se contente (très mal sûrement) de chercher de la place (des 00) à partir du début
de l'adresse allouée au Serial généré, et ira placer la Key à la suite des autres
pour composer ce serial, avant de l'afficher dans le second champ du KeyGenerator. |
Merci à l'équipe de Zone 14
Bonne Journée