--Softice Tutorial--- Date written: 3.5.2001 Program Details: Name: CoDe_InSide CracMe 13 Author: Bengaly Tools Used: Softice Rank: easy[X+] medium[ ] hard[ ] ____________________________________________________________________________________________ -About this protection system- Protection which based on name/serial protection. (my fav) ;D _____________________________________________________________________________________________ The Essay As this is a tutorial for more advanced newbies, I'll go into details about how I go about cracking the program. I suggest that you read this tutorial first. When you have completed the tutorial, leave this tutorial open and follow the instructions. Re-do it once more after you have completed the step by step guide... In this essay, when I write type "? EAX" or similar commands in Softice, I mean it without the quotes. _____________________________________________________________________________________________ Lets Crack The Bitch ;) Ok, again i have decided to crack another Great CrackMe by the Insane Opcode's Coder : "CoDe_InSide"..;D..so let's rock. ok, open crackme, there is 2 textA fields..enter name + serial. i enter: name: bengaly serial: 123456789 now Popup SoftIce..we will use Bpx GetDlgItemTextA breakpint. now after bpx press f5/ctrl+d..to go back to our crackme..press "REGISTER" button, softice will pop up..press f5 to read the "fake serial" textA field. then press 12. we will land here: * Reference To: USER32.GetDlgItemTextA, Ord:0000h ; fake serial textA field | :0040109C FF155C1D4000 Call dword ptr [00401D5C] ; get input for user :004010A2 5D pop ebp ; load ebp from memory :004010A3 A3D81E4000 mov dword ptr [00401ED8], eax ; eax = lengh of fake serial :004010A8 33C0 xor eax, eax ; eax = 0 :004010AA 33C9 xor ecx, ecx ; ecx = 0 :004010AC 33D2 xor edx, edx ; edx = 0 :004010AE 33DB xor ebx, ebx ; ebx = 0 :004010B0 BF001F4000 mov edi, 00401F00 ; fake name move to edi :004010B5 BE00184000 mov esi, 00401800 ; esi holds 401800 ok so this part of not hard ;D now..we need to know where is our serial is generated...so let's find the algo scheme and then we can find the adress of real serial. Open up W32ASM dissasmble the crackme..and save it as txt file. Open up the txt file in txr-editor (notepad)..not look for the code i have pasted u above..found it?? good..now..we scrool alottle little down untill here: * Reference To: USER32.GetDlgItemTextA, Ord:0000h | :0040109C FF155C1D4000 Call dword ptr [00401D5C] ; call input textA (begin of algo) ok from this code (above) this is the actual Algo schem wich used to create our real serial and to compare it to our fake one. in order to know where is real serial is generated..i will explain the algo and i will show u where is the actual generating adress ;D but before we can get to the algo adresses (where the real serial is generated), we cross loops, a long loops..so either u can bpx on adress after loops, or keep pressing 10 (trace) to be on the correct adress...took like 2-5min of tracing :/ . *note: the algo is very long so keep and eye of what's going on. [ALGO SCHEME]: -------------- * Reference To: USER32.GetDlgItemTextA, Ord:0000h <= api of textA field | :0040109C FF155C1D4000 Call dword ptr [00401D5C] ; call input textA :004010A2 5D pop ebp ; load ebp :004010A3 A3D81E4000 mov dword ptr [00401ED8], eax ; serial/name? move to eax :004010A8 33C0 xor eax, eax ; eax = 0 :004010AA 33C9 xor ecx, ecx ; ecx = 0 :004010AC 33D2 xor edx, edx ; edx = 0 :004010AE 33DB xor ebx, ebx ; ebx = 0 :004010B0 BF001F4000 mov edi, 00401F00 ; 401F00 move to edi :004010B5 BE00184000 mov esi, 00401800 ; 401800 move to esi :004010BA 0FBE07 movsx eax, byte ptr [edi] ; move byte in edi to eax :004010BD 8BD8 mov ebx, eax ; eax move to ebx :004010BF 240F and al, 0F ; 0F AND al :004010C1 0FBE4F01 movsx ecx, byte ptr [edi+01] ; byte of [edi+1] move to ecx :004010C5 85C9 test ecx, ecx ; is ecx = ecx?? :004010C7 7503 jne 004010CC ; no?? then jump :004010C9 80C141 add cl, 41 ; 41 + cl :004010CC 8BD1 mov edx, ecx ; ecx move to edx :004010CE 23C8 and ecx, eax ; eax AND ecx :004010D0 92 xchg eax,edx ; exchange edx with eax :004010D1 24F0 and al, F0 ; F0 AND ak :004010D3 23D8 and ebx, eax ; eax AND ebx :004010D5 0BDA or ebx, edx ; edx OR ebx :004010D7 33D2 xor edx, edx ; edx = 0 :004010D9 0C0F or al, 0F ; 0F OR al :004010DB 80C141 add cl, 41 ; 41 (A) + cl :004010DE 23C3 and eax, ebx ; ebx AND eax :004010E0 8806 mov byte ptr [esi], al ; al move to esi (1 byte) :004010E2 46 inc esi ; esi + 1 :004010E3 880E mov byte ptr [esi], cl ; cl move to esi (1 byte) :004010E5 46 inc esi ; esi + 1 :004010E6 47 inc edi ; edi + 1 :004010E7 803F00 cmp byte ptr [edi], 00 ; compare edi (byte) with 00 " :004010EA 75CE jne 004010BA ; not equal?? jump :004010EC 33C0 xor eax, eax ; eax = 0 :004010EE 91 xchg eax,ecx ; exchange ecx with eax :004010EF 33C0 xor eax, eax ; eax = 0 :004010F1 92 xchg eax,edx ; exchange edx with eax :004010F2 33C0 xor eax, eax ; eax = 0 :004010F4 93 xchg eax,ebx ; exchange ebx with eax :004010F5 33C0 xor eax, eax ; eax = 0 :004010F7 BF001F4000 mov edi, 00401F00 ; 01F00 move to edi :004010FC A1D01E4000 mov eax, dword ptr [00401ED0] ; serial/name? move to eax :00401101 01C7 add edi, eax ; edi + eax :00401103 33C0 xor eax, eax ; eax = 0 :00401105 4F dec edi ; edi - 1 :00401106 0FBE07 movsx eax, byte ptr [edi] ; 1 byte of edi move to eax :00401109 8BD8 mov ebx, eax ; eax move to ebx :0040110B 240F and al, 0F ; 0F AND al :0040110D 01C0 add eax, eax ; eax + eax :0040110F 2BD8 sub ebx, eax ; ebx - eax :00401111 0FBE4FFF movsx ecx, byte ptr [edi-01] ; 1 byte of [edi-01) move to ecx :00401115 85C9 test ecx, ecx ; is ecx = ecx?? :00401117 7503 jne 0040111C ; no?? then jump :00401119 80E9BE sub cl, BE ; cl - BE :0040111C 8BD1 mov edx, ecx ; ecx move to edx :0040111E 8BC3 mov eax, ebx ; ebx move to eax :00401120 23C2 and eax, edx ; edx AND eax :00401122 3C5A cmp al, 5A ; is al = 5A? :00401124 7202 jb 00401128 ; no?? jump if below :00401126 8BC3 mov eax, ebx ; ebx move to eax :00401128 13C2 adc eax, edx ; add carry edx with eax :0040112A 1BD0 sbb edx, eax ; Subtract with Borrow/Carry eax from edx :0040112C 8BC1 mov eax, ecx ; move eax to eax :0040112E 23C2 and eax, edx ; edx AND eax :00401130 240F and al, 0F ; 0F AND al :00401132 01D8 add eax, ebx ; add ebx to eax :00401134 33DB xor ebx, ebx ; ebx = 0 :00401136 91 xchg eax,ecx ; exchange ecx with eax :00401137 93 xchg eax,ebx ; exchange ebx with eax :00401138 91 xchg eax,ecx ; ecxhange ecx with eax :00401139 0FBE0F movsx ecx, byte ptr [edi] ; 1 byte of edi move to ecx :0040113C 23CB and ecx, ebx ; ebx AND ecx :0040113E 33DB xor ebx, ebx ; ebx = 0 :00401140 33D2 xor edx, edx ; edx = 0 :00401142 8806 mov byte ptr [esi], al ; 1 byte of esi move to al :00401144 46 inc esi ; esi + 1 :00401145 880E mov byte ptr [esi], cl ; 1 byte of esi move to cl :00401147 46 inc esi ; esi + 1 :00401148 4F dec edi ; edi - 1 :00401149 803F00 cmp byte ptr [edi], 00 ; compare 1 byte of edi with 00 :0040114C 75B8 jne 00401106 ; not " " jump :0040114E BF00184000 mov edi, 00401800 ; 401800 move to edi :00401153 0FBE07 movsx eax, byte ptr [edi] ; 1 byte of edi move to eax :00401156 244F and al, 4F ; 4F (O) AND al :00401158 0C41 or al, 41 ; 41 (A) OR al :0040115A 8807 mov byte ptr [edi], al ; 1 byte of edi move to al :0040115C 47 inc edi ; edi + 1 :0040115D 803F00 cmp byte ptr [edi], 00 ; compare 1 byte of edi with 00 :00401160 75F1 jne 00401153 ; not " " jump :00401162 97 xchg eax,edi ; exchange edi with eax :00401163 B000 mov al, 00 ; 00 (" ") move to al :00401165 97 xchg eax,edi ; exchange edi with eax :00401166 0FBE07 movsx eax, byte ptr [edi] ; 1 byte of edi move to eax :00401169 0FBE4F01 movsx ecx, byte ptr [edi+01] ; 1 byte of [edi+1] move to ecx :0040116D 85C9 test ecx, ecx ; is ecx = ecx? :0040116F 7503 jne 00401174 ; no?? jump else continue :00401171 80C141 add cl, 41 ; add 41 (A) to cl :00401174 8BD8 mov ebx, eax ; eax move to ebx :00401176 8BD1 mov edx, ecx ; ecx move to edx :00401178 23C2 and eax, edx ; edx AND eax :0040117A 23CB and ecx, ebx ; ebx AND ecx :0040117C 0BC3 or eax, ebx ; ebx OR eax :0040117E 0BCA or ecx, edx ; edx OR ecx :00401180 884701 mov byte ptr [edi+01], al ; 1 byte of [edi+1] move to al :00401183 880F mov byte ptr [edi], cl ; 1 byte of edi move to cl :00401185 47 inc edi ; edi + 1 :00401186 47 inc edi ; edi - 1 :00401187 803F00 cmp byte ptr [edi], 00 ; compare 1 byte of edi with 00 :0040118A 75DA jne 00401166 ; no?? then jump else continue :0040118C BE00184000 mov esi, 00401800 ; 401800 (serial) move to esi :00401191 33D2 xor edx, edx ; edx = 0 :00401193 33DB xor ebx, ebx ; ebx = 0 :00401195 8BC7 mov eax, edi ; edi move to eax :00401197 50 push eax ; save eax :00401198 8B06 mov eax, dword ptr [esi] ; move esi (serial?) to eax :0040119A 83C604 add esi, 00000004 ; esi + 4 :0040119D 8AD8 mov bl, al ; bl holds al :0040119F C1E808 shr eax, 08 ; shift right 08 in eax :004011A2 8AD0 mov dl, al ; dl holds al :004011A4 C1E808 shr eax, 08 ; shift right 08 in eax :004011A7 8AC8 mov cl, al ; cl holds al :004011A9 C1E808 shr eax, 08 ; shift right 08 in eax :004011AC 50 push eax ; save eax :004011AD 51 push ecx ; save ecx :004011AE 52 push edx ; save edx :004011AF 53 push ebx ; save ebx :004011B0 23C3 and eax, ebx ; ebx AND eax :004011B2 23C2 and eax, edx ; edx AND eax :004011B4 23C1 and eax, ecx ; ecx AND eax :004011B6 2BC8 sub ecx, eax ; eax - ecx :004011B8 2BD0 sub edx, eax ; eax - edx :004011BA 2BD8 sub ebx, eax ; eax - ebx :004011BC 58 pop eax ; load eax :004011BD 58 pop eax ; load eax :004011BE 58 pop eax ; load eax :004011BF 58 pop eax ; load eax :004011C0 93 xchg eax,ebx ; exchange ebx with eax :004011C1 91 xchg eax,ecx ; exchange ecx with eax :004011C2 92 xchg eax,edx ; exchange edx with eax :004011C3 91 xchg eax,ecx ; exchange ebx with eax :004011C4 93 xchg eax,ebx ; exchange ebx with eax :004011C5 92 xchg eax,edx ; exchange edx with eax :004011C6 91 xchg eax,ecx ; exchange ecx with eax :004011C7 91 xchg eax,ecx ; exchange ecx with eax :004011C8 0C41 or al, 41 ; 41(A) OR al :004011CA 91 xchg eax,ecx ; exchange ecx with eax :004011CB 92 xchg eax,edx ; exchange edx with eax :004011CC 0C41 or al, 41 ; 41(A) OR al :004011CE 92 xchg eax,edx ; exchange edx with eax :004011CF 93 xchg eax,ebx ; exchange ebx with eax :004011D0 0C41 or al, 41 ; 41(A) OR al :004011D2 93 xchg eax,ebx ; exchange ebx with eax :004011D3 0C41 or al, 41 ; 41(A) OR al :004011D5 C1E008 shl eax, 08 ; shift left 08 in eax :004011D8 0AC1 or al, cl ; cl OR al :004011DA C1E008 shl eax, 08 ; shift left 08 in eax :004011DD 0AC3 or al, bl ; bl OR al :004011DF C1E008 shl eax, 08 ; shift left 08 in eax :004011E2 0AC2 or al, dl ; dl OR al :004011E4 8907 mov dword ptr [edi], eax ; move eax into edi (4 bytes?) :004011E6 83C704 add edi, 00000004 ; edi + 4 :004011E9 33C9 xor ecx, ecx ; ecx = 0 :004011EB 33D2 xor edx, edx ; edx = 0 :004011ED 33DB xor ebx, ebx ; ebx = 0 :004011EF 58 pop eax ; load eax :004011F0 3BC6 cmp eax, esi ; compare esi with eax <= serial :004011F2 75A3 jne 00401197 ; not equal jump to begginnig of algo else continue :004011F4 33C0 xor eax, eax ; eax = 0 :004011F6 BF001F4000 mov edi, 00401F00 ; 401F00 moves to edi :004011FB A1D01E4000 mov eax, dword ptr [00401ED0] ; 00401ED0 (name/serial) move to eax :00401200 01C7 add edi, eax ; eax + edi :00401202 4F dec edi ; edi - 1 :00401203 33C0 xor eax, eax ; eax = 0 :00401205 0FBE07 movsx eax, byte ptr [edi] ; move (byte) of edi to eax :00401208 03D0 add edx, eax ; eax + edx :0040120A 0FAFC8 imul ecx, eax ; eax * ecx :0040120D 01C1 add ecx, eax ; eax + ecx :0040120F 4F dec edi ; edi - 1 :00401210 803F00 cmp byte ptr [edi], 00 ; compare edi (byte) with " " :00401213 75F0 jne 00401205 ; not equal..jump :00401215 0FAFCA imul ecx, edx ; edx * ecx :00401218 91 xchg eax,ecx ; exchange ecx with eax :00401219 0FC8 bswap eax ; byte swap eax :0040121B 3C00 cmp al, 00 ; compare al with " " :0040121D 7503 jne 00401222 ; not equal..jump :0040121F 0FAFC2 imul eax, edx ; edx * eax :00401222 0FC8 bswap eax ; byte swap eax :00401224 BF00184000 mov edi, 00401800 ; 00401800 move to edi :00401229 BE00154000 mov esi, 00401500 ; 00401500 move to esi :0040122E 0FBE0F movsx ecx, byte ptr [edi] ; edi (byte) move to ecx :00401231 47 inc edi ; edi + 1 :00401232 0FAFC1 imul eax, ecx ; ecx * eax :00401235 3587654321 xor eax, 21436587 ; eax xor 21436587 :0040123A 8BD0 mov edx, eax ; eax move to edx :0040123C 254F4F4F4F and eax, 4F4F4F4F ; eax AND 4F4F4F4F :00401241 0D41414141 or eax, 41414141 ; eax OR 41414141 :00401246 8906 mov dword ptr [esi], eax ; eax move to esi (4 bytes?) :00401248 83C604 add esi, 00000004 ; esi + 4 :0040124B 8BC2 mov eax, edx ; edx move to eax :0040124D 803F00 cmp byte ptr [edi], 00 ; compare edi (byte) with " " :00401250 75DC jne 0040122E ; not equal..jump :00401252 33C0 xor eax, eax ; eax = 0 :00401254 33D2 xor edx, edx ; edx = 0 :00401256 BF00154000 mov edi, 00401500 ; 00401500 move to edi :0040125B BE001C4000 mov esi, 00401C00 ; 00401C00 move to esi :00401260 A1D01E4000 mov eax, dword ptr [00401ED0] ; 4 bytes of 401ED0 move to eax :00401265 93 xchg eax,ebx ; exchange ebx with eax :00401266 33C9 xor ecx, ecx ; ecx = 0 :00401268 8B045F mov eax, dword ptr [edi+2*ebx]; 4 bytes of (edi+2*ebx) move to eax :0040126B 0FC8 bswap eax ; byte swap eax :0040126D 8BD0 mov edx, eax ; eax move to edx :0040126F 8BC8 mov ecx, eax ; eax move to ecx :00401271 81E100FF0000 and ecx, 0000FF00 ; 0000FF00 AND eax :00401277 81E2000000FF and edx, FF000000 ; FF000000 AND edx :0040127D 81E0FF000000 and eax, 000000FF ; 000000FF AND eax :00401283 C1E008 shl eax, 08 ; shift left 08 in eax :00401286 C1E908 shr ecx, 08 ; shift right 08 in ecx :00401289 C1EA18 shr edx, 18 ; shift right 18 in edx :0040128C 01C8 add eax, ecx ; ecx + eax :0040128E 01D0 add eax, edx ; edx + eax :00401290 C1E808 shr eax, 08 ; shift right 08 in eax :00401293 244F and al, 4F ; 4F (O) AND al :00401295 0C41 or al, 41 ; 41 (A) OR al :00401297 83C704 add edi, 00000004 ; edi + 4 :0040129A 0FB006 cmpxchg byte ptr [esi], al ; comapre and exchange al with byte of esi <= serial? :0040129D 7408 je 004012A7 ; is it ok?? jump to good boy :0040129F 6A01 push 00000001 ; save 1 (true??..nope) :004012A1 46 inc esi ; esi + 1 (next char) :004012A2 4B dec ebx ; ebx - 1 :004012A3 75C3 jne 00401268 ; mov eax, dword ptr [edi+2*ebx] :004012A5 EB06 jmp 004012AD ; call api Long eh??..yes it is long and somehow can be confusing...well it is..first time i tried it i didn't find the adress and the right cmopare..but good old CoDe_InSide gave me some good directions. ok..u noticed that the algo uses alot of xchg command..to change registers values... but close look at the end of our algo will show us this part: ------------------------------------LOOP--------------------------------------------------------- :0040126B 0FC8 bswap eax ; byte swap eax :0040126D 8BD0 mov edx, eax ; eax move to edx :0040126F 8BC8 mov ecx, eax ; eax move to ecx :00401271 81E100FF0000 and ecx, 0000FF00 ; 0000FF00 AND eax :00401277 81E2000000FF and edx, FF000000 ; FF000000 AND edx :0040127D 81E0FF000000 and eax, 000000FF ; 000000FF AND eax :00401283 C1E008 shl eax, 08 ; shift left 08 in eax :00401286 C1E908 shr ecx, 08 ; shift right 08 in ecx :00401289 C1EA18 shr edx, 18 ; shift right 18 in edx :0040128C 01C8 add eax, ecx ; ecx + eax :0040128E 01D0 add eax, edx ; edx + eax :00401290 C1E808 shr eax, 08 ; shift right 08 in eax :00401293 244F and al, 4F ; 4F (O) AND al :00401295 0C41 or al, 41 ; 41 (A) OR al :00401297 83C704 add edi, 00000004 ; edi + 4 :0040129A 0FB006 cmpxchg byte ptr [esi], al ; comapre and exchange al with byte of esi <= serial? :0040129D 7408 je 004012A7 ; is it ok?? jump to good boy :0040129F 6A01 push 00000001 ; save 1 (keep save untill true) :004012A1 46 inc esi ; esi + 1 (next char) :004012A2 4B dec ebx ; ebx - 1 :004012A3 75C3 jne 00401268 ; mov eax, dword ptr [edi+2*ebx] ---------------------------------------ENDD LOOP------------------------------------------------- :004012A5 EB06 jmp 004012AD ; call api this code is a Loop..how did i knew it's a loop look at adress 004012A3..there is a jump to 401268 which is the begginig of the loop (real serial creation loop). ok..so we got alot of xchng in our algo..so if u loop at the serial creation loop (see above) we can see a little instrucion: cmpxchg (compare any changes), this is very good..a cmp instruction..and a je/jne instructions after it..that means we are at the right place ;D now be at adress 0040129A (cmpxchg byte ptr [esi], al) in softice (after 3-5 min of tracing), if we will press: D ESI.. we will get this: 017F:00401C00 31 32 33 35 34 36 37 38-39 00 00 00 00 00 00 00 123546789....... ; fake serial 017F:00401C10 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 017F:00401C20 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 017F:00401C30 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 017F:00401C40 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 017F:00401C50 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 017F:00401C60 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 017F:00401C70 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ now if u will look closely at the algo u will notice a 2 hex numbers wich are repeated: 41/4F This means that the program will print the serial in ascii of A-O (41-4F). ok now to the magic part: on cmpxchg press ? EAX u will get this: 0000004F 0000000079 "A" now because we are dealing with an cmpxchg nistruction, that means that every time u will be at this adress again..eax will get a diff value (loop remember). so keep trace f10..u will find your self landing on the same adress again..but if u will do ? EAX again..eax will have a diff value..keep doing it and write the value (ascii) of the eax untill the loop continue to other code..if it's continues then it means that the program has finished creating the right serial and push 00000001 will be 00000000 ;D well it seems that the algo serial cmpxchng is keep looping untill read the name we enter (err name lenght ;D ). so the serial will be exactly as the name lenght u entered ;D (loops also) name: bengaly serial: AAEKKIC Have Fun ;D *Question: how do i SnapShot from Sice?? *A: use symbol loader..after closing sICE..open syLoader..file->save Sice history ;D CrackMe cracked ;) ________________________________________________________________________________________________ My thanks and gratitudes goes to: ----CoDe_InSide----- ;for helping in cracking -----BLAcKgH0sT------ ;for being good friend :) -------FusS------ ;asm / keygenning helper All the writers of Cracks tutorials and CrackMes