HyperChem v5.02 - Tutorial

Historical Reference - HyperChem v5.0

http://www.hyper.com - Webpage.
ftp://ftp.hyper.com/pub/demo/ - (6.86Mb).

Welcome to another requested tutorial. In HyperChem we have something of a reversing challenge, a license manager blocks our initial evaluation, followed by a mean 14 day time-trial as well as a 50 runtime limit, theirs also a fairly ugly evaluation string as well. Lets install the software and start reversing.

The first problem you'll need to overcome will be apparent, just attempt to run HyperChem and you'll be informed that the software has yet to be activated. So lets run the included Soft License program, you'll locate your machine code (mine incidentally is 943931998) and in response you have to insert an Authorization Code, this isn't trivial, because the license manager will accept just about any key and say that its valid, try it and see.

So we are back to HyperChem, lets fire a >bpx MessageBoxA, you'll get a break at address 004BCF92 (inside chem.exe), so lets examine that location inside W32Dasm, now you can try walking back up through the code, but I warn you now, these guys were serious about you not cracking from here and I'll be suitably impressed if you find how to avoid this message box. I had to think here, I figured the program was getting the authorization code or validating it using the registry, so I fired RegMon and launched HyperChem, even with a filter your going to get a lot of breaks but look carefully for the reading of a key called "DemoKey".

Sifting the disassembly for "DemoKey", I noted the following code.

:0041B6FC PUSH 004F5C8C <-- "DemoKey".
:0041B701 LEA EAX, [EBP+FFFFFEE8]
:0041B707 PUSH EAX
:0041B708 CALL 004E2040
:0041B70D ADD ESP, 08 <-- Correct stack.
:0041B710 LEA ECX, [EBP+FFFFFF6C]
:0041B716 PUSH ECX
:0041B717 MOV EDX, [EBP+FFFFFE40]
:0041B730 CALL DWORD PTR [004F1018] <-- ADVAPI32.RegQueryValueExA.
:0041B736 TEST EAX,EAX <-- Check key exists.
:0041B738 JNZ 0041B778 <-- Jump_bad.
:0041B73A MOV EDX, [EBP+FFFFFE40]
:0041B740 MOV DWORD PTR [EBP+FFFFFD38], EDX
:0041B746 MOV EAX, [EBP+FFFFFD38] <-- Check DS here.
:0041B74C MOV ECX, [EAX] <-- ? ECX = bad code.
:0041B74E MOV DWORD PTR [EBP+FFFFFD34], ECX
:0041B754 MOV EDX, DWORD PTR [EBP+FFFFFD34] <-- Check DS again.
:0041B75A CMP EDX, DWORD PTR [EBP+FFFFFD30] <-- Check "DemoKey".
:0041B760 JNZ 0041B778 <-- Jump_bad.

This code controls our first check, don't bother >bpx RegQueryValueExA, its very tedious trying to get to this code because the registry is queried so much. Instead perform some INT 3 patching, say at the PUSH ECX. So we need to force the result of this compare or you can just query the value of your good code and enter it into the license manager, (in my case, the good code is ? ECE28598 or 3974268312).

On to the next stage. Another wretched message box appears, 14 days evaluation and a maximum of 50 runs. Time for some real zen cracking, from the disassembly I was sure the program used GetLocalTime to read and verify the date. Take a look at this code, (you might like to push your BIOS date forward after you have examined this break).

:0041A176 CALL DWORD PTR [004F12C0] <-- KERNEL32.GetLocalTime
:0041A17C SUB ESP, 00000010
:0041A17F MOV ECX, ESP <-- Save Stack Pointer.
:0041A181 MOV EDX, [EBP-10] <-- Note 07CE here = 1998 (the current year).
:0041A184 MOV DWORD PTR [ECX], EDX
:0041A186 MOV EAX, DWORD PTR [EBP-0C] <-- Note value here (current day).
:0041A189 MOV DWORD PTR [ECX+04], EAX
:0041A18C MOV EDX, DWORD PTR [EBP-08]
:0041A18F MOV DWORD PTR [ECX+08], EDX
:0041A192 MOV EAX, DWORD PTR [EBP-04]
:0041A195 MOV DWORD PTR [ECX+0C], EAX
:0041A198 CALL 0041B7B1 <-- Check the date.
:0041A19D ADD ESP, 00000010
:0041A1A0 TEST EAX,EAX <-- Good_date_Moves_EAX_to_1.
:0041A1A2 JNZ 0041A1A8 <-- Jump_good.

This is very important, here we use different parts of registers to store various parts of the date, trace inside the call 0041B7B1 and you'll find this very important section of code which we must fix.

:0041B7B7 AND EAX, 0000FFFF <-- Preparation.
:0041B7BC CMP EAX, 000007CE <-- Check_year_is_1998.
:0041B7C1 JNE 0041B7E6 <-- Bad_jump.
:0041B7C3 MOV ECX, DWORD PTR [EBP+0A]
:0041B7C6 AND ECX, 0000FFFF <-- Preparation again.
:0041B7CC CMP ECX, 0000000A <-- Check_month_for_10 (i.e. October).
:0041B7CF JG 0041B7E6 <-- Bad_jump.
:0041B7D1 MOV EDX, DWORD PTR [EBP+0A]
:0041B7D4 AND EDX, 0000FFFF <-- Preparation again.
:0041B7DA CMP EDX, 00000006 <-- Check_month_for_6 (i.e. June).
:0041B7DD JL 0041B7E6 <-- Bad_jump.
:0041B7DF MOV EAX, 00000001 <-- Good_guy.
:0041B7E4 JMP 0041B80C <-- Jump_out_of_here.

