
                Cracking for newbies #5 - by woody^drn

I want to show you how to make some tricks for your programs, so it
will be more difficult to crack - some anti cracking routines.
In vaczine #3 I talked about how to xor strings so they don't seem
that interesting when the cracker looks at the .exe file.
This time I'll talk about a packing method and some checks you can
make in your program.

First we can start with the checks. Lets say the program is like this:
You've made two nag screens, one that isn't xored and one that's packed
and xored. We'll call them n1 and n2.

1) When your program starts, we let it check if any of the bytes (where
   the program calls the nag) of n2 is changed or modified.
   If it has been changed goto 2., else goto 4.
2) Display the n1.
3) Check if n1 has been changed, if so goto 4.
4) Display the n2.
5) Check if check 1) has been changed, if so goto 8. if not goto 6.
6) Check if check 3) has been changed, if so goto 9. if not goto 7.
7) Run the program.
8) fix check 1) and goto 5)
9) fix check 3) and goto 5)

Can you follow this ... the code checks it self, if something has been
changed aka patched/cracked it will fix the bytes that has been patched.
The crme#2.exe is a good example. You can make several nags that has
been hidden (I'll explain how to hide them later) just in case if the
other once is patched or destroyed, and just make the code display those
who are not patched.

There are several ways to hide strings, you can pack or xor the strings.
Make a depacking routine in the start of the program or just depack it
only when needed. If they are only depacked when needed it will make it
hard to dump it, well not hard, but the string refs wouldn't be there.
In w32dasm you can only see the strings if they are referenced to some
of the code. And we can use that weakness ... with illegal opcode
placement .. or whatever we choose to call it. etc.:

:0040103C 0000                    add byte ptr [eax], al
:0040103E 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"Crackme v1.6 for Vaczine #4"
                                  |
:00401040 6800304000              push 00403000

* Possible StringData Ref from Data Obj ->"NAG :)"
                                  |
:00401045 681C304000              push 0040301C
:0040104A 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:0040104C E8E5FFFFFF              Call 00401036

You can see that this will make it say "Crackme v1.6 .." ... the opcodes
fit, but what if the opcodes at 40103C has more than 2 bytes, like a
call. We could change 40103C 0000, to 40103C E83D, then it would need
more bytes and will overlab the push 00403000. Lets change it:

:0040103C E83D6A0068              call 68407A7E
:00401041 0030                    add byte ptr [eax], dh
:00401043 40                      inc eax
:00401044 00681C                  add byte ptr [eax+1C], ch
:00401047 304000                  xor byte ptr [eax+00], al
:0040104A 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:0040104C E8E5FFFFFF              Call 00401036"

See ?? now it doesn't show the string refs to the "NAG :)" or
"Crackme v1.6" ... really easy and quick. This is called delta offsets
The only thing is .. we have to make sure that the code doesn't jump to
40103C but only jumps to 40103E. That was one way of doing it .. ofcause
this wont confuse softice! We can't code this, this has to be done
manually either by hiew or any good hexeditor.

I've allready explained how to xor strings in vaczine #3, so lets move
on ... how to pack the opcodes. Packing is fairly easy, I'll explain a
very easy method that I've used in crme#2.exe.

The program starts normally, after initializing all the stuff it needs
to do, it jumps to the depacking routine: (I'll explain as we go on..)

.0040103B: B85F304000                   mov       eax,00040305F ;" @0_"

Moves the char at 40305F into eax, that char is 78h.

.00401040: 33D2                         xor       edx,edx

Xors edx with edx .. aka edx = 0

.00401042: 8A10                         mov       dl,[eax]

Moves the char in eax into dl, dl is now 78h.

.00401044: 80F212                       xor       dl,012 ;"

Now it xors dl with 12 ... 78h xor 12h = 6A.

.00401047: 8810                         mov       [eax],dl

Moves dl into eax's place (the place where it got the 78h from).

.00401049: 40                           inc       eax
.0040104A: 3D76304000                   cmp       eax,000403076 ;" @0v"
.0040104F: 76F1                         jbe      .000401042

Increases eax and compares eax with 403076. If eax is below or equal
then it will goto the the depacking start again .. just with the next
char at eax's place (inc eax).

Eax was 40305F and it will xor every char until eax is 403076.
40305F - 403076 looks like this:

.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

Alot of opcodes which makes no sense at all. But when the depacking
routine is done with xoring all these opcodes with 12, it will look
like this:

.0040305F: 6A00                         push      000
.00403061: 6800304000                   push      000403000 ;" @0"
.00403066: 681C304000                   push      00040301C ;" @0"
.0040306B: 6A00                         push      000
.0040306D: E8C2DFFFFF                   call     .000401034
.00403072: E99BDFFFFF                   jmp      .000401012

Very easy to understand ... pushes the top text of the window and the
text in the window. then it calls messageboxa to display the window.
and jumps back into the normal code again.

The packed/depacked code is actually at the strings offsets. So this
wont appear in w32dasm. The string can now be used as executing code
instead of strings. nice ... ;)

This is basicly how all packers are done .. this is just a very *very*
basic way of doing it. If the packed opcodes was supposed to be a nag
screen, then you can implant the checking routine to see if it has been
depacked .. if not .. the program is patched/cracked.

That's all for now .. cya !

-wOODY^dRN

