Cracking Turorial #5

Това е  петия урок по кракване от ^Shade^.Всичко е обяснено много просто и елементарно.Необходимо е само да прочетете страницата до край.Но не си мислете че сте вече Кракери като сте прочели само тази страница.

В този урок ще кракнем едно  CrackMe което трябва да изтеглите от тук.

Принадлежности:

SoftIce Можете да го изтеглите от http://freak-inc.hit.bg/Download.htm
Win32dasm Можете да го изтеглите от http://freak-inc.hit.bg/Download.htm
HexWorkshop Можете да го изтеглите от http://freak-inc.hit.bg/Download.htm

Когато се занимавате с кракване трябва задължително да си правите резервни копия.Аз си правя файлове .bak .
Първо включете Crackme-то и го разгледайте.Какво забелиязвате ?По всичко личи че ще трябва да го кейгенваме.

Първо го дисасемлирайте с Win32Dasm.След това както винаги щракнете 'String References'.Веднага забялязвме "Thank you for support :)" и "You have entered invalid registration".Избираме 2ия.
Какво виждаме тука:

<---------------------------------------------------------------------------------------------------------------------------->
* Reference To: USER32.SendDlgItemMessageA, Ord:0000h
|
:004011B3 E81A010000 Call 004012D2
:004011B8 8B15E0224000 mov edx, dword ptr [004022E0]
:004011BE FFD2 call edx 
:004011C0 E89F000000 call 00401264
:004011C5 85C0 test eax, eax
:004011C7 7407 je 004011D0                         //jump-ва към съобщение,че сме въвели невалиден номер ако eax!=0

* Possible StringData Ref from Data Obj ->"Thank you for support :)"
|
:004011C9 BB50204000 mov ebx, 00402050
:004011CE EB05 jmp 004011D5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011C7(C)
|

* Possible StringData Ref from Data Obj ->"You have entered invalid registration "
->"number."
|
:004011D0 BB04204000 mov ebx, 00402004
<---------------------------------------------------------------------------------------------------------------------------->
Добре виждаме условния jump на адрес 4011C7.Можем да го пачнем и да го направим от JE на JNE но вова не ни е целта.Нашата цел е да разберем какъв е правилния сериен номер на даден NAME !!
Преди този условен JMP има Call 40011C0 , в който по всичко личи че се извършва сравнението на серийните номера.

**Важно: Слагайки Breakpoint за  GetDlgItemTextA това ще стане много бързо и лесно,но после ще трябва малко F10 докато стигнем до call-а  на адрес 4011C0**

Сега въведете NAME и SERIAL във CrackMe-то.
Аз например въведох : Name --->Shade
                                           Serial --->123456789

Сега натиснете ОК.SI се включва на нашия Breakpoint...Сега натиснете F11 и сме вече в CrackMe-то.
Сега натискайте F10  докато стигнете адреса на 'call 4011C0' и след това влезте в call-а с  F9.

Това което виждаме е :
:00401264 33DB xor ebx, ebx //ebx=0
:00401266 8B0DD7224000 mov ecx, dword ptr [004022D7] //Премества големината на серийния номер в ecx
:0040126C BE6B224000 mov esi, 0040226B //Премества указателя за серийния номер в ESI
:00401271 83E000 and eax, 00000000 
:00401274 51 push ecx 
:00401275 8A06 mov al, byte ptr [esi] //Премества 1ия знак от серийния номер в AL
:00401277 3C39 cmp al, 39 //Сравнява го с 39
:00401279 7E04 jle 0040127F //Ако е по малко или равно jmp 004127F
:0040127B 2C27 sub al, 27 //Иначе изважда му изважда 27(AL=AL-27)
:0040127D 0C20 or al, 20  //AL=AL OR 20 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401279(C)
|
:0040127F 2C30 sub al, 30 //Изважда 30 от AL(AL=AL-30)
:00401281 46 inc esi //Прибавя 1 към ESI(ESI=ESI+1) ****Указателя ня серийния номер беше е ESI
:00401282 83E901 sub ecx, 00000001 //Вади от ECX 1(ECX=ECX-1) **** Указателя на големината на серийния номер в ecx
:00401285 6BC904 imul ecx, 00000004 //Умножава ECX с 4(ECX=ECX*4)
:00401288 D3E0 shl eax, cl // (EAX=EAX Shl CL)
:0040128A 03D8 add ebx, eax //ebx=ebx+eax
:0040128C 59 pop ecx
:0040128D E0E2 loopnz 00401271 
:0040128F 33C0 xor eax, eax //EAX=EAX XOR EAX
:00401291 33D3 xor edx, ebx //EDX=EDX XOR EBX
:00401293 81FAAB0CAD0D cmp edx, 0DAD0CAB //Сравнява EDX със 0DAD0CAB
:00401299 7501 jne 0040129C //JMP ако са различни
:0040129B 40 inc eax 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401299(C)
|
:0040129C C3 ret

Големината на серийния номер е поставена в ecx.
Серийния номер е поставен в esi (Може да го видим като напишем : d esi)
На адрес 401275 се премества първия символ от серийния номер.После се конвертва от ascii в decimal
На адрес 401282 вождаме че от от ECX се озважда 1,след тоето резултата се умножава с 4.
След това eax е  shift-нат наляво с cl.
След това eax е add-нат към ebx

Най-важното

На address 401291 виждаме че edx е XOR-нат с ebx, и после е сравнен с 0DAD0CAB.
В EDX е  (калкулацията от NAME) който е  пресметнат от името на в call-а на адрес 4011BE. За да ни напише че сме въвели правилния сериен номер трябва калкулацията на серийния номер до тук  XOR'нат с EBX (calc. от нашия NAME) би трябвал да е  0DAD0CAB . Но ние сме въвели грешен сериен номер и няма да ни напише че серийния номер ни е правилен.

serial XOR (калкулацията от NAME) = 0DAD0CAB
? XOR ?(калкулацията от NAME) = 0DAD0CAB
Резултатът от калкулацията се съдържа на 

:00401291 33D3 xor edx, ebx //EDX=EDX XOR EBX
 в регистъра EDX
=> нашия сериен номер сте бъде равен на 0DAD0CAB/EDX(:00401291 33D3 xor edx, ebx //EDX=EDX XOR EBX)

Надявам се че всичко е точно и ясно.Ако нещо не сте разбрали ми пишете на sashoo@abv.bg .Чао за сега.