Cr@ck Tutorial (CheckPop 1.1 for Windoze95/98/NT4 by Nevis Systems)


		   <01" rulez!]------->

----==================-<[by VucoeT in 4/98]>-===================----

 ===		INVESHKU/ckpop11.exe?Q=mx03-cDwuXO0901&O=853
		(copy and paste it! ... thanx for upping!)
-Rating:     	Beginner 
 ======         (that knows, how to turn on the machine ;])

-The program:	POP-email-checker, dunno details ;]

-Protection: 	Time Trial;Serial to register

-Tools you will need:	

SOFTICE for Win95 3.22+ (Debugger)

W32DASM 8.9+ (almost any version will do, this is the one I use)
---> get them at Lord Caligo's Fantastic World of Cracking.

HEX-EDITOR (Exlpained here is HexWorkshop, but any will do)
---> get it at

-Best read with: Windows NOTEPAD.EXE, one of the best M$-Products!
 ==============  or even better printed on some sheets of cellulose.


(after installed in Win95)

OK, let's start getting an overview of the target and its behavior.
When we start it, there is a weird NAG, telling us, that this Version
is Shareware and when the LEGAL-use-time is over. And the good news
(for us ;] ) is, that the stupid nag won't appear, once we are a re-
gistered user. 
By changing the system time we know, that the time trial takes the 
actual time to compare it with the day Checkpop has been installed on 
your system. But that's just a side comment (another approach).
OK, at the same time a help screen is opened, which tells us about
the (VERY interesting;]) registration details.
Errr ... both screens we don't seem to like ... but don't worry, you
are not gonna see them for a long time ;].


As you might know, there are functions installed in library files of
Windows(DLLs; like USER(32).DLL,GDI32.DLL,...) that are uni-
versal and that can be called by programs in order to use them, 
instead of using own functions, that have to be coded first 
(which is additional work). Coders are lazy, as we all are ;]. So 
most of the time they will use windows-own functions.
The program just PUSHes the nescessary values for the function it
will call, before it is executed. You could say, parameters are 
given from the program to (a) Windows (-function) to use Windows-own
set of functions.
This is good for us;], because, if we know the effect of those 
functions, we can easily break into the running program and stop
it at the point, where a certain function is called.

You may ask:"How to do that???". This is the job of the Debugger, in
our case SoftIce. Ir runs in background and kind of "examines" all
activities, of (in our case) Windows. The code, which runs thru
(Softice and) the processor is the so called machine-code or Assembly
language, which is the only language the processor can handle.
Every high-leveled language will translate the code into assembly in
order to make it understandable for the (Intel-)processor. That's why
you maybe should bite yourself into assembly, cos it is essential.


OK now it gets interesting. After Checkpop is launched, we press the 
right button on the taskbar symbol of CheckPop and select [ABOUT]. 
In the window appears a button [REGISTER]. Hehehe <-THE-> button, 
so to speak. When you are cracking and using this kind of approach, 
then you have to first examine your target program to find the place, 
where you can enter your SERIAL- number. We found it here! (the re-
gister-box at the beginning [NAG] is the same BTW.).
Press the [REGISTER] button and the program wants you to enter a 
VALID serial-number. So we must think of something, because most of
us won't have this VALID number (others, please stop here ;]). Unless
you don't have a lucky guess the program won't accept your entry ;].
Note: It doesn't tell you, if your entered number was correct, but
just goes on unregistered.

We are about to break into the function, that 
is usually used to get a text from a dialog-window, such as our 
serial. There are 2 functions, that do (quite) the same. 

Functions for getting a text (string) from a Dialog-Window

The first:
GetDlgItemTextA, GetDlgItemText

The second:
GetWindowTextA, GetWindowText

the "A" is used to call the 32bit function, while the other one 
(without the "A" behind) is for 16bit appz. Since our target runs
in WindowsNT too, we can already guess, that it is a 32bit program.
If you are not sure, just set breaks on both. 

So this Window gets out entered serial-number and later there will 
some sort of check, if it was the right one. Our aim is to find the
location in the program, that checks, if it should go on saying:
"Thanks soo much for registering" or "Get away silly gambler!" ;],
of course the expression used in applications will be different ...


