Crackme for newbies #2 - by woody^drn Okay .. the second crackme has some "cryptet" bytes, or you might say the file is packed. The crackme isn't really finished yet, but I havn't got the time to finish it, so many new projects. The file is crme#2.exe. But anyways, the crackme will show how packers works, well it's how packers pack the data, but in a more lame way ;) This crackme is kinda easy cause you can easily nop the hole checking part of it, but lets go through it all anyways .. just be happy that I didn't crypt the strings too ;) Make a backup of the program and lets run it. It starts with a messagebox saying "NAG :)", then another one with "Did you see the nag? no? cewl..", so the task here is to remove the nag screen. Load it into w32dasm and lets see what there .. Hmmm ... no strings ;) that's kinda odd ? heh .. let's load it in Sourcer and see what it brings us ... that didn't work either. I don't even wanna load it into ida, cause I hate the layout .. Well back to w32dasm ... and try tracing the program step by step: //******************** Program Entry Point ******** :00401000 E936000000 jmp 0040103B It starts by jumping to offset 40103B, what's there .. Call unsuccessfull says w32dasm .. hmmm maybe using delta offsets ? ;) Load the file into hiew and check the address: .0040103A: E9B85F3040 jmp 0403063F7 .0040103F: 0033 add [ebx],dh .00401041: D28A1080F212 ror b,[edx][012F28010],cl .00401047: 8810 mov [eax],dl Okay the nearest offset is at 40103A, so the opcode or hex at 40103A is the delta offset, the bad opcode ;) lets nop it .. Now w32dasm can jump to the offset ... nice ;) :0040103B B85F304000 mov eax, 0040305F :00401040 33D2 xor edx, edx It moves eax to 40305F, lets check what's there .. .0040305F: 7812 js .000403073 .00403061: 7A12 jp .000403075 .00403063: 225212 and dl,[edx][00012] .00403066: 7A0E jp .000403076 .00403068: 225212 and dl,[edx][00012] .0040306B: 7812 js .00040307F .0040306D: FA cli .0040306E: D0CD ror ch,1 .00403070: ED in eax,dx .00403071: ED in eax,dx .00403072: FB sti .00403073: 89CD mov ebp,ecx .00403075: ED in eax,dx .00403076: ED in eax,dx Hmm some crapy opcodes .. lets go a little further from 40103B :0040103B B85F304000 mov eax, 0040305F :00401040 33D2 xor edx, edx * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040104F(C) | :00401042 8A10 mov dl, byte ptr [eax] :00401044 80F212 xor dl, 12 :00401047 8810 mov byte ptr [eax], dl :00401049 40 inc eax :0040104A 3D76304000 cmp eax, 00403076 :0040104F 76F1 jbe 00401042 :00401051 770A ja 0040105D It moves 40305F into eax, then it zeros edx (xor edx,edx aka mov edx,0) then it moves the character at eax's place into dl and xors dl with 12 Then moves the result into eax. Increses eax, and checks if eax is 403076. It will jump to 401042 if eax is below or equal (jbe). If it's not it will jump to 40105D. Now as you probably noticed, this is the packing routine. It takes a char and xors it with 12, and replaces the old char with the new one, and does that until it reaches the offset 403076. So lets load the crackme into hiew and xor the bytes. Press F3 in hiew then F8 and write 12 in the hex editbox. Now press F8 until you reach 403077 (403077 because of the command jbe). Now you'll see this: .0040305F: 6A00 push 000 .00403061: 6800304000 push 000403000 .00403066: 681C304000 push 00040301C .0040306B: 6A00 push 000 .0040306D: E8C2DFFFFF call .000401034 .00403072: E99BDFFFFF jmp .000401012 This looks like a nice messagebox, pushes the text and then calls the messageboxa command. Lets check what's at 403000 and 40301C. At 403000 : Crackme v1.6 for Vaczine #4 At 40301C : NAG :) Well now you know, at 40305F the nag screen will appear ;) Back to the packing routine ... After it has depacked the nag, it will jump to 40105D, so what's there ! Call/Jump unsuccessful .. delta offset again .. darn ;) :0040105C C0B8061040008A sar byte ptr [eax+00401006], 8A :00401063 1080FAE9749D adc byte ptr [eax+9D74E9FA], al :00401069 E90B200000 jmp 00403079 So 40105C is the nearest offset, nop 40105C. Now w32dasm can jump ... :0040105D B806104000 mov eax, 00401006 :00401062 8A10 mov dl, byte ptr [eax] :00401064 80FAE9 cmp dl, E9 :00401067 749D je 00401006 :00401069 E90B200000 jmp 00403079 Now it will move 401006 into eax, and then move the char at eax's place into dl. Then it compares dl with E9, if it's equal it will now jump to 401006 if not it will jump to 403079. Lets check whats in 401006, Call/jump unsuccessful .. dammit ;) nop the nearest offset. :00401006 E96E200000 jmp 00403079 Okay ... it jumps to 403079, but it would jump there anyways .. so that was a checkpoint. It checked if the cracker had patched the offset, if so it will jump there anyways (this could have been done *alot* better, but then I had no idea how to explain what's going on ;) but anyways I hope you get the idea). Lets jump to 403079 and check what's there: (this doesn't show in w32dasm so you'll have to load it into hiew). .00403079: E9E1FFFFFF jmp .00040305F Hmmm ;) heh .. this is what happens when you make a crackme by hand (patching in hiew instead of using a compiler ;)). Well we *know* what's on 40305F, that's the nag screen - the packed bytes. .00403072: E99BDFFFFF jmp .000401012 This is what comes after the nag screen, a jump to 401012. And once again a delta offset, just nop it (the nearest offset). Then you'll se this: :00401012 A001104000 mov al, byte ptr [00401001] :00401017 3C36 cmp al, 36 :00401019 746A je 00401085 :0040101B E900000000 jmp 00401021 Does this look like a check point again ? yea it does ;) Move the hex at 401001 into al, compare al to 36, and jump if it's equal, and since we havn't patched the program at the offset, it will jump to 401085 ... if the byte was patched it would jump to 401021. But first let's check what's on 401085: (first a delta offset again ;) aint it cool ;) heh). :00401085 A061304000 mov al, byte ptr [00403061] :0040108A 3C68 cmp al, 68 :0040108C 75AD jne 0040103B :0040108E A072304000 mov al, byte ptr [00403072] :00401093 3CE9 cmp al, E9 :00401095 75A4 jne 0040103B :00401097 7402 je 0040109B Here is one more check point, remember the packed data .. 403061 and 403072 is the packed data, which is now unpacked .. well if the program hasn't been tampered with. What is does is to see if offset 403061 is equal to 68. .00403061: 7A12 ... this is the packed data when it's packed. When unpacked it looks like: .00403061: 6800304000 .. so if offset 403061 isn't 68 it means that it hasn't been unpacked aka the program is patched, a cracker is trying to crack the program. When it compares the offset with 68 and it's not equal with 68 it jumps to 40103B, which is where it depacks the nag screen and diplays it .. get it ? if someone has removed the code where it should depack the nag screen .. it will automaticly depack it anyways. The next check point is just for double checking .. checks 403072 is has been unpacked .. if not it will depack the nag screen. But if this hasn't been tampered with it will jump to 40109B .. once again a delta offset. just nop it ... : :0040109B 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"Crackme v1.6 for Vaczine #4" | :0040109D 6800304000 push 00403000 * Possible StringData Ref from Data Obj ->"Welcome to this crackme did " ->"you see the nag ? no ? cewl" | :004010A2 6823304000 push 00403023 :004010A7 6A00 push 00000000 * Reference To: USER32.MessageBoxA, Ord:01BBh | :004010A9 E886FFFFFF Call 00401034 :004010AE E902000000 jmp 004010B5 Finally ;) some string references heh.. well this aint too hard to se what it does .. it will display the second screen "welcome to this crackme ...." .. and call the messageboxa command. After that it will jump to 4010B5 .. and again a delta offset. :004010B5 E96EFFFFFF jmp 00401028 Jump to 401028 ... lets check it out .. * Reference To: KERNEL32.ExitProcess, Ord:0075h | :00401028 E801000000 Call 0040102E Exit ! geez ;) we'er through this rather long description of the crackme. Now .... da da da duuuuuumm ... how to crack it ;) The only thing we have to do is display the second screen, which was at 40109B .. now we just have to make it jump to 40109B first thing in the program, the entry point is at 401000. just say jmp 40109B well jmp 49B .. we need the offset not the data line .. now it will only display the second screen, but we need to repair the exitprocess. .00401028: E801000000 call .00040102E .0040102D: E8FF250020 call 020002A31 We know that after displaying the second screen it will jump to 401028, and here it calls 40102E .. but there is a delta offset here, lets fix it. Remove the char at 40102D. .00401028: E801000000 call .00040102E .0040102D: 90 nop .0040102E: FF2500204000 jmp ExitProcess There ya go .. and we have cracked the crackme ... nice ;) that's all folkes! -wOODY^dRN