> ########\ ##\ ##\ ############\ ########\ > ######## | ## | ## | ############ | ######## | > ## ## | ## | ## | \___\##\____\| ##\_____\| > ## ## | ## | ## | ## | ## | > ############\ ############ | ## | ######\ > ############ | ############ | ## | ###### | > ## ## | \___\##\____\| ## | ##\___\| > ## ## | ## | ## | ## | > ############ | ## | ## | ############\ > ############ | ## | ## | ############ | > \___________\| \_\| \_\| \___________\| > > ############\ ###########\ ###########\ > ############ | ########### | ########### | /\ > ##\_________\| ## ## | ## ## | ___/ \___ > ## | ## ## | ## ## | \ / > ## | ## ## | ########### | \ o o / > ## | ## ## | ########### | / __ \ > ## | ## ## | ##\________\| /__ __\ > ## | ## ## | ## | \ / > ############\ ########### | ## | \/ > ############ | ########### | ## | > \___________\| \__________\| \_\| > > >************************************************* >******* TEST DE WINACE.EXE V1.2 ******* >************************************************* >Dt:01/02/2000 > >Salut à tous, > >Petite étude de WinAce.exe Version 1.2 > >Alors on s'équipe de tout ce qu'il faut : Jus de fruits, barres de céréales... >(certains pour la frime disent : Alcool, drogueS et autres accélérateurs de particules...) > >Il s'agit d'un prog Delphi compacté par AsPack (c'est écrit ds le PE ;o] ). > >************************************************* >Donc 1ere manipulation : le décompactage. >************************************************* > >On prend un éditeur de PE header et on vérifie les infos des sections >CODE : C0000040 => problèmes = pas de Désassemblage, pas de Debug... >On corrige par un E0000020. > >On trace un peu de code avec un Debgr (style SoftICE ou TRW2000) >- première remarque un PUSHAD => il y a de forte chance d'avoir un POPAD à la fin. > >0177:00648001 PUSHAD *******=Push EDI, ESI, EBP, EBX, EDX, ECX, EAX >0177:00648002 CALL 00648542 >0177:00648007 JMP 00648051 >0177:00648051 MOV EBX,00442994 >0177:00648056 ADD EBX,EBP >0177:00648058 SUB EBX,[EBP+004429C1] >...... On UnPack... >...... >0177:006484BC POPAD ******* He Oui >0177:006484BD JNZ 006484C7 >0177:006484C7 PUSH 005802E4 Adresse du prog >0177:006484CC RET On y va >0177:005802E4 PUSH EBP On y est ;) >0177:005802E5 MOV EBP,ESP >0177:005802E7 ADD ESP,-10 >0177:005802EA PUSH EBX > >Donc l'adresse de l'exe est 005802E4 > >en 0177:006484CC on place un JMP EIP pour faire une boucle infinie... >On prend son meilleur dumper (SDump ou ProcDump ou autre) > >On fait un Full Dump de l'exe WinAce (J'aime bien ProcDump). >Ensuite on Kill la tâche WinAce.exe (il y a une boucle infinie) > >On prend son meilleur éditeur de PE (ProcDump par exemple ;) et on corrige le point d'entrée : >005802E4 - 00400000 = 001802E4 et voila... >On obtient un exe non compressé qui tourne correctement ! > >Bien sur on peut attendre d'avoir un prog qui fait du UnAsPack directement >mais bon il faut qd même un minimum de savoir faire pour ne pas être trop dépendant ! > >************************************************* >Enregistrement d'un utilisateur Oui mais OU ?? >************************************************* >Après qq tests (plus ou moins longs en fonction du niveau du testeur ;) >On galère un peu dans AceTools.Dll (en fait il n'y a que les formulaires) >On passe dans Ace.Dll et on revient dans WinAce.exe etc... > >Pour les nouveaux : Y a pas de secret on fait de façon classique : >Un bp sur un call et on le passe si Code non Valide alors il faut étudier ce call ! >(on procède un peu par dichotomie) > >// bien sur on peut être plus Zen et voir que ds Ace.Dll il y a des noms de fonctions >// qui sont très explicites donc on y met un BP ;) et hop Glop Glop ! > >Donc dans WinAce on tombe ici : > >:00558DBD FFD3 call ebx :::Appel du TRegForm (ou l'on met le code) >:00558DBF 84C0 test al, al :::Bouton Cancel ? >:00558DC1 0F847B010000 je 00558F42 :::Oui on annule... >:00558DC7 33C0 xor eax, eax :::Sinon on test les résultats >:00558DC9 A348625800 mov dword ptr [00586248], eax >:00558DCE 8D95F0FDFFFF lea edx, dword ptr [ebp+FFFFFDF0] >:00558DD4 8D85F0FCFFFF lea eax, dword ptr [ebp+FFFFFCF0] >:00558DDA E8459EEAFF call 00402C24 >:00558DDF BAA48F5500 mov edx, 00558FA4 >:00558DE4 8D85F0FCFFFF lea eax, dword ptr [ebp+FFFFFCF0] >:00558DEA E8DD9DEAFF call 00402BCC :::Taille de la AVString (UserName) >:00558DEF 8D95F0FCFFFF lea edx, dword ptr [ebp+FFFFFCF0] >:00558DF5 B884625800 mov eax, 00586284 >:00558DFA B132 mov cl, 32 :::On transforme la chaîne en une 0Ended >:00558DFC E83F9EEAFF call 00402C40 >:00558E01 8D45F0 lea eax, dword ptr [ebp-10] >:00558E04 BA84625800 mov edx, 00586284 >:00558E09 E8CAB0EAFF call 00403ED8 :::edx = Code >:00558E0E 8D85ECFCFFFF lea eax, dword ptr [ebp+FFFFFCEC] >:00558E14 8D95F0FEFFFF lea edx, dword ptr [ebp+FFFFFEF0] >:00558E1A E8B9B0EAFF call 00403ED8 :::*eax = Code >:00558E1F 8B85ECFCFFFF mov eax, dword ptr [ebp+FFFFFCEC] >:00558E25 8D55F8 lea edx, dword ptr [ebp-08] >:00558E28 E81BF9EAFF call 00408748 :::eax = 17h = length(Code) >:00558E2D BB01000000 mov ebx, 00000001 >:00558E32 EB21 jmp 00558E55 > > :::Nettoyage du code > >:00558E34 8B45F8 mov eax, dword ptr [ebp-08] >:00558E37 8A4418FF mov al, byte ptr [eax+ebx-01] >:00558E3B 2C20 sub al, 20 >:00558E3D 7404 je 00558E43 >:00558E3F 2C0D sub al, 0D >:00558E41 7511 jne 00558E54 >:00558E43 8D45F8 lea eax, dword ptr [ebp-08] >:00558E46 B901000000 mov ecx, 00000001 >:00558E4B 8BD3 mov edx, ebx >:00558E4D E826B3EAFF call 00404178 >:00558E52 EB01 jmp 00558E55 > >:00558E54 43 inc ebx > >:00558E55 8B45F8 mov eax, dword ptr [ebp-08] >:00558E58 E8D7B0EAFF call 00403F34 >:00558E5D 3BD8 cmp ebx, eax >:00558E5F 7ED3 jle 00558E34 >:00558E61 8D45F8 lea eax, dword ptr [ebp-08] :::eax = code ss les '-' >:00558E64 BAB08F5500 mov edx, 00558FB0 >...... >...... >:00558EB8 E83BB2EAFF call 004040F8 :::eax=Code :::edx=AVString >:00558EBD 50 push eax >----------------------------------------------- ---------------------- ---------- >:00558EBE E85992F5FF call 004B211C ****Renvoie une erreur de code!! >----------------------------------------------- ---------------------- ---------- >:00558EC3 8945F4 mov dword ptr [ebp-0C], eax >:00558EC6 33C0 xor eax, eax >:00558EC8 5A pop edx >:00558EC9 59 pop ecx >:00558ECA 59 pop ecx >:00558ECB 648910 mov dword ptr fs:[eax], edx >:00558ECE EB0A jmp 00558EDA ***RegUser OK si [00586248]=0 >:00558ED0 E907A6EAFF jmp 004034DC >:00558ED5 E8A6A8EAFF call 00403780 > >:00558EDA 837DF400 cmp dword ptr [ebp-0C], 00000000 :::OK si [00586248]=0 >:00558EDE 7424 je 00558F04 >:00558EE0 C6058462580000 mov byte ptr [00586284], 00 >:00558EE7 8D95ECFCFFFF lea edx, dword ptr [ebp+FFFFFCEC] >:00558EED A130EF5800 mov eax, dword ptr [0058EF30] >:00558EF2 E83DC7EAFF call 00405634 >:00558EF7 8B85ECFCFFFF mov eax, dword ptr [ebp+FFFFFCEC] >:00558EFD E8F2E0FDFF call 00536FF4 >:00558F02 EB3E jmp 00558F42 > >:00558F04 833D4862580000 cmp dword ptr [00586248], 00000000 :::OK si [00586248]=0 >:00558F0B 0F95C2 setne dl >:00558F0E 8B45FC mov eax, dword ptr [ebp-04] >:00558F11 8B80F0160000 mov eax, dword ptr [eax+000016F0] >:00558F17 E83433EDFF call 0042C250 >:00558F1C 6A00 push 00000000 >:00558F1E 8D95ECFCFFFF lea edx, dword ptr [ebp+FFFFFCEC] >:00558F24 A118F35800 mov eax, dword ptr [0058F318] >:00558F29 E806C7EAFF call 00405634 >:00558F2E 8B85ECFCFFFF mov eax, dword ptr [ebp+FFFFFCEC] >:00558F34 668B0DB48F5500 mov cx, word ptr [00558FB4] >:00558F3B B202 mov dl, 02 >:00558F3D E89EBFEFFF call 00454EE0 :::Affiche Reg OK > >:00558F42 33C0 xor eax, eax >:00558F44 5A pop edx >:00558F45 59 pop ecx >:00558F46 59 pop ecx >:00558F47 648910 mov dword ptr fs:[eax], edx > >:00558F4A 68728F5500 push 00558F72 > >:00558F4F 8D85ECFCFFFF lea eax, dword ptr [ebp+FFFFFCEC] >:00558F55 E85EADEAFF call 00403CB8 >:00558F5A 8D45F0 lea eax, dword ptr [ebp-10] >:00558F5D E856ADEAFF call 00403CB8 >:00558F62 8D45F8 lea eax, dword ptr [ebp-08] >:00558F65 E84EADEAFF call 00403CB8 >:00558F6A C3 ret > >On voit donc que l'on peut forcer l'enregistrement de l'utilisateur à Vrai ! > >MAIS MAIS : cela ne ce fait pas complètement car il y a un KeyFile (Ace.KEY) qui n'est pas écrit... > >Pourrait-on forcer cette écriture ? ;-) > >Pourquoi ne pas simplement chercher le flag qui dit Reg OK et le fixé ? > >************************************************* >On étudie de plus près : call 004B211C >************************************************* > >Et l'on fini par arriver dans Ace.Dll avec un décalage de 00250000 à ajouter >(en fct de l'adresse de chargement)(Donc en debug on à :00409C76 qui est :00659C76) > >On a un JMP [005B9B74] = JMP 0066241C > >------------------------------- >Exported Function : ACERegister *** Vu le nom de la fct on ne pouvait pas se tromper ! >------------------------------- >:0041241C 56 push esi >...... >...... >:00412438 83F913 cmp ecx, 00000013 ::: si length(code) < 13h alors >:0041243B 740A je 00412447 >:0041243D B821020000 mov eax, 00000221 ::: ERREUR 221 (mauvais code) >:00412442 E94EFBFFFF jmp 00411F95 > ::: sinon >:00412447 8B7510 mov esi, dword ptr [ebp+10] ::: esi = Code >:0041244A BFCEF04400 mov edi, 0044F0CE >:0041244F 57 push edi > >:00412450 AC lodsb >:00412451 8807 mov byte ptr [edi], al >:00412453 47 inc edi >:00412454 3C00 cmp al, 00 >:00412456 75F8 jne 00412450 >:00412458 5F pop edi :::fin de copie du code ds Edi >:00412459 BE1CDF4400 mov esi, 0044DF1C ::: var globales >:0041245E BFD1DC4400 mov edi, 0044DCD1 >----------------------------------------------- ---------------------- ---------- >:00412463 E80E78FFFF call 00409C76 *** Test du Code >----------------------------------------------- ---------------------- ---------- >:00412468 57 push edi > >:00412469 AC lodsb >:0041246A 8807 mov byte ptr [edi], al >:0041246C 47 inc edi >:0041246D 3C00 cmp al, 00 ::: al = 0 si code OK >:0041246F 75F8 jne 00412469 ::: sinon affiche Code not good >:00412471 5F pop edi >:00412472 A114DF4400 mov eax, dword ptr [0044DF14] >:00412477 E90FFBFFFF jmp 00411F8B > >************************************************* >On étudie de plus près : call 00409C76 >************************************************* > >:00409C76 51 push ecx >:00409C77 52 push edx >:00409C78 56 push esi >:00409C79 57 push edi >----------------------------------------------- ---------------------- ---------- >:00409C7A E8F5FCFFFF call 00409974 :::test du code >----------------------------------------------- ---------------------- ---------- >:00409C7F 833D9813440000 cmp dword ptr [00441398], 00000000 >:00409C86 0F85BD000000 jne 00409D49 ::: ERREUR 221 >:00409C8C 833D86F0440000 cmp dword ptr [0044F086], 00000000 >:00409C93 742D je 00409CC2 >:00409C95 B882F04400 mov eax, 0044F082 >:00409C9A E89BFEFFFF call 00409B3A >:00409C9F 85C0 test eax, eax >:00409CA1 0F84C9000000 je 00409D70 >:00409CA7 C6058EF0440000 mov byte ptr [0044F08E], 00 >:00409CAE E8C8FDFFFF call 00409A7B >:00409CB3 B80C000000 mov eax, 0000000C >:00409CB8 E8B8880000 call 00412575 >:00409CBD E987000000 jmp 00409D49 > >:00409CC2 6A00 push 00000000 >:00409CC4 6805040000 push 00000405 >:00409CC9 6A00 push 00000000 >:00409CCB 6A00 push 00000000 >:00409CCD 68DBD84400 push 0044D8DB >:00409CD2 C6050A24450000 mov byte ptr [0045240A], 00 >:00409CD9 FF15C9DB4400 call dword ptr [0044DBC9] ::: Call 0054823C ds WinAce >:00409CDF 85C0 test eax, eax >:00409CE1 740F je 00409CF2 >:00409CE3 C70598134400FF000000 mov dword ptr [00441398], 000000FF >:00409CED 5F pop edi >:00409CEE 5E pop esi >:00409CEF 5A pop edx >:00409CF0 59 pop ecx >:00409CF1 C3 ret > >************************************************* >On étudie de plus près : call 00409974 >************************************************* > >C'est là que l'on s'amuse ! > >:00409974 53 push ebx >...... >:00409979 C8200000 enter 0020, 00 :::un peu de mémoire locale >:0040997D 8D7DF0 lea edi, dword ptr [ebp-10] >:00409980 BE28104000 mov esi, 00401028 >:00409985 A5 movsd >:00409986 A5 movsd >:00409987 A5 movsd >:00409988 A5 movsd >:00409989 B910000000 mov ecx, 00000010 >:0040998E BED1F04400 mov esi, 0044F0D1 >:00409993 8D7DE0 lea edi, dword ptr [ebp-20] :::esi= code - les 3 1er lettres >:00409996 31C0 xor eax, eax >:00409998 57 push edi >:00409999 F2 repnz >:0040999A A4 movsb >:0040999B 5F pop edi :::fin de copie ds edi en 008FF830 > >:0040999C 8B0D38AB4200 mov ecx, dword ptr [0042AB38] :::"34679ACDEFHKLMNPQRSTWXY" >:004099A2 EB06 jmp 004099AA ::: appelons cette chaîne GrpA >...... >:004099AC EB06 jmp 004099B4 >...... >:004099B4 8A5C28E0 mov bl, byte ptr [eax+ebp-20] :::bl = 1ere lettre >...... >on vérifie si les lettres du Code sont dans le GrpA : "34679ACDEFHKLMNPQRSTWXY" >sinon il y a une erreur : >Donc le code ne peut être composé que de ces lettres là! >...... >:004099C1 83FA17 cmp edx, 00000017 ::: bl pas ds GrpA >:004099C4 75DE jne 004099A4 >:004099C6 C7059813440021020000 mov dword ptr [00441398], 00000221 ::: ERREUR 221 >:004099D0 E950360000 jmp 0040D025 ::: bad Code >....... >si OK on se retrouve avec edi qui pointe sur la liste des index des lettres du code >par rapport à la position ds GrpA (exp : A ds le code donne 05 ds la zone ptée par edi) >....... >Qq calculs sur le code ainsi modifié >....... >:004099E3 6B442AF017 imul eax, dword ptr [edx+ebp-10], 00000017 >:004099E8 83C204 add edx, 00000004 >:004099EB 89442AEC mov dword ptr [edx+ebp-14], eax >:004099EF 83FA0C cmp edx, 0000000C >:004099F2 75EF jne 004099E3 >:004099F4 0FB64429E0 movzx eax, byte ptr [ecx+ebp-20] :::dernière valeur >:004099F9 0145F0 add dword ptr [ebp-10], eax >:004099FC 31C0 xor eax, eax >:004099FE 8B5428F0 mov edx, dword ptr [eax+ebp-10] >:00409A02 83C004 add eax, 00000004 >:00409A05 C1EA18 shr edx, 18 >:00409A08 C64428EF00 mov [eax+ebp-11], 00 >:00409A0D 015428F0 add dword ptr [eax+ebp-10], edx >:00409A11 83F810 cmp eax, 00000010 >:00409A14 74C6 je 004099DC >:00409A16 EBE6 jmp 004099FE >:00409A18 8D45F0 lea eax, dword ptr [ebp-10] >:00409A1B BAE2F04400 mov edx, 0044F0E2 >:00409A20 8D580C lea ebx, dword ptr [eax+0C] >:00409A23 B903000000 mov ecx, 00000003 >:00409A28 89C6 mov esi, eax >:00409A2A 89D7 mov edi, edx >:00409A2C 57 push edi >:00409A2D F2 repnz >:00409A2E A4 movsb >:00409A2F 5F pop edi >:00409A30 83C004 add eax, 00000004 >:00409A33 83C203 add edx, 00000003 >:00409A36 39D8 cmp eax, ebx >:00409A38 75E9 jne 00409A23 >:00409A3A 837DFC00 cmp dword ptr [ebp-04], 00000000 >:00409A3E 7407 je 00409A47 >:00409A40 B801000000 mov eax, 00000001 >:00409A45 EB02 jmp 00409A49 >:00409A47 31D8 xor eax, ebx >:00409A49 BB03000000 mov ebx, 00000003 :::compteur pour un calcul >:00409A4E BACEF04400 mov edx, 0044F0CE :::adrs mémoire >:00409A53 A386F04400 mov dword ptr [0044F086], eax :::init >:00409A58 B8FFFFFFFF mov eax, FFFFFFFF :::init >:00409A5D E87C580000 call 0040F2DE :::Calcul de CRC?? >:00409A62 0FB6C0 movzx eax, al :::on garde AL (doit être = à C3) >:00409A65 A38AF04400 mov dword ptr [0044F08A], eax :::on sauve en mémoire >:00409A6A 89C2 mov edx, eax >:00409A6C B8E2F04400 mov eax, 0044F0E2 :::Adresse >:00409A71 E891DC0000 call 00417707 :::Calcul de CRC?? >:00409A76 E9AA350000 jmp 0040D025 :::on s'en va!!! enfin > >Donc tout ca c'est le calcul de vérif code !! >Quel B....L de M...E !!! > >Ca multiplie, ca décale, ca tourne, ca appel et allons-y ne nous privons pas c'est du Pascal ! >Mais pensez donc à ceux qui regarde ca sous un autre œil ! >En assembleur c'est moins amusant ce genre de chose ! > >Là il y a un choix à faire : > >Soit il y a une routine qui calcule le bon code soit on utilise tjrs cette routine pour vérifier. >Qd le prog se lance il doit vérifier si l'on est inscrit donc si l'on passe ds le coin au démarrage >c'est qu'il y a vérification du code saisie (donc stockage qq part - ds Ace.key pour ceux qui on bien lu)... > >On va qd même vérifier en regardant un peu le code source du prog et des Dlls (Ace.dll)... >A plus tard... > >Bon comme on a trouver la routine de calcul c'est plus simple mais on se balade d'un call à l'autre en >dead listing c'est dur dur. > >Là on arrête tout et on fait une pause kitkat ! >(qq mn plus tard...) > >Soyons plus Zen et réfléchissons un peu : > >Données du pb => une AVstring (username) et un code >Solutions possibles => (il n'y en a pas 36) >1- le username donne un code mémoire qui est comparé à celui saisie ? >2- le username donne un CRC qui est comparé à celui du code saisie ? > >Soluce 1: le code fishing => il doit y avoir ds le prog une comparaison de chaîne >Soluce 2: on fait un (ou plusieurs) calcul(s) avec le username et > un (ou plusieurs) calcul(s) avec le code > ensuite on compare le résultat (généralement un entier)... > >On a vu en 00409974 que le 1er calcul est fait sur le code donc on peut >imaginer qu'il s'agit d'un calcul de CRC ! >On remarque ds le code (:00409A2D et :00409A6C) que le résultat est placé en 0044F0E2. > >Donc on va utiliser une vieille ruse de Sioux : suivre le gibier à la trace ! >On passe donc sous debuger et on surveille la zone mémoire 0044F0E0:0044F0F0 >On prend une zone un peu plus large pour les 1ers tests... > >Petite promenade...Remarque importante on lit/écrit aussi en 0044F080:0044F090 donc >on regarde aussi cette zone mémoire... > >Résultats: > >1°) Calcul de CRC avec le code, écriture en 0044F0E2:0044F0E8 (adrs:00409a2d) >2°) Copie du résultat en 008ff4bc (adrs:00417794) >3°) Copie d'une valeur calculée de 008ff6fc vers 0044F0E2 (adrs:004177ab) >4°) Calcul de CRC avec la AVString (username), écriture en 0044F082 (adrs:00409c45) >5°) Test important 0044F082=0044F0E2 ??? OUI alors le code est bon !!! > >On sait que :0040999C nous indique que les lettres composant le code sont ds >"34679ACDEFHKLMNPQRSTWXY" > > >Un indice on remarque que le CRC calculé en 0040f2de des 3 1eres lettres du code >doit faire eax=??????C3. Un peu de Zen et on se dit que comme ds tous les progs >il doit s'agir des initiales du prog. On fait un test avec "ACE" et c'est gagner!!! > >Il devient maintenant très simple de patcher le code du programme (en mémoire pour tester) >en regardant la zone mémoire de 0044F080:0044F0EF et en répondant aux interrogations du prog ! > > >qqs exemples mais pas tous : il faut aussi que vous travailliez un peu >:00409C7F 833D9813440000 cmp dword ptr [00441398], 00000000 >:00409C86 0F85BD000000 jne 00409D49 ::: devient EB049090 >:00409C8C 833D86F0440000 cmp dword ptr [0044F086], 00000000 >:00409C93 742D je 00409CC2 ::: devient EB2D > >:00409C3D E89C560000 call 0040F2DE >:00409C42 8B55BC mov edx, dword ptr [ebp-44] >:00409C45 8902 mov dword ptr [edx], eax >:00409C47 3B4260 cmp eax, dword ptr [edx+60] >:00409C4A 7521 jne 00409C6D ::: devient 9090 > >:00409C59 E880560000 call 0040F2DE >:00409C5E 8B55BC mov edx, dword ptr [ebp-44] >:00409C61 3A4266 cmp al, byte ptr [edx+66] >:00409C64 7507 jne 00409C6D ::: devient 9090 > >etc... il y a en tout 8 adresses et 17 octets à changer.................. > > >Ceux qui se demandent comment on fait pour savoir si l'on "jump" ou pas doivent >faire un peu plus de "dead listing". On y remarque très bien >si l'on part vers une erreur ou un affichage de msgbox (sinon on test et on prend des notes ;o) > >Ensuite on saisie un Username et un code "ACEDT....DT" et on s'enregistre...Bingo !! >(en fait on peut prendre des lettres ds : "34679ACDEFHKLMNPQRSTWXY") >(Parce Que ca ne sert à rien de mettre des patchs ds tous les coins - > sinon on peut aussi patcher ce test ?-) > >Le fichier Ace.Key est généré et l'utilisateur est le bon et on peut en changer qd on veut ! > >Tous ceci serait très sympa mais d'après vous : Pourquoi avoir Aspacker l'exe et laisser les Dlls en clair ??? >Réponse : Tout simplement car il y a un test de validité de la Dll dans le prog !!! > >Donc on peut tjrs utiliser un patcher mémoire ou trouver la routine de control et la modifier (tjrs patch mémoire) >on peut aussi garder le prog unAspaked (on l'a fait au début) et le patcher en direct ! > >IL Y A AUSSI UNE AUTRE SOLUTION : (moins élégante) >Une version de la Dll pathée et une non patchée. On utilise une fois la Dll patchée pour l'enregistrement >ensuite on utilise la classique. Comme ca pas besoin de unAspack ni de patcher mémoire... > >Mais on doit pouvoir faire mieux : > >************************************************* >Etudions la routine de contrôle de la Dll : >************************************************* > >En première réflexion on pense à un calcul de CRC sur la Dll (un octet de modifié et hop perdu !!) >Ensuite on peut imaginer qu'il y a un test des octets cruciaux (un octet de modifié et hop perdu !!) > >Comment le savoir me direz-vous : Très simple on prend la Dll et on modifie un octet très en dehors des "zones sensibles"... Si un message s'affiche => c'est un CRC sur le fichier complet !! > >Résultat : On cherche un texte ds la Dll et on le modifie => ERREUR de Dll !!! > >On a donc un CRC sur toute la Dll. On ne peut donc rien modifier même en équilibrant le poids des octets. > >Il y a d'autre possibilité de tester le code : >- somme des octets (contournable par équilibrage du code) >- somme des octets pondérée (octet1*1 + ... + octet9*9 + octet10*1 + ... + octet19*9) >- Vérification du nombre de NOP (Au lieu de mettre 2 NOP on met un DEC + un INC) >- Etc... > >Une chose à faire si vous ne maîtrisez pas les CRC : aller sur le Web et trouver des codes sources de routines de calcul de CRC (freeWare). Vous apprendrez comment en 2 ou 3 ligne de prog on fait une solide vérification. Vous remarquerez qu'il y a un tableau d'entiers 32 bits qui est utilisé (intéressant à chercher avec un Editeur hexa). Vous apprendrez que l'entier recevant le résultat est initialisé à FFFFFFFF au début du calcul. Ensuite vous compilez le code source et vous en étudiez l'assembleur cela vous donne une idée du type d'instructions utilisées (shr résult..xor index..shl index..xor résu,tableau[index])... >Juste avec ces infos vous pouvez trouver la routine de calcul ds le prog ;o)) > >Calculons les CRCs de la Dll correcte => E0/chk8 22E0/chck16 0092/crc16 56BF/ccitt DEC8F3A0/crc32 (valeur en complément à 1) >Pour ceux qui ne manient pas les calculs : HexWorkShop fait ca très bien ! >ATTENTION : Suivant les algos on trouve des valeurs à +/- 1. > >On gardera en mémoire la valeur D3C8F3A0 qui est un CRC32 (bien ds le style du prog) >Là il y a plusieurs voies possibles : >- recherche en dead listing d'une routine de calcul de CRC (facile) >- recherche en dead listing d'un test sur la valeur du CRC (il faut de la chance) >- live Debug et recherche de lecture du fichier (ace.dll) >(les tables d'imports non pas étaient régénérées => pas de trace facile en Dead Listing - ca reste faisable) > >Supposition : Au feeling on va dire qu'il y a ouverture du fichier, lecture et comptage... >Donc cherchons les ouvertures de fichiers. > >Plaçons les pts d'arrêts sur : CreateFileA, ReadFile, LoadLibraryA >(pour faire la différence avec le chargement de Ace.Dll) > >INFO: Avec ces routines le nom du file sera ds EDI. > >On tombe sur : > >1°) CreateFileA pour Ace.Dll >2°) ReadFile pour Ace.Dll ( bon début ) >3°) On trace en pas à pas ( on passe qd même au dessus des routines ) > On regarde les Registres.. >4°) Tient en retour de fonction EAX=DEC8F3A0 !!!!!! Ca nous dit qq chose cette valeur. > (On vient donc de passer la routine de calcul du CRC) >5°) On continue en prenant des notes sur les adresses d'exécution... >6°) Tient cmp EAX, DEC8F3A0 !!!! Joli test de CRC valide > si OK alors EAX=0 et Ret >7°) He hop : test AL, AL si OK alors goto somewhere... > >Voilà, voilà : Donc plusieurs possibilités => > >1°) On remplace la valeur DEC8F3A0 par celle du CRC32 de la DLL modifiée (215EC681) >2°) On force la comparaison par un mov EAX,00000000 >3°) On force le test AL par un Jump SomeWhere > >************************************************* >Etudions la façon de placer les modifications : >************************************************* > >1°) On change ds la Dll (pas de problème particuliers) >2°a) On patch l'exe décompressé simple et efficace >2°b) On ajoute du code au prog compressé pour faire un patch mémoire de l'exe ! > >Regardons cette solution 2°b : > >Où, quand, comment et pourquoi ???? > >1°) OU : Simplement là où il y a de la place ds le code ;)) >On va prendre le PE header du prog compressé (ProcDump, Hiew...) et l'on regarde les sections. >La plus sympa est .aspack on voit qu'elle a une taille physique < à la taille virtuelle (alignement de code) > donc on se dit qu'il y a de la place par là. >Pour en être sur on regarde et l'on voit que le prog ne passe pas 00649BFF en adresse alors que l'on voulait justement écrire entre 00649C000 et 00649FFF ! ! ! >(Adrs = Image (00400000) + VirtualOffset (00248000) + PhysiqSize (1C000) = 00649C000) >Mais on remarque qu'il y a pas mal de 00 après 00649B11 donc un petit test en lecture/écriture >mémoire va nous dire si le programme se sert de cette zone mémoire. >Réponse NON donc on peut utiliser cet espace pour mettre du code machine ! > >2°) QUAND : Simplement quand le compacteur a fini son travail ;)) >Nous avons vu au départ (lors de la phase de Dump) que la fin du travail se situe en 006484CC >en remontant un peu on voit MOV [adrs], EAX voilà un bel endroit pour détourner l'attention du programme >et le modifier qq peu (car EAX contient le point d'entré du prog décompressé). > >0177:006484B3 5B POP EBX >0177:006484B4 0BDB OR EBX,EBX >0177:006484B6 89855C2E4400 MOV [EBP+00442E5C],EAX (EAX=EntryPt) >0177:006484BC 61 POPAD >0177:006484BD 7508 JNZ 006484C7 >0177:006484BF B801000000 MOV EAX,00000001 >0177:006484C4 C20C00 RET 000C >0177:006484C7 6800000000 PUSH 00000000 (le pt d'entré est placé ici) > > >2°) COMMENT : Bonne question ;)) >En 006484B6 on va faire un JUMP 00649B20 et à cette adresse nous allons placer >le code manquant pour une bonne étude du programme... > >006484B6 JMP 00649B20 : Adresse du patch >... >00649B20 MOV BYTE PTR [Adrs1],EB >00649B27 MOV BYTE PTR [Adrs2],EB >00649B2E MOV [EBP+00442E5C],EAX on écrit le point d'entré >00649B35 JMP 006484BC On retourne d'où on vient... > >He voilà on lance le prog original (un peu modifié) et tout va bien on peut s'enregistrer, >changer qd on veut de nom utilisateur et bénéficier de l'ensemble des fonctions... > > >*********************************************************************** >Voilà donc les secrets de la protection de WinAce 8-) >Bon prog, tout n'est pas l'un en dessous de l'autre, >on a une bonne segmentation du code qui balade bien le cracker de base... >Le checksum et le prog Aspaked compliquent un peu les choses... >Une bonne surprise pour un shareWare bien sympa ! > >- MAIS comme tjrs avec un peu de Zen on arrive au bout ! >Pour ceux qui se demandent comment être ZEN ? >Réponse : Faite une pose de temps à autre, ayez l'esprit clair... >Ensuite devant un problème particulier demandez-vous comment vous auriez >programmé cela. Si vous êtes bon le prog sera certainement comme vous le pensez ! > >Pour la prochaine fois : LE KEYGEN >donc on bosse ses math asm... >*********************************************************************** > > >Pour ceux qui se demandent pourquoi il n'y a pas toutes les adresses à patcher ? >Réponse : Le tutorial est fait pour apprendre pas pour faire un crack en direct ! >Avec ce tut pour faire un crack il vous faudra travailler un peu, vous avez le chemin >à suivre, la technique à utiliser, il ne vous reste plus qu'à pratiquer ! > > > >PAS DE SITE PAS D'ADRESSE EMAIL : >Question ? => posez-les sur les forums français... > >////////////////////////////////////////////////////////////////////////// /// >Comme toujours : >////////////////////////////////////////////////////////////////////////// /// >VOUS NE DEVEZ PAS UTILISER CE COURS POUR OBTENIR ILLEGALEMENT DES PROGRAMMES. >IL DOIT JUSTE SERVIR A VOTRE EDUCATION. >AVOIR CE COURS EST LEGAL MAIS L'APPLIQUER NE L'EST PAS !!! >////////////////////////////////////////////////////////////////////////// ///