I already assume you have been working a bit with softice, installed
it propperly and are ready to set the break. If not see 
HTTP://FRAVIA.ORG for tuts on installing Softice. Don't forget to
make softice load the DLLs, which contain the functions, we want to 
break on. Do this by eding the WINICE.DAT file in your softice dir
and remove the ";" in front of the Exports (DLLs):

EXP=c:\win95\system\user32.dll         ;Library file of our function

(your pathnames may differ ... EXP=C:\windows\...)
(near the end of WINICE.DAT, this is how it should look)


OK now, remember, that we are still on our registration window, with
Softice running. Enter some Serial, but dont confirm it yet. 
Activate Softice by pressing F5 or CTRL-D. OK, this is the debugger.
Just enter:

"bpx getdlgitemtexta" 

You have to guess, which of the two functions discussed b4 it is, 
but I prefer trying this one first and it is the right one here.
It can be, that any of it will break, too. After setting this break-
point go back to the Serial-Entry (again CTRL-D). Enter something 
and confirm your entry by hitting [OK] ...

BOOM! ;]

OK, what you see now is: Softice has detected, that a program wants
to call the function, we set a breakpoint on before. We are now in-
side the DLL, at the beginning of that function (indicated by a 
seperator looking like this:------------USER32!.TEXT...).
We want to go to the location in our program, where it was called 
from. By pressing [F11] we can. Look at the piece of code below.
(normally you should write down the location of the break here to
 find it later in W32DASM, but I did that for you, as I am a nice
 person ;])

* Reference To: USER32.GetDlgItemTextA, Ord:00F5h
:0040C2F4 FF15D0344200     Call dword ptr [004234D0]  ;the call!
:0040C2FA 8D542408         lea edx, dword ptr [esp+08];
:0040C2FE B968144200       mov ecx, 00421468          ;
:0040C303 52               push edx                   ;
:0040C304 E8C7A6FFFF       call 004069D0       ;Hmmm ...
:0040C309 E8F2000000       call 0040C400       ;Is-the-serial-valid?
						Read on to see why!
:0040C30E 6A01             push 00000001       ;
:0040C310 56               push esi            ;

* Reference To: USER32.EndDialog, Ord:00B4h    ;End Dialog!
:0040C311 FF15B0344200      Call dword ptr [004234B0]
:0040C317 E9BE000000        jmp 0040C3DA

(after ";" its my comments)
(WDASM Disassembly piece of the code. Easier for me to paste here!;])

So here we are! This is the piece of code, where our serial is
read. After that we can see two calls ... (Hmmm?). Later we find 
USER32.EndDialog, which as you might guess ends the dialog ... ;]. 
So most likely the determination, whether the serial we entered was 
the right or wrong one will be in one of those 2 calls. 
Can you follow?
OK, the job of Softice is done for now. To prevent it from
popping up again, enter "BC*", which means "Clear all breakpoints".


Now that we know the location, we can open W32DASM and disassemble
the file checkpop.exe (disassemble -> get the assembler code).
Since it is not too big, it will be done quickly. So now search for
the location in W32DASM, that we got B4 on the break. I think you
will be able to find it easily and then see the piece of code above.
The key must be in those 2 CALLs ... (usually a routine is done, 
which checks, if the entered code is valid).

OK, what is always done, when you want to crack a program to make it
registered is, you try fishing for strings, that W32DASM fortunately
seperates (Refs-String Data Reference). What strings could that be? 
Of course some which appear to have a clear connection with a (hidden) 
routine, that checks, if the program is registered or not. The only
text we find is "Registered", which as we might guess will show up
somewhere, after we entered the valid serial.
Go, where this string is used in the assembled listing, by double
clicking on it. Sometimes there is more than one occurence of a
string, so always try to double click it more than once ...

If we do so we land here: 
* Reference To: USER32.SetWindowTextA, Ord:0221h
:004011A5 FF15A8344200    Call dword ptr [004234A8]
:004011AB E850B20000      call 0040C400 ;Is-the-serial-valid?
					;In our case, whatever
					;happenes in the call
					;it will at least move 
					;something into EAX,
					;which is NOT 01, since
					;we entered a wrong serial.
					;What it is, is not really
					;interesting here.

