Corel Ventura 7 trial: Crack it the hard way
Some advices for using the tools with efficiency
10 May 1998
by JaZZ
Courtesy of reverser's page of reverse engineering
slighly edited by reverser+
Well... an AMAZING essay! JaZZ entered the scene already with his "What's new with timelock", but now doubles with a Ba-Whom! A great essay:
1) cracking (hard) targets for purest reversing pleasure (what a difference... in results!)
2) Showing a technique and not just a banal "Hey guys, look how I diddit")
3) Teaching AT THE SAME TIME advanced and intermediate/new readers some USEFUL tricks, and "must know":
Raw Data Offset         008D8600
Raw Data Size           000F7200
Ever found this "raw" stuff dumping PEs? Here you'll see (among other precious things) how important this is...
...awaiting your essays on whatever (difficult) your old collection of CD will give you, JaZZ! (and many reader would be amazed by the reversing subtilities (and lessons) that can be found even inside old protection schemes...
There is a crack, a crack in everything That's how the light gets in
( )Beginner ( )Intermediate (x)Advanced ( )Expert

In a very clever essay, "Cracking the Corel/Elan commercial protection scheme", +ReZiDeNt explain how to bruteforce any Corel trial by intercepting the date params. In this one, I'd like to propose an alternative to this, I mean bypassing the Elan wrapper at all. More than simply cracking an app, i'd like to show how the powerful features of our tools can be used to defeat what has been designed to fool ourselves at our funny game.
Corel Ventura 7 trial: Crack it the hard way
Some advices for using the tools with efficiency
Written by JaZZ

Just wandering in my old CDs, looking for the stuff of a good cracking session, I fell on a thing called "ventura 7", and I noticed that i had never try any Corel scheme before (until now, that is...). Well, before any attempt, as I always listen to the advices of the older ones :-), let's have a quick look at reverser+'s for any related essay...Hmm, one by +ReZiDeNt, the sort of fellow that doesn't seem to be a nothing...So this corel stuff looked challenging, I then decided NOT to read the above essay for the moment, just try it myself first, and see if we came to similar conclusions.

Tools required
dumppe (or any PE file dumper)
optionnal: wdasm89 (for convenient listings)
Target's URL/FTP
Obviously you WON'T download such a monstrosity : 108 Mb of -overbloated, need to precise ?- code. Just check out for a Corel trial on your CDs, as what follows is more thought as a "generic" crack for this kind of protection. I found mine on the "windows news" french mag december 97 issue.

Once again we couldn't have care LESS about this kind of target, (this one seems to be a sort of "computer assisted publishing" stuff, but i cannot really say :-) . Anyway, who could be silly enough to use a program whose main exe is 11.5MB large, almost crashing the PC when loading ? By the way, as you'll see, it has a pretty decent protection scheme, and then deserved to be ... cracked (neither bought nor used of course).
First of all, with this scheme, you need to have a working trial. Having an expired one, you're very unlikely to restart it, believe me. Yet it's pretty easy to have a functionnal app, just use filemon and regmon (I assume my reader does know how to use them), delete what has to be and reinstall the whole crap - this is already some kinda crack isn't it, but we'll go further-
In the tools required section, I mentionned wdasm as optionnal, as it simply crashed when loading the huge ventura.exe. I Finally manage to disassemble it, but this is mainly a living approach, a dead listing one would be impossible in this case. At first, a deep knowledge of the exe will be provided by a PE analyser (I use dumppe. You'll find it at +mammon's amazing site). What do we learn here ? (I just dump the interesting stuff, meaning the one I understand ;-)
Magic                                       010B
Linker Version                              3.00
Size of Code                            0001A600
Size of Initialized Data                00AE5600
Size of Uninitialized Data              00000000
Address of Entry Point                  00AEC690
Base of Code                            00AEC000
Base of Data                            00001000
Image Base                              00400000
Section Alignment                       00001000
File Alignment                          00000200
Operating System Version                    4.00
..... then follows the description of the "objects" of ventura.exe:
Section Table
01  0000001 	Virtual Address         00001000
		Virtual Size            008D7F7E
		Raw Data Offset         00000600
		Raw Data Size           008D8000
		Relocation Offset       00000000
			Initialized Data

02  0000002 	Virtual Address         008D9000
		Virtual Size            000F7098
		Raw Data Offset         008D8600
		Raw Data Size           000F7200
		Relocation Offset       00000000
			Initialized Data
..... a few more follows, and then:
0B  0000011 	Virtual Address         00AEC000
		Virtual Size            0001A415
		Raw Data Offset         00AAC800
		Raw Data Size           0001A600
		Relocation Offset       00000000

