Lesson 4 : Time protections - A short history of time
(Best viewed with good old Courier).
Time protections in Windows,
For 'time protections' we intend a serie of protection schemes
which are aimed to restrict the use of an application
ONE
-to a predetermined amount of days, say 30 days, starting with
the first day of installation... 'CINDERELLA' TIME PROTECTIONS
TWO
-to a predetermined period of time (ending at a specific fixed
date) independently from the start date... 'BEST_BEFORE' TIME
PROTECTIONS
THREE
-to a predetermined amount of minutes and/or seconds each time
you fire them... 'COUNTDOWN' TIME PROTECTIONS
FOUR
-to a predetermined amount of 'times' you use them, say 30
times. Strictly speaking these protections are not 'time'
dependent, but since their schemas are more or less on the
same lines as in the cases ONE, TWO and THREE, we will examine
them inside this part of my tutorial. Let's call them 'QUIVER'
protections since, as with a quiver, you only have a
predetermined amount of 'arrows' to shoot (and if you never
went fishing with bow and arrows, on a mountain river, you do
not know what's real zen... the fish springs out suddendly, but
you 'knew' it, and your fingers had already reacted... a lot of
broken arrows on the rocks, though :=)
As first example I have chosen a double protected
application: it has a time protection (of the 'Cinderella' type,
limited to 90 days) as well as a 'quiver' protection
scheme, which is the other -not time bounded- current variante
of the shareware protections... i.e. you should use this program
only 25 times before a protection lock.
It's a relatively 'old' windows protection (april 1995). I found
the program on a cheap cd-rom, which I bought (in a bunch with
9 others) a month ago: 6000 megabytes of bad protected software
for the price of a good glass of wine! PCPLUS SUPER CD n°13,
originally edited in July 1995. I believe it should be pretty
easy to find it or to find this program on the Web if you do not
already have it inside your collection of cheap CD-ROM. Another
advantage of this program, from our perspective, is that the
whole PCFILE.EXE represents de facto the protection scheme
itself... not excessively overbloated: only 8912 bytes, when the
'real' application works inside the (huge and overbloated)
pcf.dll, which will be called only if the user passes the
protection. You can easily print the WHOLE disassembled listing
of PCFILE.EXE (46 Wordperfect pages), that you'll quickly get
through wcb (for instance). For once you'll have a COMPLETE and
COMPLICATED protection scheme under your eyes.
Basically we'll study here the 'beginning' of more complex
time protection schemes, the ones we'll crack with our later
lessons. Some protection elements are here still 'naïv', but the
protectionists have -at least- worked a little against easy
cracks... which makes this protection even more interesting for
us :=)
This program shows even a 'nasty' behaviour: should you use
it after the locking snapped, it will obliterate the whole (main)
pcf.dll from your harddisk, without any warning. This obviously
does not mean anything at all here, but it's the secret to more
advanced (and nastier) protection schemes, so you better have a
look at it too. Nice, enough let's start now.
[PCFILE] (aka the 'dll counter' method)
PCFILE, version 8, (PCFILE.EXE, 8912 bytes, 17 apr 1995, Atlantic
Coast software) is a database program which will be disabled
after having 90 days from its first use or after having used it
25 times, whichever comes first.
We'll begin as usual: just use your wordprocessor search
capacities to search inside the whole directory (and
subdirectories) of PCFILE for words like 'demo' 'order' 'contact'
'expire' 'disabling' 'evaluation' and so on (alternatively, like
I do, you can write your own little C utility to do it even more
quickly and automatically on the whole 600 megabytes CD-ROM you
have inserted on your drive :=)... You'll see immediately that
only two of the PC-files can interest us: PCFILE.EXE and
PCFRES.DLL. A quick 'turbodumping' of PCFILE.EXE itself will
fetch all filenames and nagstrings we need to be happy from the
end of the file... here they are:
A) 010C PCF.DAT
B) 0114 PCF.DLL
1) 2.011C PC-FIle demo has been disabled...
2) 2.01A2 The PC-File demo program has reached the maximum
allowable 25 sessions...
3) 2.0298 This demo version of PC-File 8 is designed...
4) 2.035A The PC-File demo program has reached... 90 days
5) 2.0474 This is the last demo session...
When I see something like this I know that the crack is already
made... it's so easy I can't understand why they don't just give
their software away for free... money I suppose, people seem to
be obsessed with this prepuberal problem... how stupid, besides:
neminem pecunia divitem fecit.
Beside, snooping inside files can be graet fun! At times you find
some 'real' info inside them... Have a look at lotus Wordpro,
for instance, you'll read something like: 'You idiot! Can't flow
a partial paragraph!'; 'Yow! Need to SetFoundry() on this object!';
'Dude! I couldn't find myself!'; 'Ain't nothing to pop!' and many
other amenities which throw a crude light on the life (and possible
blunders) of commercial programmers and on the well know fact
that most application are throw out FULL of bugs just in order
to make money ('bugs for bucks').
OK, back to our cracking: let's just search for the above NUMBERS
inside the code of PCFILE:
1) PC-File has been disabled: 011C
1.1100 >C8040100 enter 0104, 00
1.1104 56 push si
1.1105 C70632060000 mov word ptr [0632], 0000
1.110B 6A00 push 0000
1.110D B81401 mov ax, 0114; THIS is PCF.DLL
1.1110 8946FE mov [bp-02], ax
1.1113 50 push ax
1.1114 9A2E0D0212 call 1:0D2E ;what happens here?
1.1119 83C404 add sp, 0004
1.111C 40 inc ax
1.111D 7532 jne 1151
1.111F 1E push ds
1.1120 681C01 push 011C ;HERE****
1.1123 8D86FCFE lea ax, [bp-0104]
1.1127 16 push ss
1.1128 50 push ax
1.1129 9A6E110000 call USER._WSPRINTF
Therefore this target will be disabled after a check at the
beginning of WinMain (1.1100) if ax, after having been
incremented is non zero. We should have a look at the routine at
1:0D2E to see what happens... but let's first check the other
nagstrings... no point in delving immediatly inside routines.
2) The PC-File demo has reached the maximum allowable 25
sessions... 01A2
1.11C9 >807EFC66 cmp byte ptr [bp-04], 66
1.11CD 7C0F jl 11DE
1.11CF 6AFF push FFFF
1.11D1 9A36120000 call USER.MESSAGEBEEP
1.11D6 6A00 push 0000
1.11D8 1E push ds
1.11D9 68A201 push 01A2 ; HERE ****
1.11DC EB62 jmp 1240
Therefore 25 sessions if byte ptr [bp-04] >= 66 (as you can see,
the protectionists did not use anything vaguely similar to 25dec,
which is 19hex).
3) This demo version of PC-File 8 is designed... : 0298
1.11DE >807EFC4D cmp byte ptr [bp-04], 4D
1.11E2 7518 jne 11FC
1.11E4 6A00 push 0000
1.11E6 1E push ds
1.11E7 689802 push 0298 ;HERE ****
1.11EA 1E push ds
1.11EB FF361000 push word ptr [0010]
1.11EF 6A00 push 0000
1.11F1 9A48120000 call USER.MESSAGEBOX
1.11F6 C70632060100 mov word ptr [0632], 1 ;Flag 632!
This 'Welcome nagged user' message appears therefore only THE
FIRST time you run, when our byte ptr [bp-04] has been set to 4D.
That figures: 66h - 4Dh = 19h, which are the 25 times allowed...
the programmers from Atlantic Coast must have thought something
like 'Stupid crackers will not fetch our nice clever protection:
he'll be searching for byte 19h! Ah!' Note the flag set in
location [632] if it's the first run :=)
4) The PC-File demo program has reached... 90 days : 035A
1.1211 833E320600 cmp word ptr [0632], 0000
1.1216 7565 jne 127D
1.1218 A13406 mov ax, [0634]
1.121B 8B163606 mov dx, [0636]
1.121F 2B062C06 sub ax, [062C]
1.1223 1B162E06 sbb dx, [062E]
1.1227 83FA76 cmp dx, 0076
1.122A 7251 jb 127D
1.122C 7705 ja 1233
1.122E 3D00A7 cmp ax, A700
1.1231 764A jbe 127D
1.1233 >6AFF push FFFF
1.1235 9A3C130000 call USER.MESSAGEBEEP
1.123A 6A00 push 0000
1.123C 1E push ds
1.123D 685A03 push 035A ; HERE!
There, location [634] in ax and location [636] in dx.
ax subtracts location [62C] and dx subtracts with carry location
[62E]. Is it more than 76h? (Which is 118 dec), Tell user he has
reached 90 days. Is it exactly 76h? Then have a look at ax, if
it is more than A700 then tell user the same.
5) This is the last demo session... : 0474
1.132D >56 push si
1.132E 9AFFFF0000 call KERNEL._LCLOSE
1.1333 807EFC66 cmp byte ptr [bp-04], 66
1.1337 7C19 jl 1352
1.1339 6AFF push FFFF
1.133B 9AFFFF0000 call USER.MESSAGEBEEP
1.1340 6A00 push 0000
1.1342 1E push ds
1.1343 687404 push 0474 ;HERE****
1.1346 1E push ds
1.1347 FF361000 push word ptr [0010]
1.134B 6A10 push 0010
1.134D 9AFFFF0000 call USER.MESSAGEBOX
1.1352 >1E push ds
1.1353 681401 push 0114 ;this is PCF.DLL
1.1356 6A01 push 0001
1.1358 9AFFFF0000 call KERNEL.WINEXEC ;exec PCF.DLL
And here, finally we have our good old [bp-04] -once more-
compared to 66h. Notice that there is no Jumpequal nor
jumpgreater check. This means that the program ALREADY KNOWS that
the user has reached here for the first time the fatidic 66. This
means (of course) that this code will be examined AFTER having
incremented the counter of the protection, which must therefore
happen somewhere between 1.123D and 1.132D (the end of routine
4 and the beginning of routine 5). If you have printed the whole
disassembled listing of PCFILE.EXE and if you have read my other
lessons about dead listing (-> 9.3 and 9.4) you do not need any
more to read the following part of this lesson. Choose your
armchair and sit there with a pen, your listing and a good
cocktail (may I suggest a good Martini-Wodka? Don't use anything
else but Moskowskaja). The moment to start 'feeling' the code has
come! You can do everything alone. Write colored arrows on your
listing! The first (or the fourth) simphony of Mahler on your CD!
Everything will appear!
Indeed, if you prefer to follow here, behold: at 1.12B2 we
have a call KERNEL._LOPEN wich opens the file PCF.DLL (0114):
1.12AD 681401 push 0114 ;want pcf.dll
1.12B0 6A01 push 0001
1.12B2 9AFFFF0000 call KERNEL._LOPEN ;open it
and at 1.12CD we have the exact point where, inside pcf.dll, a
byte will be modified (at 10AF8):
1.12C6 6A01 push 0001
1.12C8 68F80A push 0AF8
1.12CB 6A00 push 0000
1.12CD 9AFFFF0000 call KERNEL._LLSEEK
The only modification takes place therefore inside PCF.DLL, a
monstruosity of 1088832 bytes, where location 10af8 grows WITHOUT
any change in the date of the dll. You can easily check this:
* copy pcf.dll pcf.ded
* (run pcfile a couple of time)
* fc /b pcf.dll pcf.ded
fc /b is file compare /binary, good old (and quick) dos, duh?
And this is what you get...
Comparing files PCF.DLL and PCF.DED
00010AF8: 55 50
Et voila mesdames et messieurs, found the other way round, please
note that this more 'practical' method can also be used *before*
beginning the dead listing examination of the file (and would
have given you the '0AF8' string to search for).
Well, what did we learn? A lot: an hidden counter grows in
another file without leaving many traces. The 'quiver'
protection snaps after growing more than 66h, having started at
4Dh. The flag for first time user is inside [0632]. [0634] and
[0636] are used for the current date, [062C] and [062E] are the
original date against which they are checked in a funny way.
There are two different protections, therefore we'll need
two different cracks to deprotect this cram. Let's begin with the
easiest one.
Our FIRST crack, must destroy the counter that increases inside
pcf.dll (the '25' session allowance). This will be made cracking
following instruction:
1.12F3 FE46FC inc byte ptr [bp-04]
which is obviously the increasing instruction we are searching
for (BECAUSE it's the only 'inc byte ptr' in the whole stupid
program, AND because it is located short after the _LLSEEK, AND
because it's incrementing nobody else than our good old [bp-
04]... what do you want more, a neon green flashing arrow light
on the top of it?)
We'll very simply "noop" this instruction, transforming it, for
instance, in 40 90 48 (inc ax, nop, dec ax = do nothing). Well,
yes, that was it for the '25 sessions' lock protection, thankyou,
you may use the program a zillion times now. What now? Ah, yes,
the DATE lock, let's have a look once more at it:
1.1218 A13406 mov ax, [0634]
1.121B 8B163606 mov dx, [0636]
1.121F 2B062C06 sub ax, [062C]
1.1223 1B162E06 sbb dx, [062E]
1.1227 83FA76 cmp dx, 0076 ;118 (-90=1c)
1.122A 7251 jb 127D
1.122C 7705 ja 1233
1.122E 3D00A7 cmp ax, A700 ;(42572)
1.1231 764A jbe 127D
1.1233 >6AFF push FFFF
1.1235 9A3C130000 call USER.MESSAGEBEEP
1.123A 6A00 push 0000
1.123C 1E push ds
1.123D 685A03 push 035A ;HERE! 90 days!
Therefore, if location [636] is > than 76, the nag snaps.
This 76 is calculated through what SEEMS a simple comparison
between the actual date and the installation date.
1.1218 A13406 mov ax, [0634] ;load date ax
1.121B 8B163606 mov dx, [0636] ;load date dx
1.121F 2B062C06 sub ax, [062C] ;subtract first date
1.1223 1B162E06 sbb dx, [062E] ;subtract first date
1.1227 83FA76 cmp dx, 0076 ;allowed limit (?)
1.122A 7251 jb 127D ;ok: you may
1.122C 7705 ja 1233 ;beggar off
1.122E 3D00A7 cmp ax, A700 ;well, what's this
1.1231 764A jbe 127D ;then?
In the reality there are various mathematical checkings
going on here, as the second check on ax = A700 shows. This DOES
NOT need to concern us much (we'll crack this code, later,
changing the 'first time user' flag), but it's useful you have
a rough understanding of what goes on inside these schemes,
therefore let's delve a little inside it.
Basically, the good old dos function GetSystemDate (21/2A)
works like this: On entry: ah = 2a
On return:
al = day of the week (0 = Sunday, 1 = Monday...)
cx = year
dh = month
dl = day
Short before the 90 days check, the protection calls two
routines:
1:09B4 (GetSystemDate) and 1:0D64 (FetchInstallationCode)
The first one fetches the date (1.9D3-1.9D7) and the Time
(21/2C, at 1.9E2), get's ONCE MORE the system date (1.9F7)
subtracts the years against 1980 (1.A20: sub cx, 07BC) and then
makes quite a lot of maniuplation of these data (around 1.C7D,
where one year LESS than the current year will be stored in
[SI+03], in order to calculate the total amount of days). The
second one prepares the numbers for the sub ax and sbb dx of the
90 days check.
As I said all this does not need to concern you much, coz
the protectionists have mad a 'protecion blunder': they have made
every time snapping depending on a flag, the one in [0632].
What happens is: THE FIRST THING this program makes, smack
at the beginning of WinMain, is to set to zero (FALSE) the
abovementioned flag:
1.1105 C70632060000 mov word ptr [0632], 0000
Only in case of first time use, this flag will be set to TRUE at
1.11F6 C70632060100 mov word ptr [0632], 0001
knowing that, anyway, as soon as the program runs again this flag
will be reset to FALSE by Winmain.
And, as we saw, this flag is checked both for the 90 days snap:
1.1211 833E320600 cmp word ptr [0632], 0000
and for the 'This is your last day Cinderella' Warning:
1.1315 >833E320600 cmp word ptr [0632], 0000
A good fundamental crack will therefore be the 'automatical'
setting to TRUE of this flag by our Winmain:
1.1105 C70632060100 mov word ptr [0632], 0001
Everytime the program runs it will believe that's the first time
it does it.
I know, theoretically, having nooped the increase inside PCF.DLL,
the counter should remain always at 4D, which would set ANEW the
flag to true every run... but we do not want the first 'welcome'
nagscreen either, do we? Therefore:
****** Crack for PCFILE version 8, 1997 ***
psedit pcf.dll
search 4E 49 44 4D (4D only if you did not run it)
modify in 4E 49 44 50 (second time run)
psedit pcfile.exe
search 83 C4 06 FE 46 FC
modify in 83 C4 06 40 90 48 (nooped increase)
search C7 06 32 06 00 00
modify in C7 06 32 06 01 00 (flag always true)
*********************************************
As second example I have chosen a fairly interesting 'CINDERELLA'
protection scheme of a Window application which can be useful for
our purposes: Link Check (Version 5.1), an application written
in august 1996. I'll crack here the Windows 3.1 version, for
reasons explained in lesson 9.4, but you'll easily find the Win95
version on the net, whose protection scheme works on the same
lines.
Link Check is a suite of three (3) diagnostic programs which
allows the user to examine different areas of the system.
1) Link Check (WLCHECK.EXE) enables the user to view the links
between an executable file and the modules it requires to run on
the system.
2) Memory Check (WMCHECK.EXE) allows the user to view, load and
unload modules currently in memory.
3) Function Check (WFCHECK.EXE) allows the user to view actual
function calls inside modules.
WLCHECK EXE 40400 24/08/96 5:10
WMCHECK EXE 37104 18/08/96 5:10
WFCHECK EXE 45424 24/08/96 5:10
WLCCOMM DLL 46960 18/08/96 5:10
KSLHOOKS DLL 29568 15/08/96 1:00
The protection scheme inside this program allows a 21 days use
of the program, then 'disables' it. Even in the first 21
'allowed' days there are some functions that are disabled,
anyway. Another interesting feature of the protection scheme, is
that once you register, an 'electronic key' will be created and
sended to you in order to unlock Link Check for the full retail
version (which, as usual, means that the shareware version you
are using CAN be unlocked).
Therefore this application:
is TIME-LIMITED
has been CRIPPLED
has some DISABLED functions
can be UNLOCKED.
A wonderful world of cracking possibilities! Let's rub our hands!
So much to find! So much to learn! Thanks, Karri Software Ltd!
(100422.3521@compuserve.com)
For these protection schemes we must use both the 'Winice' live
approach and the 'dead listing' one. (both described elsewhere
in my tutorial).
Let's begin at the beginning, i.e. searching for strings inside
the WLCHECK.EXE we'll find nothing.
You'll soon realise that the protection scheme hides inside the
two *.dll WLCCOMM.DLL & KSLHOOKS.DLL... the real problem, with
this kind of protections, is that the 'modalities' to unlock it
are not known, i.e., that you cannot just crack the unlock
procedure itself, but you must reverse engineer the program long
enough to find the 'switch' that fires your cracked 'unlock'
procedure, in order to 'register' this program and in order to
be able to use it ad libitum.
What happens with time protections?
The first problem for the protectionists is the tampering with
the system date. Even a stupid user could set the system clock
backwards in order to use a program of the CINDERELLA sort.
Your target would be easily fooled by any stupid user if it did
just set a variable [START_DATE] and then simply check the system
time with something like
IF SystemTime > [START_DATE+30] then beggar off
ELSE OK
Therefore (almost) all this program use some sort of 'diode'
location. Like diodes, which let current through in only one
direction, these locations can only grow... i.e, if you set the
system time to 1 January 2000 and then run the program, it will
throw you off, as expected, but even when you go back to your
current year and date this will be 'remembered'...and the
protection will NOT allow you any more to use the program even
should you (theoretically) still have some free 'try me' days...
your setting at year 2000 screwed up your license for ever.
IF SystemTime > [START_DATE+30] then [MARK_HERE]
ELSE continue
If [MARK_HERE] = TRUE then beggar off
ELSE OK
Let's try altering the system date on our WLCHECK.EXE target...
Woa! As I said... it does not work anymore.
It's fairly easy to get at this part through Winice: Just bpx
WritePrivateProfileString (which is a very interesting function
indeed) and then have a good look at the pointers: You'll quick
find out that KSLHOOKS (Segment 0B) writes his own xCLSID value
inside system.ini. The block of KSLHOOKS.DLL's code responsable
for this is the following:
11.0569 9AE4013500 call 7:01E4 ;'Value' and 'SYSTEM.INI'
11.056E 83C408 add sp, 8 ;adjusting stack
11.0571 8D843901 lea ax, [si+0139]
11.0575 57 push di
11.0576 50 push ax ;pushing 'xCLSID'
11.0577 8D46FA lea ax, [bp-06]
11.057A 16 push ss
11.057B 50 push ax ;pushing 'Value'
11.057C 8D468A lea ax, [bp-76]
11.057F 16 push ss
11.0580 50 push ax ;pushing '{6178-0503...}'
11.0581 8D46EE lea ax, [bp-12]
11.0584 16 push ss
11.0585 50 push ax ;pushing 'SYSTEM.INI'
11.0586 9AFFFF0000 call KERNEL.WRITEPRIVATEPROFILESTRING
11.058B 33C0 xor ax, ax
11.058D 5E pop si
11.058E 5F pop di
11.058F C9 leave
11.0590 CB retf
The call to 7.01E4 fetches the strings 'Value' and 'SYSTEM.INI'
which are 'hardwired' there byte by byte, for instance, 'INI' is
fetched like this:
7.0234 26C6440749 mov byte ptr es:[si+07], 49 ;I
7.0239 26C644084E mov byte ptr es:[si+08], 4E ;N
7.023E 26C6440949 mov byte ptr es:[si+09], 49 ;I
What is really interesting in this part of the protection scheme,
is that the function WritePrivateProfileString is one of the MOST
COMMON functions used for this kind of protections, being the
function normally used in order to 'keep track' inside an 'INI'
file of the particular configuration of an application that the
user has chosen... as a matter of fact this program creates an
hidden WLCHECK.SWL file inside c:\windows where it writes its
data, it also writes, through the above code,
[xCLSID]
Value={0000006236-0017105173-6326000000}
inside system.ini
and then it writes ANOTHER string inside the reg.dat 'register'
of the windows directory. A short digression, about registrations
in the reg.dat of the Windows directory. If you never had a look
at the reg.dat file (wich you should not have only firing
regedit.exe, but using the switch /v TROUGH THE COMMAND LINE
run!) you are in for a big surprise. If you are used to install
and de-install programs as much as I do, you'll be able to see,
for instance, real BATTLES between big or widespread software
packages (for instance Coreldraw and PaintShopPro) fought
there... but you'll also find some cryptic messages like
WB_10=VMWB20
FILTER = 000000000e
OPTION = 0000000005
TAG = 0000001857
KEY = 0000184F
or, even more cryptic:
VxDSettings = {0000006178-0419758349-4326000000}
And this is actually our target, as you can see... the first
thing you should know is that some protection schemes hyde the
date checking part of their protection inside reg.dat.
The above value is the 'ID' of our target, and the ciffer in the
'middle' varies with the date and with the passing of the time.
As we said, once the protection snaps, there is no 'normal'
way to reinstall a working copy of the program, even substituting
ALL the files with fresh ones and deleting the 'secret'
WLCHECK.SWL will not help... in order to reinstall this program
or to use it for the eternity (in 21 days chunks) you would have
to do the following every time the limit snaps:
A) regedit /v
delete key VxD
B) edit system.ini
manually delete the block
"[xCLSID]
Value={0000006236-0017105173-6326000000}"
C) attrib c:\windows\wlcheck.swl -r -s -h
del c:\windows\wlcheck.swl
D) reinstall everything anew and run 21 more days... clearly not
a satisfactory solution, exspecially given the fact that some
routines are disabled... therefore let's delve a little more
inside this protection scheme... we'll find a much neater crack,
you'll see... :=)
Since the 'legitimate' user will get 'an electronic key' from the
protectionists, there must exist, somewhere, a small menu of the
kind 'Enter your electronic key, legitimate sucker'... we could
find it searching with a little imagination (and/or zen) inside
our listings, but in these cases, it's much more quicker a small
run with WRT (Windows Resource Toolkit) by borland. Since we are
already inside KSLHOOKS.DLL, let's begin with this one.
Wrt loads kslhooks.dll and shows you immediatly that there are
only three dialog items, the last one, tagged as 'dialog 503'
represents the 'Unlock' little window: ('Please enter your key'),
which has two buttons: OK (1) and Cancel (2). Let's use WRT
'ID_tagging' option: we'll immediatly fetch the ID number of the
'Please enter your key' field: 2035.
2035 dec is 7F3 hex, therefore we now just need to search 07F3
inside our listing... and we land immediatly here:
6.00DE >8B760A mov si, [bp+0A]
6.00E1 FF760E push word ptr [bp+0E]
6.00E4 6A08 push 0008
6.00E6 9AFFFF0000 call USER.GETWINDOWLONG
6.00EB 8946FC mov [bp-04], ax
6.00EE 8956FE mov [bp-02], dx
6.00F1 83FE01 cmp si, 0001
6.00F4 7556 jne 014C
6.00F6 FF760E push word ptr [bp+0E]
6.00F9 68F307 push 07F3 ;HERE! ****
6.00FC 9AFFFF0000 call USER.GETDLGITEM
6.0101 50 push ax
6.0102 8D4698 lea ax, [bp-68]
6.0105 16 push ss
6.0106 50 push ax
6.0107 6A63 push 0063
6.0109 9AFFFF0000 call USER.GETWINDOWTEXT
6.010E 8D4698 lea ax, [bp-68]
6.0111 16 push ss
This block of code is part of an Exported function from
kslhooks.dll: KSLHOOKPROC4 - Ord:0006h
Here is the whole sequence:
:CALL_PLEASE_ENTER_ELECTROKEY
6.00DE >8B760A mov si, [bp+0A]
...
6.00F9 68F307 push 07F3 ;HERE ***
is called (being at 6.00DE) from
:ENTER 68
6.0082 C8680000 enter 0068, 00
...
6.009B 7441 je 00DE ;HERE ***
which (being at 6.00082) is called from
:PUSH_82
6.000F 68FFFF push selector KSLHOOKPROC4
6.0012 688200 push 0082 ;HERE ***
6.0015 FF36200C push word ptr [0C20]
6.0019 9AFFFF0000 call KERNEL.MAKEPROCINSTANCE
Much interesting, but we are not yet there...
let's see if we have other occurrences of our 7F3h instance
(which, as we saw through WRT, corresponds to the 'Enter your
Key' field of the 'Unlock' window). Yes, we have one more
occurrence (always inside KSLHOOKS.DLL):
4.030A >81FEF307 cmp si, 07F3 ;HERE ***
4.030E 7515 jne 0325 ;don't care if not unlock
4.0310 FF760E push word ptr [bp+0E] ;nID
4.0313 56 push si ;=7F3, =unlock, =hDlg
4.0314 9AFFFF0000 call USER.ISDLGBUTTONCHECKED
4.0319 0BC0 or ax, ax ;mashed button?
4.031B 7408 je 0325 ;Yeah, jump...
4.031D C45EFC les bx, [bp-04]
4.0320 2689B7B104 mov es:[bx+04B1], si
4.0325 >83FE02 cmp si, 0002 ;...here
Now, IsDlgButtonChecked is a 'typical' windows function with
following structure:
UINT IsDlgButtonChecked(HWND hFlg, int nID)
where the handle of the dialog box contaning the button control
is specified in hDlg. The ID value of the desired button is
passed in nID. For two-state buttons this function returns zero
if the button is unchecked and non zero if it is checked, -1 if
an error occurs.
What else can we do?
Let's search for the limit (21 days, that corresponds to 15h)
inside our code. Well, we'll find two interesting occurrences
inside the OTHER dll module: WLCCOMM.DLL:
:OCCURRENCE_1_OF_21_DAYS_LIMIT
1.3E25 >80BEFFFE15 cmp byte ptr [bp-0101], 15 ;here***
1.3E2A 7403 je 3E2F ;Please restart...
1.3E2C E9B900 jmp 3EE8 ;xor ax and retf
and now, look what we have immediately afterwards...
1.3E2F >FF760E push word ptr [bp+0E]
1.3E32 1E push ds
1.3E33 681306 push 0613 ;Please restart...
1.3E36 1E push ds
1.3E37 68EE05 push 05EE ;Retail version...
1.3E3A 6A40 push 0040
1.3E3C 9A90080000 call USER.MESSAGEBOX
1.3E41 FF760E push word ptr [bp+0E]
1.3E44 6A01 push 0001
1.3E46 9AE03E0000 call USER.ENDDIALOG
1.3E4B E99A00 jmp 3EE8 ;xor ax and retf
Now, string 0613 is
"Please restart the program for the reatil version to take
effect"
and string 05EE is
"Retail version successfully unlocked"
...clearly we have found the part of the code where the user gets
the appropriate message once he has digited the correct key
inside the unlock window in KSLHOOKS.
But let's use a little more our 'new' WRT approach. Examining the
'dialog' items through WRT, we'll see that inside WLCCOMM.DLL
there are 'two' About Link check templates, a 'nice' one (for
registered users) and a 'nag' one (for Cinderella's users).
The nice one is WLCCOMM.DIALOG 130, and its second part reads
'This copy of Link check is licensed to'
FIELD 1 = 603 (25bh)
FIELD 2 = 604 (25Ch)
The 'nag' one is WLCCOMM.DIALOG 131 and its second part reads
'UNREGISTERED Shareware notice...' with two buttons:
'How do I register' which is 601 (259h) and
What do I get for it which is 602 (25ah).
Well... let's have a look around our code... and here is
(obviously) the relevant part of it inside WLCCOMM.DLL:
1.3C60 >8B760E mov si, [bp+0E]
1.3C63 FF7606 push word ptr [bp+06]
1.3C66 6AF4 push FFF4
1.3C68 9A8A1D0000 call USER.GETWINDOWWORD
1.3C6D 56 push si
1.3C6E 685B02 push 025B ;here***
1.3C71 9A803C0000 call USER.GETDLGITEM
1.3C76 394606 cmp [bp+06], ax
1.3C79 7421 je 3C9C
1.3C7B 56 push si
1.3C7C 685C02 push 025C ;here***
1.3C7F 9ADA3C0000 call USER.GETDLGITEM
1.3C84 394606 cmp [bp+06], ax
1.3C87 7413 je 3C9C
1.3C89 FF760A push word ptr [bp+0A]
1.3C8C FF7608 push word ptr [bp+08]
1.3C8F FF7606 push word ptr [bp+06]
1.3C92 6A01 push 0001
1.3C94 9A08039E3D call KSLCONTROLCOLOR
1.3C99 E94E02 jmp 3EEA
Whereby, here is the part for the shareware user:
1.3EA6 >81FE5902 cmp si, 0259 ;How do I register?
1.3EAA 7513 jne 3EBF
1.3EAC FF760E push word ptr [bp+0E]
1.3EAF 1E push ds
1.3EB0 688B06 push 068B
1.3EB3 6A01 push 0001
1.3EB5 6A00 push 0000
1.3EB7 687217 push 1772
1.3EBA 9AD43E0000 call USER.WINHELP
1.3EBF >81FE5A02 cmp si, 025A ;What do I get for it?
1.3EC3 7523 jne 3EE8
1.3EC5 FF760E push word ptr [bp+0E]
1.3EC8 1E push ds
1.3EC9 689706 push 0697
1.3ECC 6A01 push 0001
1.3ECE 6A00 push 0000
1.3ED0 687117 push 1771
1.3ED3 9AFFFF0000 call USER.WINHELP
1.3ED8 EB0E jmp 3EE8
and as you can easily see, here lays the 'working' for the two
mushbuttons of the shareware version.
Shareware starts at 1.3EA6 and will be called from here
1.3DB9 >81FE5802 cmp si, 0258
1.3DBD 7403 je 3DC2
1.3DBF E9E400 jmp 3EA6
Unlocked version starts at 1.3C60 and will be called from here:
1.3C3E C8FE0400 enter 04FE, 00
1.3C42 57 push di
1.3C43 56 push si
1.3C44 1E push ds
1.3C45 B87938 mov ax, selector 2:0000
1.3C48 8ED8 mov ds, ax
1.3C4A 8B460C mov ax, [bp+0C]
1.3C4D 2D1900 sub ax, 0019
1.3C50 740E je 3C60 ;***here! UNLOCKED
1.3C52 2DF700 sub ax, 00F7
1.3C55 7465 je 3CBC ;copyright, 1st part
1.3C57 48 dec ax
1.3C58 7503 jne 3C5D ;(jmp 3EE8) out
1.3C5A E94901 jmp 3DA6
Well... if [bp+0C] is 19 (dec25) then we'll jump to our unlocked
routine?

<< Home