Cracking the Corel/Elan commercial protection scheme
(A 'brute force' parameter interception approach :-)
advanced
Advanced cracking series

by +ReZiDeNt

+cracker!

(24 November 1997, slightly edited by reverser+)
Courtesy of reverser'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<stdio.h> #include<stdlib.h> #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(&quot;Generic crack for *ALL* Corel trial applications, copyright 1997, +ReZiDeNt\n\n&quot;); if(argc <2) { printf("Usage: PATCH.EXE <TARGET.EXE>\n&quot;); exit(0); } fp=fopen(argv[1],&quot;r+b&quot;); if(!fp) { printf(&quot;ERROR: Unable to open file\n&quot;); exit(0); } getdate(); printf(&quot;\nSearching - please wait, this may take some time...\n&quot;); 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(&quot;ERROR: No match found\n&quot;); if(match == 1) { printf(&quot;Target found! Patching...&quot;); fseek(fp, location, SEEK_SET); fwrite(&amp;patch, sizeof(patch), 1, fp); printf(&quot;\nAll done!&quot;); } if(match &gt; 1) printf(&quot;ERROR: More than one location was found\n&quot;); fclose(fp); } /* we can't use strcmp because there might be null chars */ int cmp(char *buf, char *target) { int j=0; while(j<tlen) { if(*buf++ !="*target++)" return FALSE; j++; } return TRUE; } /* get the date and validate it */ void getdate() { int day, month, year; int leap; int invalid="FALSE;" /* patch[28]="=" day */ /* patch[36]="=" month */ /* patch[44-45]="=" year (reverse byte order!) */ printf("Enter day (dd): "); scanf("%d",&day); printf("Enter month (mm): "); scanf("%d",&month); printf("Enter year (yyyy): "); scanf("%d",&year); /* is it a leap year? */ if((year % 4)="=" 0) leap="TRUE;" else leap="FALSE;" /* only allow a four-digit year */ if(year < 1900 || year> 9999) invalid = TRUE; if(month <1 || month> 12) invalid = TRUE; switch(month) { case 1, 3, 5, 7, 8, 10, 12 : { if(day &gt; 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(&quot;ERROR: Invalid date entered\n&quot;); 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, reverser+
and of course +ORC (and anyone I forgot)!
(c) +ReZiDeNt All rights reversed
You are deep inside reverser's page of reverse engineering, choose your way out:

advanced
Advanced cracking series

redhomepage redlinks redanonymity +ORC redstudents' essays redacademy database
redtools redcocktails redantismut CGI-scripts redsearch_forms redmail_fravia
redIs reverse engineering legal?