What a surprise! Only ONE object of code, and only 1A415 (107541) bytes long. Without any doubt, the rest is mainly encrypted code. Look at the first object: It's qualified "initialized data" and it's 8D7F7E (9273214) bytes long. Don't you feel (with very little Zen) this is the main stuff, and the tiny object of code is the Elan crap ? In addition you get the entry point, It's well located in this piece of code. For those who don't know, the adress given is RELATED to the "image base" (it's called Related Virtual Adress), that means to have the real entry point when it'll be loaded, you'll have to sum the image base+the RVA of the entry point, here leading to:

Remark: all the information beginning with "RAW..." is very precious too: it gives us both the Offset & length of the object in the file. It's then mathematically very simple to locate a byte in the file (you may have noticed that wdasm does it...Look at the bottom), without searching any hex pattern, when knowing its adress in softice (we assume it's not relocated as stated in the header, anyway if the loader had the nasty idea to relocate the whole thing, it would crash everything for almost all the code is crypted). A simple example: I want to patch at adress EEF123, thats where lies the protection !
1)get the offset within the object: EEF123-(AEC000+400000)=3123
2)compute the offset in ventura.exe file (AAC800 is the "raw data offset" -this means file offset- of the "0B" object): 3123+AAC800=AAF923
3) check if the contents are really the same :-)

You may wonder why i'm explaining that. Simply as a trick to bpx the entrypoint of a target with the "minimal" tools, as the loader32 won't break at the entry (any ideas why?). So launch the monster,CTRL D, addr ventura, bpx EEC690, CTRL D, quit the app, restart, (follow me ?) it should have break right !
Well, now just sit and sip a .... and trace it for a few minutes, and no matter what COREL stuff you are using it'll undoubtly be the same. Dya see what's going on ? Over and over.... the same code. Undercover a lotta thing certainly happen, which you don't see, unless you trace deep! And obviously they dont want us to know where the real app starts. But now look closer at this huge "switch/case" block and you'll realize it has a great weakness:

* Referenced by :at least 60 jmps !
:00EEC6F0 A1CC39EE00              mov eax, dword ptr [00EE39CC]
:00EEC6F5 8B08                    mov ecx, dword ptr [eax]
:00EEC6F7 8BC1                    mov eax, ecx
:00EEC6F9 890DB876EE00            mov dword ptr [00EE76B8], ecx
:00EEC6FF 25FFFF0000              and eax, 0000FFFF
:00EEC704 0135CC39EE00            add dword ptr [00EE39CC], esi
:00EEC70A A3BC76EE00              mov dword ptr [00EE76BC], eax
:00EEC70F 8BC1                    mov eax, ecx
:00EEC711 250000FFFF              and eax, FFFF0000
:00EEC716 3D00004203              cmp eax, 03420000
:00EEC71B 7713                    ja 00EEC730
:00EEC71D 0F845A020000            je 00EEC97D
:00EEC723 3D0000E400              cmp eax, 00E40000
:00EEC728 0F840F020000            je 00EEC93D
:00EEC72E EBC0                    jmp 00EEC6F0
:00EEC730 3D00000407              cmp eax, 07040000
:00EEC735 7713                    ja 00EEC74A
:00EEC737 0F84C2020000            je 00EEC9FF
:00EEC73D 3D00001106              cmp eax, 06110000
:00EEC742 0F8457020000            je 00EEC99F
:00EEC748 EBA6                    jmp 00EEC6F0
:00EEC74A 3D00007D09              cmp eax, 097D0000
:00EEC74F 7713                    ja 00EEC764
:00EEC751 0F84CC020000            je 00EECA23
:00EEC757 3D00006F09              cmp eax, 096F0000
:00EEC75C 0F8495080000            je 00EECFF7
:00EEC762 EB8C                    jmp 00EEC6F0
:00EEC764 3D00000411              cmp eax, 11040000
:00EEC769 7716                    ja 00EEC781
:00EEC76B 0F8408030000            je 00EECA79
:00EEC771 3D00009210              cmp eax, 10920000
:00EEC776 0F84E2020000            je 00EECA5E
:00EEC77C E96FFFFFFF              jmp 00EEC6F0
.... and over and over....
This will allow us to step out this trap: we'll just bpx EEC6F0 if bpcount==... Of course you got to find the right value. I personnaly use some kind of "dichotomy": my first increment is 0x40. Sice will pop 3 times and the app starts. So the right value is between C0 and 100. Then I set the bpcount to C0, and when sice pops I lower it to 20. It'll break just once. So the value is between EO and 100. And so on with the "increment step" dividing by 2 each time. Note that when you're here, you can even finish with a banal bpx EEC6F0 as it'll break 32 times max, so it won't hurt your hands too much. Finally this code is executed (for me) exactly EE (238) times. Some F10 keypress will then easily get you to the real startpoint of the babe.
This is the exit:
:00EED00F 33C9                    xor ecx, ecx
:00EED011 8A88F0D0EE00            mov cl, byte ptr [eax+00EED0F0]
:00EED017 FF248DDCD0EE00          jmp dword ptr [4*ecx+00EED0DC]