:004011B0 83F801          cmp eax, 00000001
:004011B3 7522            jne 004011D7  ; Jump, if 1 not equals eax
				        ; the BAD jump, which will
				        ; override our "Registered"
				        ; to go the way of the wrong
				        ; entered serial. BTW here
				        ; there is no Window telling
				        ; us, that we have entered
				        ; a wrong number ...

* Possible StringData Ref from Data Obj ->"Registered"
:004011B5 6850C04100              push 0041C050

OK, do you remember the call 0040C400 (Is-the-serial-valid?). You al-
ready seen it before. When? Well after we broke in with Softice. One
of those calls we saw, seeing the code after the break. This
is confirmed thou (this CALL (routine) is the check, if the program
is registered). If you wanted to find out, how the real number is
calculated then take a look at this call. But this is more advanced.

Let's take a resumée. What will happen, if we enter the wrong serial
is, that the "Is-the-serial-valid?"-CALL will return something
different than "01" to EAX. If the returned value inequals 01, then
it will jump away from our beloved "Registered", otherwise it will go
on. So whats our aim? We want the prog not to take the BAD jump and
the way, where the program is gonna go is set in this routine, by 
making EAX "00" or "01".


So the returned value must be "01" in order to make the program think
we are registered users. What we will do is the following: We go to
the beginning of the CALL. We already found out, that it will GOOD-
jump later, if the returned value is "01". So we just use the be-
ginning of the called function to apply our code to move "01" into

The following will move "01" into EAX and then return. The "01" is 
the only thing we need from this CALL ... =) ... the Assembly-
commands for this are:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PUSH 00000001   ; put "01" into the stack
POP EAX         ; put the stack value into EAX (EAX=01)
RET             ; Return to where it was called from

in HEX (with what we will overwrite later) it is: "640158C3"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

OK, so far so good. You may ask, why we didnt just disable the jump
somehow (NOP). Well the "01" is the sign here (and maybe elsewhere,
which is very important!!!) for registered version. And this sign
maybe used elsewhere too and it is, as you know. 

Just check inside the CALL.

WDASM32 shows you, which addresses called this function:
* Referenced by a CALL at Addresses:
|:004011AB   , :004050A0   , :0040BF41   , :0040C309 ; 3 more!
:0040C400 64A100000000            mov eax, dword ptr fs:[00000000]

So what we can say now is, that 2 other locations (beside our 
004011AB and 0040C309) check this routine, if the program is 


To change it in "checkpop.exe" first make a backup-copy of it. Then
open it with your hex-editor and find the offset-address of the code 
we see in the status-bar of W32DASM before (Offset XXXXXXX in file:
checkpop.exe) Found the code? Search for it or scroll, whatever you
prefer. The location should be B800h ("h" means HEX). Now overwrite 
the "64A10000" with "6A0158C3". Changes done? Save the file and 
launch it to see, what is the effect of the changes!

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Note:If you cannot save the file in the Hexeditor, then be sure to
     have checkpop closed, while applying the changes. You cannot
     save to the file, if it is running!
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


OK, well we start it, the help-screen still pops up. Ergh! We think:
All for nothing! But continuing to the about-window, the program
tells us, that we are a registered user (and unable to enter a 
serial now). Thats good! Even if we change the System time to one
month later, it still works, without showing the "EXPIRED ... "-
screen (just play around with the ORIGINAL file, too). We even know
(now), where our search-string "registered" is located. It is the
Name of the button, we cannot press ...

So to get to the point. The program behaves like an registered one
now, but there is still this help screen, which of course won't show
up telling us registration details, if we had the REAL registered
version running. Hmmm ... 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you take a look at the registry in :

HKEY_CURRENT_USER/SOFTRARE/Nevis Systems/Checkpop/1.1/

It stores the time it was installed first there, too. So if you are
desperate and don't want to crack it, you can also just delete the 
registry-entry "Nevis Systems" or just "1.1". You will have 14 more 
days of use ... but that's of course NOT our aim.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


