************************************************************************************************************************************************************** CrackMe 7 ************************************************************************************************************************************************************** Author: Fr1c Protection: SoftICE, W32Dasm, Enable Button, Name / Serial and a NAG (Btw, packed with UPX ;) URL: http://www.mesa-sys.com/~eternal/e-h/fr1c-crackme7.zip Tools: SoftICE v4.05 W32Dasm v8.93 ProcDump v1.6.2 Hex-Editor ---> Intro... Welcome to my next Tutorial !!! First we're going to Manually Unpack it (UPX), as you probably know it can be done with UPX itself but i don't like that so we're going to do it Manually :) Then to get rid of the "SoftICE, W32Dasm, Enable Button and the NAG" we're going to find those places in memory (The places to patch that is ;) with W32Dasm. And then we're going to do some "Inline Patching" (I think it's called like that ;) so that when you run the Packed CrackMe it will patch the program itself :) (Jmp OEP -> Jmp Our Code and back) And then offcourse we're going to crack it :) ---> Let's Begin... *** Manually Unpacking *** Ok, well first we're going to find the OEP of the Packed program to do the "int 3" break :) So open ProcDump and click on "PE Editor" then select the Packed CrackMe and click "Open". Notice the Entry Point it's: 00056610 But that's a "Virtual Address" we need to have the "Raw Address" ;) So click on "Sections" and check in which Section this "Virtual Address" is located in. It's the second Section called: UPX1 It's always the same with UPX ;) So to convert to "Raw Address" we do this: Virtual Address - Raw Address OEP = 00056610 - (00036000 - 00000400) OEP = 00020A10 Close ProcDump and open the Packed CrackMe in your HexEditor, then go to that location "00020A10" But we're not going to break exactly at the beginning of the Unpacking process because you can find easily where it jumps to the real OEP :) So when your at that "Raw Address" press 1 time "Page-Down" and then notice at the end of the Code something like this: 61E94BC3FEFF Now replace the "E9" with "CC" and save the File and get into SoftICE (CTRL+D). Then type "bpint 3" and get out of SoftICE (CTRL+D), run the Packed CrackMe and SoftICE should popup :) now type "BC *" to clear the breakpoint and we're landed right on the Jump to the real OEP :) So press (F10) 1 time and we're at the OEP write down the "Virtual Address" it's: 00442AE8 Ok, now do the "EBFE" trick and get to ProcDump (If you don't know what the EBFE trick is check my other Tutorials ;) and right click on the File and select "DUMP (full)" then save the File to where ever you want and then right click again and select "Kill task". ok, now in ProcDump click on "PE Editor" and open the Unpacked CrackMe. Then change the Entry Point to: 00042AE8 (No Image Base ;) That's it, now you can run and disassemble the CrackMe :) ---> Let's Begin... *** Getting rid of... *** Well if you run the Unpacked CrackMe now you'll get a Message Box saying that it has detected SoftICE :) "SoftICE is DETECTED" Ok, now open up W32Dasm and disassemble the Unpacked CrackMe and then search for that string, Nowhere??? damn ;) Hmmm... so how are we going to do this :) Ok, first we'll deal with the SoftICE check so i suggest to open the Unpacked CrackMe in your HexEditor (Close W32Dasm if you haven't done so) and then search for something like: SoftICE SICE It'll found the second one :) and so you'll see this: //./SICE Aha, the SoftICE check done with CreateFileA :) Now get into SoftICE (CTRL+D) and type "bpx CreateFileA" then out of SoftICE (CTRL+D) and open the Unpacked CrackMe. Now SoftICE breaks fast but the first time isn't the one we need because Windows needs to "Create" the File first :) So press (F5) to skip this one and SoftICE will break again. Now press (F12) 1 time and you'll see this: -------------------------------------------------------------------------------------------------------------------------------------------------------------- :00442756 83F8FF cmp eax, FFFFFFFF <--- Compare EAX with FFFFFFFF (//./SICE not found?) :00442759 7417 je 00442772 <--- If equal jump and skip the SoftICE detected Message Box :), else show it and quit :0044275B 50 push eax :0044275C E8C734FCFF call 00405C28 :00442761 B828284400 mov eax, 00442828 <--- SoftIce is DETECTED :00442766 E85DF9FFFF call 004420C8 :0044276B 6A00 push 00000000 :0044276D E8FE34FCFF call 00405C70 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00442759(C) | :00442772 B844284400 mov eax, 00442844 <--- Kill me !! My name is NAG SCREEN! :00442777 E84CF9FFFF call 004420C8 :0044277C 33D2 xor edx, edx :0044277E 8B83CC020000 mov eax, dword ptr [ebx+000002CC] :00442784 8B08 mov ecx, dword ptr [eax] :00442786 FF5160 call [ecx+60] :00442789 5B pop ebx :0044278A C3 ret -------------------------------------------------------------------------------------------------------------------------------------------------------------- So as you can see for the SoftICE check the "je 00442772" decides if we are the Good Boy or the Bad Boy ;) So we need to make it Jump, and so remember the "Virtual Address" 00442759 for our Inline Patching :) For now when your on the "je 00442772" type "r fl z" this will set the Z flag and so we jump. But... Have you seen where it jumps to? To our lovely NAG screen :) Heh, we need to make it jump a little further, and i suggest to let it jump just behind the next Call. Why? Notice the String "SoftICE is DETECTED" behind it is a Call the same as with the String "Kill me !! My name is NAG SCREEN!" so it's probably the Message Box (You can check it out with SoftICE if you want :). So we need to change the length of the Jump as well. Now just jump till you get the NAG and press "Ok" and we're back in SoftICE (Remember the Protection "Enable Button" ? ;). Now trace and go into "call [ecx+60]" and you'll see this: -------------------------------------------------------------------------------------------------------------------------------------------------------------- :00423CD4 3A5048 cmp dl, byte ptr [eax+48] :00423CD7 7411 je 00423CEA :00423CD9 885048 mov byte ptr [eax+48], dl :00423CDC 6A00 push 00000000 :00423CDE 33C9 xor ecx, ecx :00423CE0 BA0CB00000 mov edx, 0000B00C :00423CE5 E8A6100000 call 00424D90 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00423CD7(C) | :00423CEA C3 ret -------------------------------------------------------------------------------------------------------------------------------------------------------------- Hmm.. you see that Compare with DL and [eax+48]? :) If equal we jump to the ret and nothing changes, else it puts DL in [eax+48] and does all kinds of other stuff :) This is probably the "Enable Button" check ;P How are we going to find out? Simple... Just let the "je 00423CEA" jump and we'll see :) So when your on the "je 00423CEA" type "r fl z" to let it jump and press (CTRL+D) to exit SoftICE. Now the main program pops up and i see no Button Disabled or something :) Now quit the CrackMe and do the same but without letting the last "je" (the Enable Button check) jump and now you'll see in the main window that the Button "Register" is disabled ;) Hehe, right we got it :) But now we need to let this program patch itself. (Ok, one other thing, i don't want to explain this to much ;) but like i mentioned above in the File there's also a W32Dasm check. It uses FindWindowA to locate W32Dasm (If running) you can easily defeat this by changing the next line in W32Dasm or the CrackMe itself :) "URSoft W32Dasm Ver 8.93 Program Disassembler/Debugger" <--- In CrackMe "URSoft W32Dasm Ver %s Program Disassembler/Debugger" <--- In W32Dasm Anyway have you noticed something in the Code above (the second above ;) where those 2 Message Boxes are? It checks for "//./SICE" if equal we get a Message Box and then quit, else we get the NAG and Enable Button" check, and then followed by a: :00442789 5B pop ebx :0044278A C3 ret So why not change the "je 00442772" to "pop ebx, ret" :) Then we don't need to patch so much and it's more easy then the other thing we had in mind. (Well much we can still patch the "je" to a jump and skip all of it but crap, i'm gonna do it this way ;) So what we're actually going to do is at the Address "00442759" patch the bytes "7417" with "5BC3" :) Ok, if you want you can delete the Unpacked CrackMe now ;) Now we need to find some space in the Packed CrackMe for our Code. So open the Packed CrackMe in your HexEditor and go to the OEP (not the real OEP that's not there now ;) and press "Page-Down" 1 time. You see some little space below the Code, excellent :) I suggest to put our Code at "Raw Address" 00020BE0 and my Code looks like this (put your Code there in whatever language you want ;) : -------------------------------------------------------------------------------------------------------------------------------------------------------------- mov byte ptr [00442759], 5B mov byte ptr [0044275A], C3 push 00442AE8 ret -------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, why 2 mov's ??? Dunno, i just want it that way ;P You can also change it in "mov word ptr [00442759], 5BC3" :) And why the "push 00442AE8, ret" ??? Also dunno, it's just easy to use ;) So now save the File and run it, it works ;P Ok phew, now on to the Cracking ;) ---> Let's Begin... *** Getting a valid Name and Serial *** Open the Packed CrackMe and enter any Name and Serial i've used: Name: CoDe_InSiDe Serial: 1234567890 Now get into SoftICE (CTRL+D) and type "bpx hmemcpy" then out of SoftICE (CTRL+D) and press on the Button "Register" and SoftICE should popup. Press (F12) 12 times to get into the CrackMe Code and you'll see this: -------------------------------------------------------------------------------------------------------------------------------------------------------------- :004428AE 8B45F4 mov eax, dword ptr [ebp-0C] <--- EAX now points to our Name :004428B1 E87E11FCFF call 00403A34 <--- Get the length of our Name :004428B6 8BF0 mov esi, eax <--- Move EAX in ESI :004428B8 85F6 test esi, esi <--- Test if ESI is 00 :004428BA 7E41 jle 004428FD <--- If equal we jump and fail (well almost fail ;), else continue with the loop :004428BC BF01000000 mov edi, 00000001 <--- Mov 00000001 in EDI * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004428FB(C) | :004428C1 8D55F4 lea edx, dword ptr [ebp-0C] :004428C4 8B45FC mov eax, dword ptr [ebp-04] :004428C7 8B80C4020000 mov eax, dword ptr [eax+000002C4] :004428CD E8CE14FEFF call 00423DA0 :004428D2 8B45F4 mov eax, dword ptr [ebp-0C] <--- Move offset to our Name in EAX :004428D5 0FB64438FF movzx eax, byte ptr [eax+edi-01] <--- Move first Char in EAX :004428DA 8BD8 mov ebx, eax <--- Move EAX in EBX :004428DC 6BC363 imul eax, ebx, 00000063 <--- Multiply 00000063 with EBX and put the result in EAX :004428DF 8BD8 mov ebx, eax <--- Mov EAX in EBX :004428E1 83F306 xor ebx, 00000006 <--- XOR EBX with 00000006 :004428E4 8D45F0 lea eax, dword ptr [ebp-10] <--- Point EAX to some place in Memory :004428E7 8BD3 mov edx, ebx <--- Move EBX in EDX :004428E9 E86E10FCFF call 0040395C <--- Move DL at some place in Memory (EDX contains the data from EBX) :004428EE 8B55F0 mov edx, dword ptr [ebp-10] <--- Move [ebp-10] in EDX :004428F1 8D45F8 lea eax, dword ptr [ebp-08] <--- Point EAX to some place in Memory :004428F4 E84311FCFF call 00403A3C <--- Here it puts the Characters behind each other :004428F9 47 inc edi <--- EDI +1 :004428FA 4E dec esi <--- ESI -1 (Length of our Name) :004428FB 75C4 jne 004428C1 <--- If ESI isn't 00 we repeat the loop else continue * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004428BA(C) | :004428FD 8D55F4 lea edx, dword ptr [ebp-0C] :00442900 8B45FC mov eax, dword ptr [ebp-04] :00442903 8B80C8020000 mov eax, dword ptr [eax+000002C8] :00442909 E89214FEFF call 00423DA0 :0044290E 8B55F4 mov edx, dword ptr [ebp-0C] <--- Move offset to our "Fake" Serial in EDX :00442911 8B45F8 mov eax, dword ptr [ebp-08] <--- Move offset to our "Real" Serial in EAX :00442914 E82B12FCFF call 00403B44 <--- Compare them :00442919 750A jne 00442925 <--- If not equal we jump and just continue, else we get a Good Message Box :) :0044291B B864294400 mov eax, 00442964 <--- Good work cracker! :00442920 E8A3F7FFFF call 004420C8 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00442919(C) | :00442925 33C0 xor eax, eax :00442927 5A pop edx :00442928 59 pop ecx :00442929 59 pop ecx :0044292A 648910 mov dword ptr fs:[eax], edx :0044292D 6852294400 push 00442952 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00442950(U) | :00442932 8D45F0 lea eax, dword ptr [ebp-10] :00442935 E87E0EFCFF call 004037B8 :0044293A 8D45F4 lea eax, dword ptr [ebp-0C] :0044293D E8760EFCFF call 004037B8 :00442942 8D45F8 lea eax, dword ptr [ebp-08] :00442945 E86E0EFCFF call 004037B8 :0044294A C3 ret -------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, very simple and small Algo :) So it does this for my Name: Name: CoDe_InSiDe Put first Char in EAX (C = 43) Move EAX in EBX Then it Multiplies EBX with 00000063 and puts the result in EAX (result in EAX is now = 000019E9) Move EAX in EBX Then it XOR's EBX with 00000006 (EBX = 000019EF) Move EBX in EDX Move DL into some place in the Memory Increase EDI (Point to our next Char) Decrease ESI (Are we at the end of our Name?) If not we jump and repeat this loop else we're finished :) So, very simple when your on the instruction "call 00403B44" type "d eax" and you'll see your "Real" Serial :) In my case it weren't any readable Characters so i had this for my Name: Name: CoDe_InSiDe Serial: hex = EFEB4A09BB3D8C1F9D4A09 Ok, that's All... You can patch this CrackMe by simply NOP the "jne 00442925" but i'll leave that up to you :) *** NOTE *** Remember where i said above "If equal we jump and fail (well almost fail ;), else continue with the loop" ? ;) It was the check if we entered a Name, now the funny thing is if we haven't entered a Name we still go to the Compare stuff. So then it Compares nothing (00 our Name) with the created Serial (which is also 00 because it hasn't created any Serial from our Name) and so we continue and get the Good Boy Message :P Just try it enter nothing as your Name and Serial and your Registered. Well, a weird thing about this one is that in the Title bar it says "CrackMe 7 by Fr1c - UNREGISTERED" and after we Registered it, it isn't changed ;) But who cares... ---> Outro... And another big Tutorial ;) You maybe also think now "Hmmm... why have we Unpacked this program it wasn't necessary?" and your right it wasn't :P But hey i like to Unpack stuff ;) I hope you learned something from this Tutorial... (Btw, this CrackMe checks for W32Dasm if it's running, with the Inline Patch you can easily fix that ;) ---> Greetings... To be honest i'm getting a bit sick of these greetings everytime ;P So i'll just say: Greetings to everyone i know, and to everyone who knows me, and You... ;P Don't trust the Outside, trust the InSiDe !!! Cya... CoDe_InSiDe Email: code.inside@home.nl