which goes here:
:00EED0B5 8B4510                  mov eax, dword ptr [ebp+10]
:00EED0B8 8B4D0C                  mov ecx, dword ptr [ebp+0C]
:00EED0BB 50                      push eax
:00EED0BC 8B5508                  mov edx, dword ptr [ebp+08]
:00EED0BF 51                      push ecx
:00EED0C0 52                      push edx
:00EED0C1 FF157430EE00            call dword ptr [00EE3074] ---> this is C552D0, the entry point of the app
:00EED0C7 8B4DF0                  mov ecx, dword ptr [ebp-10]
:00EED0CA 5F                      pop edi
:00EED0CB 64890D00000000          mov dword ptr fs:[00000000], ecx
:00EED0D2 5E                      pop esi
:00EED0D3 5B                      pop ebx
:00EED0D4 8BE5                    mov esp, ebp
:00EED0D6 5D                      pop ebp
:00EED0D7 C20C00                  ret 000C

Up to this point, you may think that the crack is over, but alas, they've been mighty enough these Elan fellows to encrypt 9273214 bytes of good code. You can see that when starting in EEC690, it's pure bogus in C552D0. By the way you can't see it as -quoting an old master - "this moronic OS moves pages all the time", causing sice to dump ?? in place of the bytes. So here's a trick to force W$95 to commit it in physical memory: assemble at my_adr (wherever you feel like it, may i suggest esp-200 ?)

push eax
mov eax, [the_adress_you_want]
pop eax
jmp where_you_came_from
Using bpx my_adr ,and then g=my_adr , the page will be fully loaded. One more tip: if you just want to terminate after, assemble a: INT 3 in place of the jump. It'll generally kill the task right without damaging the already unstable windoze.
Back to the crack.We'll have to work a little more to have this code restored to its initial untouched state whenever WE want it to.
The best and fast way to fish the decryption routine is to bpm C552D0. 100 % sure we'll land right into it !
So we do it, and this is it:
:00EED100 53                      push ebx
:00EED101 33C0                    xor eax, eax
:00EED103 56                      push esi
:00EED104 57                      push edi
:00EED105 8B742414                mov esi, dword ptr [esp+14]
:00EED109 C1EE02                  shr esi, 02
:00EED10C 8BCE                    mov ecx, esi
:00EED10E 4E                      dec esi
:00EED10F 85C9                    test ecx, ecx
:00EED111 7431                    je 00EED144
:00EED113 8B542410                mov edx, dword ptr [esp+10]
:00EED117 8B7C2418                mov edi, dword ptr [esp+18]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:00EED11B 8BCF                    mov ecx, edi
:00EED11D 8BDF                    mov ebx, edi
:00EED11F C1E104                  shl ecx, 04
:00EED122 83C204                  add edx, 00000004
:00EED125 C1E305                  shl ebx, 05
:00EED128 03CF                    add ecx, edi
:00EED12A C1E909                  shr ecx, 09
:00EED12D 33CB                    xor ecx, ebx
:00EED12F 03F9                    add edi, ecx
:00EED131 8B4AFC                  mov ecx, dword ptr [edx-04]  --> initial bytes
:00EED134 33CF                    xor ecx, edi  --> a banal XOR  :=)
:00EED136 03C1                    add eax, ecx
:00EED138 894AFC                  mov dword ptr [edx-04], ecx  --> replace with decrypted bytes
:00EED13B 33F8                    xor edi, eax
:00EED13D 8BCE                    mov ecx, esi
:00EED13F 4E                      dec esi
:00EED140 85C9                    test ecx, ecx
:00EED142 75D7                    jne 00EED11B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:00EED144 5F                      pop edi
:00EED145 5E                      pop esi
:00EED146 5B                      pop ebx
:00EED147 C20C00                  ret 000C
Is this what they call DES in their adds ? This simple XORing thing ! thought it'd be more tricky !
Setting a break on EED100 and a: dex 0 esp+4 we'll see immediately that the second call is the good one (Use shift F3 to have a dword format).
The routine has three params, referenced in the above code by:
[esp+10]: adress of code to be decrypted (401000)
[esp+14]: length (8D7F7E)
[esp+18]: the initial xor key (8A7EAA7A).