This function is critical. Unless you are very confident with your patching, I'd suggest NOP-ping away all of these jumps. When this function returns we proceed and the date is checked once again (beneath CALL 0041B80E). This CALL is also very important, your about to discover another program trick, HyperChem uses its own file hwindl.dat to track the date as well, (its in your system directory and hidden).

To reverse engineer this function successfully will require some serious work, which of course I have saved you, assess each conditional jump carefully, the first part of this function verifies some registry values so you can safely assume these are all correct, remember also how API calls work, the calls to CreateFileA and ReadFile must verify that the file exist, you should be able to track down the place where the file length is verified with 14h (20 dec). To zen, you'll note that there are many checks followed by a JNZ/JZ 0041BB66, I can advise you that you do not want to jump to this location at any cost.

Remember also that we have a number of runs check also. That is at this code, so force any jumps to ensure you make it here (addendum, theres a JGE before just before here as well which needs NOP-ping).

:0041BB4C MOV ECX, DWORD PTR [EBP+FFFFFD04] <-- Prepare.
:0041BB52 AND ECX, 0000FFFF <-- 32h = 50 decimal.
:0041BB58 CMP EAX, ECX <-- Compare EAX (times run) with 50.
:0041BB5A JGE 0041BB66 <-- Bad_jump_yet_again.

Again, remember some patching etiquette here. If you don't totally understand the code before this section you might settle for obliterating all jumps to address 0041BB66 as they are bad. So we have now patched our target, now lets remove the message box also.

The first nag box is created using MessageBoxA, so be sure to note its address and NOP it away (remembering to correct the stack by 14). The 2nd box can be found with a >bpx DialogBoxParamA, once again you can NOP it away and also correct the stack by 14. The About menu uses the same call as one of our message boxes, so if you made the changes I highlighted before then the Help/About screen will not display, in my opinion its best to leave it that way.

HyperChem v5.0

Well, this was sent to me through the +HCU as a possible new project. I would have to say that not only does this not qualify as a new project, it is simply the same thing that we have presented over and over again. At most, this might qualify for the "time protections" section. Anyway, here it is. First thing, as always, is to run the program. It quickly tells you that you cannot run this version without an "authorization code". You get this code from them, and enter it in HCLicense.EXE in order to run this program. This is the very interesting part of this target's protection.

Enter any set of numbers as the Authorization Code and it will register almost every time. It doesn't like alpha characters though. Can it really be that easy? Unfortunately not. Try running the program again and nothing has changed. So what the hell is HCLicense doing? Well, check it out with W32Dasm or SoftICE or IDA or any way you want, and it comes down to this :-

All it does is take the number you put in, and store it in a key in the registry.

The key is : HKEY_CURRENT_USER\Software\Hypercube\HyperChem\5.0\Registration\DemoKey

Well, so now all we need to do is find out where in the program it checks this key. So W32Dasm CHEM.EXE and look for 'DemoKey'. Right below where you find it, you will find the following code :-

* Reference To: ADVAPI32.RegQueryValueExA, Ord:0136h

:0041B730 CALL DWORD PTR [0050A66C] ;get the key
:0041B736 TEST EAX, EAX
:0041B738 JNE 0041B778
:0041B73A MOV EDX, DWORD PTR [EBP+FFFFFE40]
:0041B740 MOV DWORD PTR [EBP+FFFFFD38], EDX
:0041B746 MOV EAX, DWORD PTR [EBP+FFFFFD38]
:0041B74C MOV ECX, DWORD PTR [EAX] ;ECX holds code from HCLicense
:0041B74E MOV DWORD PTR [EBP+FFFFFD34], ECX
:0041B754 MOV EDX, DWORD PTR [EBP+FFFFFD34] ;now in EDX
:0041B75A CMP EDX, DWORD PTR [EBP+FFFFFD30] ;check if right
:0041B760 JNE 0041B778 ;jmp if it's not right

So, we need to prevent the jump at 41b760 from being made, as follows :-

:0041B760 7516 JNE 0041B778 ;jmp if it's not right

to :-

:0041B760 4048 INC EAX - DEC EAX ; i.e. do nothing

So now we will be able to run the program right? Well, try it out. It tells us that our evaluation has expired!. Before we even get to run it once!. What kind of shoddy programming is this?. Well, it's not hard to fix. Look for an occurrence of GetLocalTime (or bpx it in SoftICE) and you'll quickly find the code snippet below.

* Reference To: KERNEL32.GetLocalTime, Ord:00F5h

:0041A176 CALL DWORD PTR [0050A914]
:0041A198 CALL 0041B7B1 ;check if expired yet
:0041A19D ADD ESP, 10
:0041A1A0 TEST EAX, EAX ;are we?
:0041A1A2 JNE 0041A1A8 ;yes, jump away
:0041A1A4 XOR EAX, EAX ;no, go on good guy
:0041A1A6 JMP 0041A1D9

So again we need to force the jump not to be made :-

:0041A1A2 JNE 0041A1A8 ;yes, jump away

to :-

:0041A1A2 4048 INC EAX - DEC EAX ;don't ever jump

That's it, HyperChem 5.02 Evaluation version now runs as it would if you had entered a valid code, and were still in the evaluation period. There is still a nag screen at startup, which I did not bother writing details about (if you don't know how to remove it, you need to study a little more). I did begin to reverse the Authorization Code, it is created from the name and organization you type in at install, however a patch was necessary to clean up the expiration, so a keymaker would only do half the job anyway.


Return to Time Trials


© 1998, 1999, 2000 CrackZ. 19th July.