
Cracking WinHex V8.32
by Cho on 18/04/99		


My intention of writing this stuff is of course to share my recent 
experience with other newbies in cracking.

This new version of winhex came up just about a week ago. 
I find it very useful and quite interesting to crack.



The programs I used for this crack are
- WinHex v8.32
- SoftIce v3.2 (mainly)
- a  hex editor for patching (if necessary).



The difficulty rating: easy; for newbies, like me!



Let's proceed as usual: run winhex.exe and get to the registration window 
from Help/Register.
You are asked to enter 2 codes: Code1 and Code2. 
Type in any numerical values you prefer! 
(I used Code1: 23456 and Code2: 10789). 

Before you send these numbers to the program, you have to press Ctrl D to 
get into SoftIce. 
You are now ready to set a breakpoint, but which one?

I can tell you I've tried "bpx getwindowtexta" and landed at :0040E43D. 
It led me to nowhere!

It would be better to breakpoint on hmemcpy. 
So type in: bpx hmemcpy and then back to winhex with Ctrl D.

When you click OK this time, it breaks and you are in SoftIce again. 
It always takes a long time to get out of hmemcpy in pressing F11 and F10 
many times to reach the winhex program code section. But you will realize, 
when you reach that point (at :0041E8FB), 
that you have just finish a getdlgitemint call:

:0041E90D   E86A66FEFF	  call getdlgitemint	       convert Code1
:0041E8FB   8945FC	  mov dword ptr [ebp-04], eax  <= landing here
:0041E8FE   6A00	  push 00		       store Code1
:0041E900   68EC734400	  push 004473EC
:0041E905   68F6010000	  push 000001F6
:0041E90A   6807	  mov eax, dword ptr [edi]
:0041E90C   50		  push eax
:0041E90D   E86A66FEFF	  call getdlgitemint	        convert Code2
:0041E912   8945F8	  mov dword ptr [ebp-08], eax   store Code2
:0041E915   33C0	  xor eax, eax


How's that? In fact, the getdlgitemint fuction converts your entered 
string of numbers (in decimal) to its value in hexadecimal. 
In this operation the hmemcpy fuction is called by the getdlgitemint fuction. 
It can be much simpler if we use "bpx getdlgitemint" to get to :0041E8FB.


You can now clear the breakpoint with "bc 0".

Just take a look of what we find: 
eax contains your Code1 (in hexa) which is then stored to the location:ebp-04.
Once you step down (F10) past this line, 
check with "d ebp-04" the location of your Code1 
(I find mine 5BA0 in 0069F918).


Stepping further down, you can see your Code2 is treated likewise at:

:0041E90D and :0041E912. 
"d ebp-08" can help to check (I find mine 2A25 in 0069F914).


What operation will be done on these codes? 
We are going to find out. 
So we will set a new breakpoint on the memory location: bpm 0069F918. 
Then Ctrl D to get back to the program. 
BANG! A window pops up to ask you "Please restart winhex", 
as if the codes were found wrong, without doing any comparison ?!



This is very tricky! Don't be discouraged. 
In fact the program wants to save the data in a winhex.cfg file 
which will then be examined when you restart the program. 

So click OK. 

SoftIce breaks again at :0041F3C9 and you see the following lines:


:0041F3C6   8B45FC	   mov eax, dword ptr [ebp-04]
:0041F3C9   A3945A4400	   mov dword ptr [00445A94], eax <= landing here
:0041F3CE   8B45F8	   mov eax, dword ptr [ebp-08]
:0041F3D1   A3985A4400	   mov dword ptr [00445A98], eax
:0041F3D6   33C0	   xor eax, eax

You can see your codes are being transfered to locations: 
:00445A94 and :00445A98; 
these are probably the locations where the program communicates 
data with the winhex.cfg file. 
We have to follow the operation: clear the old breakpoint and set 
another one with "bc 0" and "bpm 00445A94".

When you get back by Ctrl D this time, 
you have to exit the program: File/Exit. 
Then restart the program. Crac..! It breaks at :00440936 and you see:


:0044092F   EB2C	    jmp 0044095D
:00440931   A1945A4400	    mov eax, dword ptr [00445A94]
:00440936   E8BD33FFFF	    call 00433CF8		  <= landing here
:0044093B   3B05985A4400    cmp eax, dword ptr [00445A98]
:00440941   750F	    jnz 00440952
:00440943   33C0	    xor eax, eax

WOW! You've got it. Everything's here! Do you need an explanation? 
Well, your Code1 stored in 00445A94 is loaded in eax at :00440931. 
It is used to generate another code (Code2) in a subroutine. 
The returned Code2, the real one, is then compared with your Code2 
stored in 00445A98. If yours is not valid then jump to "badguy".
If it's valid, continue "goodguy". 

You now get the protection scheme of the program.


One way to get registered is to choose a Code1 
(703710 = ABCDEh, for example) and you get in eax after the call at:

:00440936 the real Code2 (47054h = 290900) that goes with your Code1; 
of course you have to convert it from hexa to deci.


To crack this program, you can patch at :00440941 (offset 3FD41h) 
in changing 750F to 7500. 
This will allow you to use any code you like.



If you feel at ease with you assembly knowledge, you can even make a 
code generator in inspecting the subroutine at :00433CF8.


Once you get registered, you will not see Register in Help and you can 
save files over 200kb.



Job done!



*IF YOU INTEND TO USE THIS PROGRAM, PLEASE PAY YOUR REGISTRATION* 

**Greetings to all and thanks to The Sandman**
