Patching Parabytes Nag Crackme - by Sunshine

Target : Parabytes Nag Crackme
File : patchme.exe (4.096 bytes)
Downloaded from : New2Cracking
Author : Parabytes
Tools used :

WDasm, Hex Editor


Download zip file here (includes orignal & patched crackme + this tut)

1. Introduction
Note: all values in this essay are hexadecimal!
Just run the crackme and we see a nice nag, it's a simple messagebox. Have a look at readme.txt to find out what exactly to do:


========
Nag Crackme
~~~~~~~~~~~
Nag patching,
patch it to show the good messagebox, not the nag :)
follow the rules :)

i've made it some day in the start of 2002, dont remember exactly...

rules :
~~~~~~~

NO re-coding !
========

2. The Crack
Ok, let's open the file in WDasm and go to program Entrypoint. We'll see this:

:00401000 B800104000 mov eax, 00401000 ; eax=401000
:00401005 B95F104000 mov ecx, 0040105F ; ecx=40105F
:0040100A 2BC8 sub ecx, eax            ; ecx=40105F-401000=5F
:0040100C 49 dec ecx                   ; ecx=ecx-1=5E
:0040100D 803890 cmp byte ptr [eax], 90; IF eax=90
:00401010 7402 je 00401014             ; THEN jump to 401014 
:00401012 EB07 jmp 0040101B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401010(C)
|
:00401014 3D0F104000 cmp eax, 0040100F ; eax=40100F?
:00401019 7531 jne 0040104C            ; IF not jump to "you've patched like a bad boy" message

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401012(U)
|
:0040101B 40 inc eax                   ; eax=eax+1
:0040101C E2EF loop 0040100D           ; jump to 40100D (if ecx>1)
:0040101E 6A00 push 00000000           ; from here on show Nag

* Possible StringData Ref from Data Obj ->"NAG !"
|

:00401020 687B204000 push 0040207B

* Possible StringData Ref from Data Obj ->"NAG! i nag you, that why i nag "
->"! kickme !"

|
:00401025 68B0204000 push 004020B0
:0040102A 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:0040102C E83D000000 Call 0040106E
:00401031 EB13 jmp 00401046  ; jump to exit routine
:00401033 6A00 push 00000000 ; form here on good guy message

* Possible StringData Ref from Data Obj ->"ParaBytes Patch ME !"
|

:00401035 6800204000 push 00402000

* Possible StringData Ref from Data Obj ->"OK!"
|

:0040103A 6815204000 push 00402015
:0040103F 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00401041 E828000000 Call 0040106E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401031(U)
|
:00401046 6864104000 push 00401064 ; push offset of exit routine
:0040104B C3 ret
                  ; go to exit routine  

Ok what's is done here... 401000 is the address where the code starts (as you see), this address is moved into eax. 40105F is the address where the code ends (just scroll down in WDasm to the end of code to see this). Both values are subtract, so in ecx we have the size (exactly: the length in bytes) of the code. Now there is a loop, let's have a look at it:
The byte to which eax points is compared with 90.
If so compare eax with 40100F. If equal, we jump to a messagebox which says us "we've patched like a bad boy" and the crackme quits.
If [eax] is not 90, increase eax by 1 and jump to the beginning of the loop where ecx is decreased by one. This is repeated until ecx=1.
In the first loop eax is 401000 which points to B8, in the second one eax=401001 -> byte ptr [eax]=00, in the third one [eax]=401002 -> byte ptr [eax]=10 and so on...

As we know in ecx is the size of the code, and exactly so many times is the loop executed. So the loop just checks if in the code is the byte 90 which means in asm "nop" = no operation. If found just check if eax is 40100F cause there is always a 90 in the opcode (803890 cmp byte ptr [eax], 90). If another 90 byte is found, we get this bad boy message.

Well, this means for us that we have to bypass the nag without using nops. So Parabytes has stolen this simple solution. Normally we just would nop out the call to MessageBox at offset 40102C and the jump to the exit routine at offset 401031. So we have to think about another solutions. 2 different approaches came to my mind:
1. we change the "nop"-check at the beginning so that it doesn't matter if there are nops and we never see the "bad boy" message or
2. what is more elegant we just jump over the nag directly to the "Ok.. good work" message.

I chose solution 2. At offset 40101E begins the nag. So we have to jump from this offset to offset 401033 where to good messagebox begins.
The differnece between both offsets is 401033-40101E=15. We can use a short jump cause 15<127. The opcode for an unconditional short jump is EB??. The ?? is the distance.
We said distance is 15 but the opcode itself is 2 bytes long, so the right opcode is EB13.
Open your hexeditor, go to raw offset 61E (which is the raw offset in file for virtual address 40101E) and change 6A00 to EB13.
That's it!
Hope you understand everything, but I think so... wasn't too difficult.

Sunshine, May 2003


This site is part of Sunshine's Homepage