So a possible (small) crack for the (big) babe may be
push 8A7EAA7A ;the above params
push 8D7F7E
push 401000
call EED100  ;decrypt
jmp C552D0   ;jmp to main program
I spare you the suspense; It won't work either, as none of the win32 API pointers in the decrypted code is properly initialised. The initial decrypted code begins with:
PUSH D42660
PUSH eax
MOV fs:[0],esp
SUB esp,60
PUSH ebx
PUSH esi
PUSH edi
MOV [EBP-18],esp
CALL [00E442BC] ;initially bogus, it'll finally be a CALL [kernel32!GetVersion]
etc....         ;but for the moment it leads to a crash!
Don't think too long, use a rough bpm E442BC to locate the dedicated routine. & now you're here:
:00EEC3C0 53                      push ebx
:00EEC3C1 56                      push esi
:00EEC3C2 57                      push edi
:00EEC3C3 8B1D7030EE00            mov ebx, dword ptr [00EE3070]  --> Imagebase of the executable=400000
:00EEC3C9 55                      push ebp
:00EEC3CA 031D8400EE00            add ebx, dword ptr [00EE0084] -->RVA of the object= A43000
:00EEC3D0 837B1000                cmp dword ptr [ebx+10], 00000000
:00EEC3D4 7460                    je 00EEC436

* Reference To: KERNEL32.GetProcAddress, Ord:0103h
:00EEC3D6 8B3DE8B1EE00            mov edi, dword ptr [00EEB1E8]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:00EEC3DC 8B430C                  mov eax, dword ptr [ebx+0C]
:00EEC3DF 03057030EE00            add eax, dword ptr [00EE3070]  --> compute the adress of the dll name
:00EEC3E5 50                      push eax                                |
:00EEC3E6 FF15ECB1EE00            Call KERNEL32.LoadLibraryA
:00EEC3EC 8BE8                    mov ebp, eax
:00EEC3EE 85ED                    test ebp, ebp
:00EEC3F0 744B                    je 00EEC43D
:00EEC3F2 8B7310                  mov esi, dword ptr [ebx+10]
:00EEC3F5 03357030EE00            add esi, dword ptr [00EE3070]
:00EEC3FB 833E00                  cmp dword ptr [esi], 00000000
:00EEC3FE 742D                    je 00EEC42D
:00EEC400 8B06                    mov eax, dword ptr [esi]
:00EEC402 A900000080              test eax, 80000000
:00EEC407 7407                    je 00EEC410
:00EEC409 25FFFF0000              and eax, 0000FFFF
:00EEC40E EB0B                    jmp 00EEC41B
:00EEC410 8B0E                    mov ecx, dword ptr [esi]
:00EEC412 A17030EE00              mov eax, dword ptr [00EE3070]
:00EEC417 8D440102                lea eax, dword ptr [ecx+eax+02]
:00EEC41B 50                      push eax
:00EEC41C 55                      push ebp
:00EEC41D FFD7                    call edi  ---> this is GetProcAdress
:00EEC41F 8906                    mov dword ptr [esi], eax  --> Here ! Install the handler.
:00EEC421 85C0                    test eax, eax
:00EEC423 7429                    je 00EEC44E
:00EEC425 83C604                  add esi, 00000004
:00EEC428 833E00                  cmp dword ptr [esi], 00000000
:00EEC42B 75D3                    jne 00EEC400
:00EEC42D 83C314                  add ebx, 00000014
:00EEC430 837B1000                cmp dword ptr [ebx+10], 00000000
:00EEC434 75A6                    jne 00EEC3DC
:00EEC436 33C0                    xor eax, eax
:00EEC438 5D                      pop ebp
:00EEC439 5F                      pop edi
:00EEC43A 5E                      pop esi
:00EEC43B 5B                      pop ebx
:00EEC43C C3                      ret
The above routine is a double loop that load a group of dll, and install (for us !) the adress of every proc used, this for each dll loaded. Its only necessary params are the imagebase in EE3070 and the RVA of the object in EE0084. As the routine is called several times, we got to init them ourselves before the call. A quick look at all the other adress involved show that they're OK as soon as you load the exe. So all the lights seem green now :-) Our unfinished crack now become:
push 8A7EAA7A  ;the decryption part
push 8D7F7E
push 401000
call EED100
mov eax,400000 ; the API handlers part
mov [EE3070],eax
mov eax,A43000
mov [EE0084],eax
call EEC3C0 
jmp C552D0     ;jmp to main program
And this is it. It's ours for ever.

Final Notes
The only interest of this target was its protection scheme. As it's completely reversed, and therefore no longer exists, please trash it right now.
Sure, I spent some (good) time to do it (and much more to write the essay ;-), but all being well considered it wasn't that difficult. In particular, the main weakness is, IMO, that the prot. scheme is completely independant (in terms of "shared" memory ressources) from the code it protects (it seems to be a common problem of all this kind of wrappers). As a result, the app functions as soon as you manage to kick off the Elan stuff. Don't you think that could be well improved ?

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.

You are deep inside reverser's page of reverse engineering, choose your way out:

redhomepage redlinks redsearch_forms red+ORC redstudents' essays redacademy database
redreality cracking redhow to search redjavascript wars
redtools redanonymity academy redcocktails redantismut CGI-scripts redmail_reverser
redIs reverse engineering legal?