We don't want this help screen !!! Maybe there is a check before 
the help screen, that checks somewhere, if we are registered users.
So we need to break or get to the CALL of this Help-nag-screen. 

There are 2 possibilities: 

Since it is most likely (just a feeling ;]), that it will be the 
first call for winhelp in this .exe file, we can just search in 
W32DASM for "winhelp" (16bit) or again "winhelpa" (32bit). Both 
will lead you to the right spot.
Just go to the start of the disassembly listing in W32DASM and do
a search for "winhelp" or "winhelpa". It will first break on the
imported function list, which is of course not, what we are looking
for. But the next break is BINGO!.

Another possibility of course is, to set a breakpoint in Softice
for "winhelpa" (bpx winhelpa), after it breaks F11, then note the 
address of the CALL and find it again in W32DASM.

Both will lead you to this:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:0040500A B968144200              mov ecx, 00421468

:0040500F E84C1C0000              call 00406C60 ;in there the value
						 of EAX is set (ob-

:00405014 85C0                    test eax, eax ;if EAX equals 0 
						 then don't jump 
						 (which means: 
						 execute the

:00405016 0F8584000000            jne  004050A0
:0040501C 68B0040000              push 000004B0
:00405021 6A01                    push 00000001

* Possible StringData Ref from Data Obj ->"checkpop.hlp"
:00405023 6828CB4100              push 0041CB28
:00405028 53                      push ebx

* Reference To: USER32.WinHelpA, Ord:025Eh      ;THIS IS THE BREAK!
:00405029 FF1528354200            Call dword ptr [00423528] ; BAD!!!
:0040502F 53                      push ebx
:00405030 53                      push ebx

Most interesting for us is again another call, which seems to de-
termine the value of EAX, since it is TESTed right after the call 
and the result of this TEST is responsible for it overriding the 
winhelp- CALL or executing it (TEST just sets a flag depending on the
value of EAX; for a deeper inside in Assembly either read more tuts
about it or buy a book (the bigger the better ;])).


The solution is again the same. Best is to change the CALL, so that
the returned EAX-value is (again) "01". So everything we have to do
again, is get to the start inside the call and change it, that it
just puts 01 into EAX and then RETURNS. It will be the same code
as in the first change we made.
So again we start our HEX-Editor, search for the offset (status bar
in W32DASM;6060h) and change it to "6A0158C3", like before.
And now launch -[Checkpop 100% Cracked]- by you! ;]


Actually the CALL before the HELP-screen reads something out of the
registry which makes the program show the help-screen. What that is 
is not important for the crack. We ask ourselfes, how to make the 
consequences look like, as if it read the VALID things out of the 
registry. So the CALL just gives back an "Valid" or an "Invalid",
here its either a "01" or a "00". You might say a good value or a 
bad value.
Don't ask me, what is happening inside the CALL. It is not really 
important for cracking this target.
If you are interested what happens inside, just follow the
CALLS and see what they are doing ... ;]


I hope this tutorial helped at least a bit to understand the way
you have to approach a target showing similar signs of protection.
This is my first tut, so if you have questions, comments or of
course if you have something to critizise, then join ...

"#cracking4newbies"-Channel on IRC (EFNET)

and tell me your sorrows. I will be glad to change things in here,
that you think are wrong or difficult to understand (if I think
that too ;]). Hope you had fun reading and cr@cking and watch out 
for more to come!
Of course this is for EDUCATIONAL purpose only. To help under-
standing, what the difference between registered and unregistered
version is. As you saw, not much ... "01" rulez here ...
and besides 14 days are too short to evaluate ... ;]

GREETZ & THANKZ(no order)

CoRN2, Vizion(some Beer?;]), ___mP(!), Wink,|caligo|, _masta_, sauron,
^pain^, sentinel^, Ghostrdr, Skater, Technoid, Slashing, Kurnitoz,
LordVader and the whole [RTA], _random, axxess, |Fresh|, _ryder_,
Intruder, i_magnus, Quantico, Raimi, RaimIO!, Raytrace, Bulldozer,
Tin, _RudeBoy_, teraphy, fravia+, +ORC (tutes) and the whole MEX!

the whole #cracking4newbies! Be there or don't!