
             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

