Another C4N Tutorial Flu[X] Tutor #9 Author: Flu[X] Date: Sometime in 2000 Materials Required: W32Dasm v8.7+ Brain 1Way v1.5 (www.atma-software.com) Hiew 5.65+ Overview: Many Crackers have heard of Component Registration systems like VBOX. The program author pays for a protection scheme for his program. This same scheme is sold over and over. If you can crack the scheme, you have effectively cracked EVERY program it protects. So if one scheme is used to protect 100 products, then crack the scheme, and you have basically cracked 100 programs by making 1 crack. This tutorial deals with such a scheme. Remember this is a tutor for newbies so i didnt pick an absurdly hard target. Brief Techincal Description of 1Way: Upon installing this package I notice it is a DLL. Linking the DLL into your program incorporates its protection when you call certain functions it provides. So if we replace a cracked DLL with the one the program expects to recieve, we have cracked the program! Below is the functions it provides: NOTE: THE IMPORTANT ONES HAVE BEEN STARED (*) (*)SharewareLimit: Handles the whole logic for time-limitation in one step SharewareReg: Registers a trial version AppSetup: Sets up an application AppRemove: Removes an application (*)AppDaysLeft: Returns number of days left in evaluation period AppIsSetup: Application set up or not AppIsExpired: Trial period expired or not (*)AppIsRegistered: Application registered or not DateIsSetBack: System Date has been set back or not GetCDriveSerial: Returns serial number of the C: drive Obviously SharewareLimit is one function to crack because it handles the entire is registered process in one step. Also AppIsRegistered is important because if a programmer calls this it will tell him if it is registered or not yet. Third, AppDaysLeft is important for programs that do not offer registration but just time out and are no longer useable. There is also a shareware nag that tends to get annoying so we will remove that as well. Fire up W32Dasm and rip up 1way.dll ===Removing the Nag==== * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:4000BCE9(C) | :4000BCF1 83FB09 cmp ebx, 00000009 <-if ebx is > 9 goto nag :4000BCF4 7F11 jg 4000BD07 :4000BCF6 833DE4F2004009 cmp dword ptr [4000F2E4], 00000009 9 goto nag :4000BCFD 7F08 jg 4000BD07 :4000BCFF 3B1DE4F20040 cmp ebx, dword ptr [4000F2E4] <- ebx > data at mem loc ?? :4000BD05 7D25 jge 4000BD2C <-jump past nag * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:4000BCF4(C), :4000BCFD(C) | :4000BD07 33DB xor ebx, ebx :4000BD09 33C0 xor eax, eax :4000BD0B A3E4F20040 mov dword ptr [4000F2E4], eax :4000BD10 6830100000 push 00001030 * Possible StringData Ref from Code Obj ->"1Way.DLL - Evaluation version" | :4000BD15 68C4BD0040 push 4000BDC4 * Possible StringData Ref from Code Obj ->"This version is for evaluation " ->"purposes only." | :4000BD1A 68E4BD0040 push 4000BDE4 :4000BD1F A148F30040 mov eax, dword ptr [4000F348] :4000BD24 8B00 mov eax, dword ptr [eax] :4000BD26 50 push eax * Reference To: user32.MessageBoxA, Ord:0000h | :4000BD27 E80492FFFF Call 40004F30 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:4000BD05(C) :4000BD2C Explanation of above: All this section does is test a few circumstances generated, and if they are met it shows the nag.. you can crack this by the modification shown below. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:4000BCE9(C) | :4000BCF1 83FB09 cmp ebx, 00000009 <-if ebx is > 9 goto nag :4000BCF4 7F11 jg 4000BD07 :4000BCF6 833DE4F2004009 cmp dword ptr [4000F2E4], 00000009 9 goto nag :4000BCFD 7F08 jg 4000BD07 :4000BCFF 3B1DE4F20040 cmp ebx, dword ptr [4000F2E4] <- ebx > data at mem loc ?? :4000BD05 7D25 jge 4000BD2C <-jump past nag if condition met BECOMES * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:4000BCE9(C) | :4000BCF1 83FB09 cmp ebx, 00000009 <-if ebx is > 9 then nothing! :4000BCF4 90 nop :4000BCF5 90 nop :4000BCF6 833DE4F2004009 cmp dword ptr [4000F2E4], 00000009 9 nothing! :4000BCFD 90 nop :4000BCFE 90 nop :4000BCFF 3B1DE4F20040 cmp ebx, dword ptr [4000F2E4] <- ebx > data at mem loc ?? :4000BD05 EB25 jmp 4000BD2C <-jump past nag ALWAYS All that was done was the removal of the code to jump to the nag! Now It wont display that annoying nag anymore! ==Cracking the SharewareLimit Function== Exported fn(): SharewareLimit - Ord:000Ah :4000E394 55 push ebp :4000E395 8BEC mov ebp, esp :4000E397 53 push ebx :4000E398 56 push esi :4000E399 8B750C mov esi, dword ptr [ebp+0C] :4000E39C 8B5D08 mov ebx, dword ptr [ebp+08] :4000E39F 56 push esi :4000E3A0 53 push ebx * Reference To: OneWay.AppIsExpired | :4000E3A1 E85AF7FFFF call 4000DB00 <- Call to see if app is expired :4000E3A6 84C0 test al, al <-test to see if it is :4000E3A8 742C je 4000E3D6 <- if app is NOT expired, Jump to continue :4000E3AA 56 push esi :4000E3AB 53 push ebx Now this is pretty simple, making it always jump to the non-expired code no matter what AppIsExpired returns will crack this function! Below are the modifications: * Reference To: OneWay.AppIsExpired | :4000E3A1 E85AF7FFFF call 4000DB00 :4000E3A6 84C0 test al, al :4000E3A8 EB2C jmp 4000E3D6 <- Always jump to good Code!! :4000E3AA 56 push esi :4000E3AB 53 push ebx * Reference To: OneWay.AppIsSetup * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:4000E3A8(U) | :4000E3D6 33C0 xor eax, eax <- good code (clear eax being used as a flag) ===Cracking the AppDaysLeft Function=== Exported fn(): AppDaysLeft - Ord:0005h :4000DCC8 55 push ebp :4000DCC9 8BEC mov ebp, esp :4000DCCB 53 push ebx :4000DCCC E843DFFFFF call 4000BC14 :4000DCD1 83CBFF or ebx, FFFFFFFF :4000DCD4 8B450C mov eax, dword ptr [ebp+0C] :4000DCD7 50 push eax :4000DCD8 8B4508 mov eax, dword ptr [ebp+08] :4000DCDB 50 push eax * Reference To: OneWay.AppIsExpired | :4000DCDC E81FFEFFFF call 4000DB00 <- Get expiration Time :4000DCE1 84C0 test al, al <-Is expired :4000DCE3 7523 jne 4000DD08 <- if yes send back no more days left in trial :4000DCE5 B81C070140 mov eax, 4001071C :4000DCEA BA10DD0040 mov edx, 4000DD10 :4000DCEF 33C9 xor ecx, ecx :4000DCF1 8A08 mov cl, byte ptr [eax] :4000DCF3 41 inc ecx :4000DCF4 E8BB4AFFFF call 400027B4 <-get # of days left :4000DCF9 7506 jne 4000DD01 <-if not registered goto here :4000DCFB 66BB0F27 mov bx, 270F :4000DCFF EB07 jmp 4000DD08 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:4000DCF9(C) | :4000DD01 668B1DD0070140 mov bx, word ptr [400107D0] <- Number of days left * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:4000DCE3(C), :4000DCFF(U) | :4000DD08 8BC3 mov eax, ebx :4000DD0A 5B pop ebx :4000DD0B 5D pop ebp :4000DD0C C20800 ret 0008 Ok, pretty simple, this can be fixed by the modifications being made below * Reference To: OneWay.AppIsExpired | :4000DCDC E81FFEFFFF call 4000DB00 <- Get expiration Time :4000DCE1 84C0 test al, al <- Is Expired?? :4000DCE3 90 nop <- changed to nop so it will Never JUMP :4000DCE4 90 nop <- to we are expired! :4000DCE5 B81C070140 mov eax, 4001071C :4000DCEA BA10DD0040 mov edx, 4000DD10 :4000DCEF 33C9 xor ecx, ecx :4000DCF1 8A08 mov cl, byte ptr [eax] :4000DCF3 41 inc ecx :4000DCF4 E8BB4AFFFF call 400027B4 <-days left :4000DCF9 EB06 jmp 4000DD01 <-always jump to set days left :4000DCFB 66BB0F27 mov bx, 270F :4000DCFF EB07 jmp 4000DD08 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:4000DCF9(U) | :4000DD01 66BB4500 mov bx, 0045 <-move 45h into # of days left (45h= 69) :4000DD05 40 inc eax <-fill bytes that new instruction does not use :4000DD06 90 nop < :4000DD07 48 dec eax < ===Cracking the AppIsRegistered Function=== Exported fn(): AppIsRegistered - Ord:0007h :4000DD14 55 push ebp :4000DD15 8BEC mov ebp, esp :4000DD17 6A00 push 00000000 :4000DD19 6A00 push 00000000 :4000DD1B 53 push ebx :4000DD1C 33C0 xor eax, eax :4000DD1E 55 push ebp :4000DD1F 68E4DD0040 push 4000DDE4 :4000DD24 64FF30 push dword ptr fs:[eax] :4000DD27 648920 mov dword ptr fs:[eax], esp :4000DD2A E8E5DEFFFF call 4000BC14 :4000DD2F 33DB xor ebx, ebx :4000DD31 8D55FC lea edx, dword ptr [ebp-04] :4000DD34 8B450C mov eax, dword ptr [ebp+0C] :4000DD37 E8E081FFFF call 40005F1C :4000DD3C 8B45FC mov eax, dword ptr [ebp-04] :4000DD3F 50 push eax :4000DD40 8D55F8 lea edx, dword ptr [ebp-08] :4000DD43 8B4508 mov eax, dword ptr [ebp+08] :4000DD46 E8D181FFFF call 40005F1C :4000DD4B 8B45F8 mov eax, dword ptr [ebp-08] :4000DD4E 5A pop edx :4000DD4F E864EEFFFF call 4000CBB8 <-get conditions :4000DD54 84C0 test al, al <-test if not conditions met :4000DD56 7471 je 4000DDC9 <- jump if not good condition so app will be unregistered :4000DD58 E827E9FFFF call 4000C684 :4000DD5D 8D45FC lea eax, dword ptr [ebp-04] :4000DD60 BAD8060140 mov edx, 400106D8 :4000DD65 E88257FFFF call 400034EC :4000DD6A 8B45FC mov eax, dword ptr [ebp-04] :4000DD6D E8DEE1FFFF call 4000BF50 :4000DD72 B81C070140 mov eax, 4001071C :4000DD77 BAF4DD0040 mov edx, 4000DDF4 :4000DD7C 33C9 xor ecx, ecx :4000DD7E 8A08 mov cl, byte ptr [eax] :4000DD80 41 inc ecx :4000DD81 E82E4AFFFF call 400027B4 <-get conditions and test them :4000DD86 7541 jne 4000DDC9 <- jump if not good condition so app will be unregistered :4000DD88 8D45FC lea eax, dword ptr [ebp-04] :4000DD8B BA40070140 mov edx, 40010740 :4000DD90 E85757FFFF call 400034EC :4000DD95 8B45FC mov eax, dword ptr [ebp-04] :4000DD98 50 push eax * Reference To: OneWay.GetCDriveSerial | :4000DD99 E8F6F7FFFF call 4000D594 :4000DD9E 8D55F8 lea edx, dword ptr [ebp-08] :4000DDA1 E8127DFFFF call 40005AB8 :4000DDA6 8B55F8 mov edx, dword ptr [ebp-08] :4000DDA9 58 pop eax :4000DDAA E8A958FFFF call 40003658 <-call for certain circumstances :4000DDAF 7518 jne 4000DDC9 <- jump if not good condition so app will be unregistered :4000DDB1 B864070140 mov eax, 40010764 :4000DDB6 BAECF20040 mov edx, 4000F2EC :4000DDBB 33C9 xor ecx, ecx :4000DDBD 8A08 mov cl, byte ptr [eax] :4000DDBF 41 inc ecx :4000DDC0 E8EF49FFFF call 400027B4 <-call for certain circumstances :4000DDC5 7502 jne 4000DDC9 <- jump if not good condition so app will be unregistered :4000DDC7 B301 mov bl, 01 <- set is registered * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:4000DD56(C), :4000DD86(C), :4000DDAF(C), :4000DDC5(C) | :4000DDC9 33C0 xor eax, eax :4000DDCB 5A pop edx :4000DDCC 59 pop ecx :4000DDCD 59 pop ecx :4000DDCE 648910 mov dword ptr fs:[eax], edx :4000DDD1 68EBDD0040 push 4000DDEB As you can see at location 4000DDC7, if bl is set to 1 then the DLL will return that it is registered. All the jumps jump past this line of code making the application be unregistered. By Nopping out the jumps we can simply make it always run a mov of 1 into bl making the application registered! Below are the changes that need to be made: Exported fn(): AppIsRegistered - Ord:0007h :4000DD14 55 push ebp :4000DD15 8BEC mov ebp, esp :4000DD17 6A00 push 00000000 :4000DD19 6A00 push 00000000 :4000DD1B 53 push ebx :4000DD1C 33C0 xor eax, eax :4000DD1E 55 push ebp :4000DD1F 68E4DD0040 push 4000DDE4 :4000DD24 64FF30 push dword ptr fs:[eax] :4000DD27 648920 mov dword ptr fs:[eax], esp :4000DD2A E8E5DEFFFF call 4000BC14 :4000DD2F 33DB xor ebx, ebx :4000DD31 8D55FC lea edx, dword ptr [ebp-04] :4000DD34 8B450C mov eax, dword ptr [ebp+0C] :4000DD37 E8E081FFFF call 40005F1C :4000DD3C 8B45FC mov eax, dword ptr [ebp-04] :4000DD3F 50 push eax :4000DD40 8D55F8 lea edx, dword ptr [ebp-08] :4000DD43 8B4508 mov eax, dword ptr [ebp+08] :4000DD46 E8D181FFFF call 40005F1C :4000DD4B 8B45F8 mov eax, dword ptr [ebp-08] :4000DD4E 5A pop edx :4000DD4F E864EEFFFF call 4000CBB8 :4000DD54 84C0 test al, al :4000DD56 40 inc eax <- inc eax and dex eax used in a pair :4000DD57 48 dec eax <- are the same as two nops :4000DD58 E827E9FFFF call 4000C684 :4000DD5D 8D45FC lea eax, dword ptr [ebp-04] :4000DD60 BAD8060140 mov edx, 400106D8 :4000DD65 E88257FFFF call 400034EC :4000DD6A 8B45FC mov eax, dword ptr [ebp-04] :4000DD6D E8DEE1FFFF call 4000BF50 :4000DD72 B81C070140 mov eax, 4001071C :4000DD77 BAF4DD0040 mov edx, 4000DDF4 :4000DD7C 33C9 xor ecx, ecx :4000DD7E 8A08 mov cl, byte ptr [eax] :4000DD80 41 inc ecx :4000DD81 E82E4AFFFF call 400027B4 :4000DD86 41 inc ecx <- inc ecx and dec ecx used in a pair :4000DD87 49 dec ecx <- are the same as two nops :4000DD88 8D45FC lea eax, dword ptr [ebp-04] :4000DD8B BA40070140 mov edx, 40010740 :4000DD90 E85757FFFF call 400034EC :4000DD95 8B45FC mov eax, dword ptr [ebp-04] :4000DD98 50 push eax * Reference To: OneWay.GetCDriveSerial | :4000DD99 E8F6F7FFFF call 4000D594 :4000DD9E 8D55F8 lea edx, dword ptr [ebp-08] :4000DDA1 E8127DFFFF call 40005AB8 :4000DDA6 8B55F8 mov edx, dword ptr [ebp-08] :4000DDA9 58 pop eax :4000DDAA E8A958FFFF call 40003658 :4000DDAF 40 inc eax <- inc eax and dex eax used in a pair :4000DDB0 48 dec eax <- are the same as two nops :4000DDB1 B864070140 mov eax, 40010764 :4000DDB6 BAECF20040 mov edx, 4000F2EC :4000DDBB 33C9 xor ecx, ecx :4000DDBD 8A08 mov cl, byte ptr [eax] :4000DDBF 41 inc ecx :4000DDC0 E8EF49FFFF call 400027B4 :4000DDC5 90 nop <- nop out jump :4000DDC6 90 nop <- " :4000DDC7 B301 mov bl, 01 :4000DDC9 33C0 xor eax, eax :4000DDCB 5A pop edx :4000DDCC 59 pop ecx :4000DDCD 59 pop ecx :4000DDCE 648910 mov dword ptr fs:[eax], edx :4000DDD1 68EBDD0040 push 4000DDEB After these modifications We have made we now possess a cracked DLL. Now if an application is protected by 1Way.dll, all we have to do is replace the supplied dll with ours and we will have cracked the program. Pretty Simple Eh? I hope to see you again in Flu[X] tutor #10 As always if you like a program buy it! This essay is for educational purposes ONLY! Software authors deserve your support! Flu[X]/C4N 2000 http://tuts99.cjb.net htp://tuts98m1.cjb.net