WinHex 8.03 - Tutorial by PcNinJa [iNSiDE]

"There isn't much for me to say here, a nice HEX editor reversed in an easy to follow manner, I'm pleased to see that PcNinJa follows through the scheme working out a valid pair of codes as opposed to patching which is to be discouraged unless the scheme really is inpracticle to reverse." "Slightly edited by CrackZ".

http://www.muenster.de/~sf/Index2.htm - Webpage (250k).

Introduction

I'm back with a new tutorial for a wonderful tool WinHex. It is a hexadecimal editor for Windows 95/98/NT with a lot of features:

Concatenating, splitting, unifying, analyzing and comparing files, disk editor... The protection scheme is based on two numbers which have to verify a certain relation. What is pretty uncommon is that you can't trace the verification after hitting "OK" since it isn't done at this point but when you restart the software.

The Protection

Once loaded with SoftICE, we go to the registration menu and find:

WinHex 8.03 Screen Shot

Now we can enter some example codes and bpx hmemcpy. The problem is that the verification isn't done at this point. The program tells us to restart (but we can see that the values must be integers because of the 2 calls to GetDlgItemInt). So I decided to use a different approach and disassemble with W32Dasm. When using the program, we see that we can't save files larger than 250Kb so I searched for the message and found the following:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041C0CA(C)

:0041C131 PUSH ECX
:0041C132 MOV EBX, EAX
:0041C134 CMP BYTE PTR [0043D40F], 00
:0041C13B JNZ 0041C17D <-- It's OK, we can save.
:0041C13D MOV DWORD PTR [ESP], EBX
:0041C140 FILD DWORD PTR [ESP]
:0041C143 FMUL DWORD PTR [0041C184]
:0041C149 CALL 00402778
:0041C14E CMP EAX, 000000FA <-- FA=250.
:0041C153 JLE 0041C17D <-- Perhaps another way to be OK.
:0041C155 CMP BYTE PTR [0043C623], 00
:0041C15C JNZ 0041C16C
:0041C15E MOV EAX, 0041C188
:0041C163 MOV DL, 04
:0041C165 CALL 00409CC4
:0041C16A JMP 0041C178

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041C15C(C)

* Possible StringData Ref from Code Obj ->"Please register in order to be "
                                        ->"able to save files larger than "
                                        ->"250 KB."

:0041C16C MOV EAX, 0041C1EC
:0041C171 MOV DL, 04
:0041C173 CALL 00409CC4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041C16A(U)

:0041C178 XOR EAX, EAX <-- We CAN'T save.
:0041C17D MOV AL, 01 <-- We CAN save.
:0041C17F POP EDX
:0041C180 POP EBX
:0041C181 RET

We rapidly see, that we can save if [0043D40F]=1, it is the crucial byte of the program (0=shareware, 1=registered)... very weak protection. So now, we're going to see where this byte is set. I searched for the string "[0043D40F]" in the source and I found that this byte was set at 01 (registered) if [0043BA14] equals a constant value 720C9h (I'll let you see that). Now we can return a last time in SoftICE and put a bpm cseg:0043BA14. This code can now be easily reached.

:00436B69 ADD EDX, EDX
:00436B6B LEA EDX, DWORD PTR [EDX+4*EDX]
:00436B6E ADD EDX, EBX
:00436B70 ADD EAX, EDX
:00436B72 MOV DWORD PTR [0043BA14], EAX

At the begining of this code, we have:

EAX = E8E4h (constant)
EBX = Code1
EDX = Code2

So [0043BA14] <- E8E4 + Code1 + 10 * Code2

Remember we must have [0043BA14]=720C9h, e.g.

Code1 + 10 * Code2 = 407525 (decimal).

For example:

Code1 = 525
Code2 = 40700

Contact: pcninja@hotmail.com


Miscellaneous Papers Return to Main Index


© 1999 Hosted by CrackZ. PcNinJa 2nd April 1999.