Cracking the Corel/Elan commercial protection scheme
(A 'brute force' parameter interception approach :-)
Advanced cracking series
by +ReZiDeNt
(24 November 1997, slightly edited by fravia+)
Courtesy of fravia's page
of reverse engineering
Well, here we go: another 'commercial' protection scheme (Elan's) bytes the dust. I have
followed with interest the slow evolution of this specific reverse engineering approach, and the vivacious correspondence,
between +ReZiDeNt (who has been the 'leading force' behind this work) and other +HCUkers inside the maillist. Here is the result of their work: a commercial protection scheme exposed for what it is: pretty easy to circumvene.
I may add that I believe (personally) that Wordperfect deserves a MUCH greater spreading... for those among you that don't know nothing of software history, take notice: Wordperfect (originally a wordprocessor developed for Utah's religious nuts) was the indiscussed LEADER of the whole wordprocessor world market until the triumph of windows and Micro$oft's successful Word attack. I still use an old (very powerful) copy of Wordperfect DOS 4.2, which let's the awful anfd buggy Micro$oft's abominion byte dust any time... alas: the porting to windows of Wordperfect was slow, messy and alltogether a first-class failure: Wordperfect almost disappeared and begins only now to reappear as a
serious competitor (probably without any more chance to regain the lost ground, sadly, given Micro$oft's lmoney and clout)
The most valuable lesson for programmers that
would like to protect their software in here? DON'T
TRUST ANY COMMERCIAL PROTECTION SCHEME!. Protect yourself: your protection (if
you happen to know how to program in assembly :-) will never be so quickly (and easily) defeated... you don't believe me? I tell you what: reading the
following you'll soon find the part where +ReZiDeNt reports what the commercial
protector themselves write about their scheme. You'll probably just read it dashing, more interested in the real essay than in that rhetoric words... well, try the following: once you
have finished reading this essay, READ ONCE MORE Elan's bragging... that's an interesting lesson in itself, I believe, a lesson about hybris :-)
This essay describes an interesting "parameter interception" method: As +ReZiDeNt writes: "So we can simply locate these pushes and 'hardwire' our own dates into the
push instructions instead"... yet so simple all this was not... a good reason to insert this essay among our "advanced cracking series" selection! Enjoy!
Cracking the Corel/Elan protection scheme, by +ReZiDeNt
A 'brute force' approach :-)
Special thanks to Noose and base+metal!
Hello all!
For many months now I've been seeing messages in usenet groups from lamers
begging for cracks for Corel trial applications.
I have yet to see a working crack for any Corel trial product (except for one
which I have been unable to test - if you have made a working crack then please
accept my apologies), and I used to spend many hours attempting to crack
this scheme when I first started cracking. I failed :-).
However, recently someone posted a message to the +HCU mailing list asking
about this protection scheme - I had actually already intended to write a
short essay on what I already knew about the protection scheme, but I instead
began to discuss the various aspects of the protection with other list
subscribers, notably Noose and base+metal.
Armed with my new-found knowledge, together with the information I had
already accumulated, I began to work on a generic crack, which is what I
will describe in this essay.
Corel have been releasing quite a large number of their applications on a
30-day trial basis, including WordPerfect 7, WebMaster Suite, Corel
Draw 7, Corel Suite 8 etc. This may seem unusual to anybody familiar with
Corel's disgraceful business practises (while they are appalling, it
should be noted that Corel's behaviour pales into insignificance when
placed alongside that of its rival, Micro$oft, who seem to seek nothing
less than world domination!), and until they (and other) software companies
have a change of heart and start giving their software away cheaply or
freely (a change that I regret I do not expect to be made), us +crackers
will continue to crack their protection schemes inside-out, and anyway
warez groups will continue to thrive (Corel apps are all, complete and
registered, pushed around inside the warez sites even BEFORE they appear
in the shops... that's the sad truth for the protectors)
OK, so lets get started on the crack proper. I will use WordPerfect 7
30-day trial version...but you will find that things should be very much
the same with *any* (fairly recent) Corel trial application.
This is because Corel, in their blind and stupid greed, decided to buy
a commercial 'licensing management' package, doubtless sold as 'uncrackable'.
Well, as we know, and +ORC said, *nothing is uncrackable*.
So, dear protectionists, don't even try - just make it cheap, or even better,
free for single user... if your program is good (a big if) you'll make enough
money from professional user.
This protection scheme is made by a company called Elan (how do I know?
Just browse around the target EXE file with your favourite hex/text editor,
you'll soon see it all over the place), who seem to specialise in
protectionist software.
Let's hope that we can become their Nemesis, and continue to sound the
death-knell of all commercial protection schemes...
Anyway, I took a look at Elan's web page (http://www.elan.com) and found a
page in which they brag (not without cause, it must be said) about the
strength of their protection.
Here are a few excerpts (courtesy of Elan):
----------------------------------------------------------------
"Demo licensing allows you to count down usage over time. This is particularly
useful for demo, or evaluation software. Instead of distributing a product that
isn't fully functional, you offer a demo key that allows a fully functional
product to be fairly evaluated, then "times out" in whatever time period you
choose.
Élan goes a step further and ensures that the customer can't "fool" the demo
key by setting back the system clock."
"The user should not be able to forge (increase) the number of licenses by
cracking the license file encryption. We've chosen a cryptographic encoding
for the code and key. Both also include checksums and other encodings to
further avoid tampering. It is highly unlikely that this coding could be
cracked without a very major and costly cryptographic effort by the customer."
"The user should not be able to create fake clients that return licenses or a fake manager that
issues free licenses. The application and license manager process both authenticate each other
by sending encrypted messages back and forth. Neither the client nor the manager will accept
messages from an invalid manager or client."
"For "time-bombed" applications: The user should not be able to run an
application after its expiration date. An optional expiration date
may be included in the key, which we believe to be highly tamper-proof.
It will, for instance, stop users from setting back system clocks in
order to artificially extend a timed license."
"The developer should be able to determine the ultimate level of
security required. Élan uses the DES ("Data Encryption Standard")
encryption algorithm, the same algorithm the US governement uses for
highly sensititive information. Elan is also one of the few
companies to obtain an export license for DES."
----------------------------------------------------------------
So, this tells us quite a few interesting things about the protection, and
basically confirms our suspicions...
Now, having established its origins, I want to first discuss the behaviour of
this protection. If you have tried to make a dead listing of the target you
will find that WD32Dasm chokes with a message to the effect that the EXE header
is non-standard, and the data references will therefore no be shown.
This means that there are no strings such as 'Evaluation' or 'Trial' that
we can search for in the dead listing (nevertheless, you should make a dead
listing anyway, as we'll refer to it later)...I'm not certain whether this
resistance to disassembly is intentional, or whether it is a side effect of
the way that the protection scheme is applied - from what I've been able
to gather (from the Elan website, what Noose found out from a helpful
Elan salesman and my own observations), it seems as though some sort of
'wrapper' is applied to the target, most likely *after* compilation.
This argument is, IMHO, strengthened by the fact that the protection code
for *all* the Corel products I have come across is almost identical.
The wrapper behaves very much like a packer might - except that it checks
the date before 'unpacking' the original program code.
This unusual approach to protection is actually comparatively secure.
The current date is checked with the install date - if your time isn't up,
the code proper for the application is loaded and off you go. If however,
your time is up (e.g. the time limit has expired) the application code is
never loaded at all!
So the code is actually self-modifying (in a way).
Hmm...this means that we can't simply jump over the time checks - instead it
is necessary to delve deeper.
Another benefit (for the protectionists) of this scheme is that there is *no*
'go-ahead-nice-guy' jump!
Instead the current date/time seems to be encrypted in some way and the
resulting data used in a *massive* jump tree which is traversed *hundreds*
of times in the protection. Again, you can't jump over this code, because hidden
in this mess is the code that loads the proper application (assuming your time
isn't up).
OK, I hope I haven't confused you too much - if you haven't understood all
the above then suffice it to say that the protection scheme is quite difficult
and calls for a 'different approach' in order to reverse it.
Now, assuming you have installed a Corel trial app, set your clock forward 30
days (or back even a minute!) and then try to run the application. Of course,
it doesn't work. Now set the clock back again and try to run the program.
You'll find that it still doesn't work...obviously the protection has
set some value in either a file somewhere or in the monstrous registry.
Using Regmon and Filemon, you'll find that the relevant keys/files are:
HKEY_LOCAL_MACHINE\System\SOFTWARE\RBO (and all values it contains)
and a 'LIC' file somewhere on your hard drive (either the \windows\system directory
or in the same directory as the protected application).
This LIC file seems to always be named '123.LIC' where '123' are any
different numbers. For example, with WordPerfect 7, the file is called '101.LIC'
and located in the \windows\system directory.
For Corel Suite 8, the file is called '110.LIC' etc.
If you take a look at this key you'll see it looks very much like the below:
----------------------------------------------------------------
! # DO NOT EDIT/COPY/MOVE/TOUCH THIS FILE! # DOING SO WILL INVALIDATE
THE KEY! 1495759114997400190218696156651151
G 1 localhost 29409528605026735253388754988463352615578602168050745868
63420417881207022485101836949246508084229387790741495533 9551540371980384961018021882475297
----------------------------------------------------------------
The advertising from the Elan website claims it uses DES encryption etc.
- it may be that the LIC file format could be decoded and a 'universal'
one distributed, but I've not got the time for all that :-)
Every time you run the protected program, it writes to both the registry *and*
the LIC file...so when it expires, both are 'corrupted'. To get the program
running again you'll have to delete the registry key
'HKEY_LOCAL_MACHINE\System\SOFTWARE\RBO' *and* replace the LIC file
with the original one from the CD-ROM or wherever you installed the trial
from. You'll also have to set the date back to around the same time as you
acquired the trial version - the reason for this is that the LIC file stores
a set of dates (thoroughly encrypted, of course) between which the trial
application may run, a sort of 'window' in time...these dates are read by
the protection code (so you can't just replace the LIC file whenever it
expires, unless you also set the date back - and delete the registry keys).
Let's summarise what we now know:
1) The code is self-modifying, much like an EXE packer
2) Both a license file and registry keys are used
3) There is set 'time window' in which we may run the protected program
4) The protection takes even minutes and seconds into account (try it!)
5) Setting the date back doesn't work :-)
Taking all the above into account, you might think 'why not use a loader, such
as the Date Cracker by +gthorne?' - well, you could use such a program, and it
might work, but only if you also found a way to change the minutes etc...don't
forget that if you use a loader, all the files you save will have the wrong
date etc.
All in all, not a very elegant solution.
Instead, I propose a somewhat brutal, but nevertheless perhaps more appropriate
(IMHO) solution - why not edit the protection code that fetches the date, and
force it to return the same date each time? If you have cracked a lot of
time-trial programs before, or have looked at the entry essays for the
1998 +HCU, you'll probably know that many programs use a single function
to retrieve the current date/time and encode it somehow (I believe there
may be a standard MFC function which is often used - can anyone confirm this?).
Now, as you also are probably aware, parameters are passed to functions via
the stack (in C/C++ at least) - this means that before the call to the
encode date function, we should see a good few 'PUSH' instructions.
These will be pushing the necessary values (e.g. second, minute, hour,
day, month, year) onto the stack, where they will be retrieved by the
called function.
So we can simply locate these pushes and 'hardwire' our own dates into the
push instructions instead.
If you step though the program code (of whichever Corel app you use) you'll
see that after each call to KERNEL32.GetLocalTime there are indeed a
lot of pushes, and a call that returns a value that is suspiciously like an
encoded date...look through your dead listing for 'GetLocalTime' (there is
probably just one) and a few lines after you'll see the code I mean:
:007FB596 25FFFF0000 and eax, 0000FFFF
:007FB59B 50 push eax ; push seconds
:007FB59C 33C0 xor eax, eax
:007FB59E 668B442426 movax, word ptr [esp+26] ; load minutes
:007FB5A3 50 push eax ; push minutes
:007FB5A4 8B442428 mov eax, dword ptr [esp+28] ; load hours
:007FB5A8 25FFFF0000 and eax, 0000FFFF
:007FB5AD 50 push eax ; push hours
:007FB5AE 33C0 xor eax, eax
:007FB5B0 668B44242A mov ax,word ptr [esp+2A] ; load day
:007FB5B5 50 push eax ; push day
:007FB5B6 33C0 xor eax, eax
:007FB5B8 668B44242A mov ax, wordptr [esp+2A] ; load month
:007FB5BD 50 push eax ; push month
:007FB5BE 8B44242C mov eax, dword ptr [esp+2C] ; load year
:007FB5C2 25FFFF0000 and eax, 0000FFFF
:007FB5C7 50 push eax ; push year
:007FB5C8 E8F3190000 call 007FCFC0 ; encode date
:007FB5CD 8B8C24F0000000 mov ecx, dword ptr [esp+000000F0]
:007FB5D4 83C41C add esp, 0000001C
:007FB5D7 85C9 test ecx, ecx
:007FB5D9 7402 je 007FB5DD
:007FB5DB 8901 mov dword ptr [ecx], eax
You can imagine the call (in C) might look something like this:
encode_date(DWORD day, DWORD month, DWORD year,
DWORD day, DWORD hour, DWORD minute, DWORD second);
So this is where the date/time is encoded (including the seconds!) - all we
need to do now is change the code to push our own values, in this
case a valid date/time with the license file 'time window' that I mentioned
earlier.
To find the 'time window' if you don't already know it, try a date
near to when the magazine from which you got the CD was distributed.
Assuming, as an example, that a valid date within the 'time window' for
Corel WordPerfect 7 was 20/6/96 (20th of June 1996), we would alter the above
code to look like the below:
:007FB596 33C0 xor eax, eax ; set seconds to 0
:007FB598 90 nop
:007FB599 90 nop
:007FB59A 90 nop
:007FB59B 50 push eax ; push seconds
:007FB59C 33C0 xor eax, eax
:007FB59E66B80000 mov ax, 0000 ; set minutes to 0
:007FB5A2 90 nop
:007FB5A3 50 push eax ; push minutes
:007FB5A4 B800000000 mov eax, 00000000 ; set hours to 0
:007FB5A9 90 nop
:007FB5AA 90 nop
:007FB5AB 90 nop
:007FB5AC 90 nop
:007FB5AD 50 push eax ; push hours
:007FB5AE 33C0 xor eax, eax
:007FB5B0 66B81E00 mov ax, 001E ; set day to 30
:007FB5B4 90 nop
:007FB5B5 50 push eax ; push day
:007FB5B6 33C0 xor eax, eax
:007FB5B8 66B80600 mov ax, 0006 ; set month to 6 (June)
:007FB5BC 90 nop
:007FB5BD 50 push eax ; push month
:007FB5BE 33C0 xor eax, eax
:007FB5C0 66B8CC07 mov ax, 07CC ; set year to 1996
:007FB5C4 90 nop
:007FB5C5 90 nop
:007FB5C6 90 nop
:007FB5C7 50 push eax ;push year
:007FB5C8 E8F3190000 call 007FCFC0 ; encode date
:007FB5CD 8B8C24F0000000 mov ecx, dword ptr [esp+000000F0]
:007FB5D4 83C41C add esp, 0000001C
:007FB5D7 85C9 test ecx, ecx
:007FB5D9 7402 je 007FB5DD
:007FB5DB 8901 mov dword ptr [ecx], eax
So, we push zeros for the hours, minutes and seconds, and we push a
valid day/month/year (one that falls in the 'time window') - so every time
the protection calls this routine it will return the very same encoded
date each time! BTW, my patching above is rough and ready, with many
unnecessary nops (0x90) in it - you should of course try to patch code using
few (if any) nops. I'll leave this as a short exercise for ASM newbies, they
can try to tidy up my patch a bit, make it more elegant :-)
Don't forget, this scheme is applied after the program is created, so the code
is *exactly* the same for each application protection with the Elan scheme,
making it very easy for us +crackers to crack...I suspect we will soon see
a new 'improved' version of this scheme though...wait and see...
Thus we demonstrate once more how useless another (probably expensive)
protection scheme in the reality is.
There are still some (minor) limitations with this crack however;
* you must delete the registry key
'HKEY_LOCAL_MACHINE\System\SOFTWARE\RBO', and all values it contains.
* You'll also need to replace the appropriate LIC file with the original,
'uncorrupted' copy.
So long as you do that, and then patch the application before running it
again, it will never expire and you're free to evaluate it as long as you
feel necessary (not that you would of course, as that would be illegal ;-)
I'll tell you what, let's take this a step further and write a little C
program to search the application for the code we need to patch (remember,
it will be the *same* for every Corel/Elan application - which could be
convenient!), and then patch it with the desired date.
Following is the code to my 'generic crack', it's pretty simple but it
works fine (sorry if the formatting gets messed up...):
/* START PATCH.C */
#include
#include
#define TRUE 0 /* a few constants to make the */
#define FALSE 1 /* code more readable :-) */
#define TLEN 7 /* length of target string */
/* the patch data */
unsigned char patch[]={0x33, 0xC0, 0x90, 0x90, 0x90, 0x50, 0x33, 0xC0,
0x66, 0xB8, 0x00, 0x00, 0x90, 0x50, 0xB8, 0x00,
0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x50,
0x33, 0xC0, 0x66, 0xB8, 0x00, 0x00, 0x90, 0x50,
0x33, 0xC0, 0x66, 0xB8, 0x00, 0x00, 0x90, 0x50,
0x33, 0xC0, 0x66, 0xB8, 0x00, 0x00, 0x90, 0x90,
0x90, 0x50};
int cmp(char *buf, char *target);
void getdate(void);
void main(int argc, char *argv[])
{
FILE *fp;
unsigned char buf[TLEN];
/* below is the target string we will seach for */
unsigned char target[TLEN]={0x89, 0x4E, 0x0C, 0x8B,
0x44, 0x24, 0x20};
int c;
long int location = 0;
long int pos = 0;
int match = 0;
int found = TRUE;
printf("Generic crack for *ALL* Corel trial applications, copyright
1997, +ReZiDeNt\n\n");
if(argc <2) { printf("Usage: PATCH.EXE \n");
exit(0);
}
fp=fopen(argv[1],"r+b");
if(!fp)
{
printf("ERROR: Unable to open file\n");
exit(0);
}
getdate();
printf("\nSearching - please wait, this may take some time...\n");
while((c=fgetc(fp)) != EOF)
{
if(c == target[0])
{
pos=ftell(fp);
ungetc(c, fp);
if(fread(buf, sizeof(buf)+1, 1, fp) != NULL);
{
found = cmp(buf, target);
if(found == TRUE)
{
match++;
if(match == 1)
location = ftell(fp);
}
else
fseek(fp, pos, SEEK_SET);
}
}
}
if(match == 0)
printf("ERROR: No match found\n");
if(match == 1)
{
printf("Target found! Patching...");
fseek(fp, location, SEEK_SET);
fwrite(&patch, sizeof(patch), 1, fp);
printf("\nAll done!");
}
if(match > 1)
printf("ERROR: More than one location was found\n");
fclose(fp);
}
/* we can't use strcmp because there might be null chars */
int cmp(char *buf, char *target)
{
int j=0;
while(j 9999)
invalid = TRUE;
if(month <1 || month> 12)
invalid = TRUE;
switch(month) {
case 1,
3,
5,
7,
8,
10,
12 : {
if(day > 31 || day <1) invalid="TRUE;" } ; break; case 2 : { if(leap="=" TRUE && day> 29 || day <1) invalid="TRUE;" if(leap="=" FALSE && day> 28 || day <0) invalid="TRUE;" } ; break; default : { if(day < 1 || day> 30)
invalid = TRUE;
}
}
/* insert the new values into the patch string */
if(invalid == FALSE)
{
patch[28] = day;
patch[36] = month;
/* reverse byte order of year */
/* (quick and nasty method) :-)*/
asm {
mov ax, year;
mov patch[45], ah;
mov patch[44], al;
}
}
else
{
printf("ERROR: Invalid date entered\n");
exit(0);
}
}
/* END PATCH.C */
If you're looking for the compiled version of this crack then try the below URL:
http://rezident.home.ml.org/cracks.html
It is perhaps worth mentioning that this 'brute force' approach could be used
to reverse almost *any* Windoze-based time-trial application.
Of course, most time-trial protections are pitifully weak, and it's easier to
find the 'go-ahead-nice-buyer' jump (and you'll learn more) - but if you
come accross a protection that can't be beaten any other way, this method
should work.
Keep Cracking! +ReZiDeNt
Greetz to:
All +HCU'kers, Noose, base+metal, Aesculapius, +trurl, fravia+
and of course +ORC (and anyone I forgot)!
(c) +ReZiDeNt All rights reversed
You are deep inside fravia's page of reverse engineering,
choose your way out:
Advanced cracking series
homepage
links
anonymity
+ORC
students' essays
academy database
tools
cocktails
antismut CGI-scripts
search_forms
mail_fravia
Is reverse engineering legal?