HyperChem v5.02 - Tutorial

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.


© 1998 CrackZ. 19th July.