September  2000
"PerfectDisk 2000"
( "Using what the Shareware Author Provides" )
Win Code Reversing
by halifax
Code Reversing For Beginners 
published by tsehp 
Program Details
Program Name: Pd2kdsi.exe
Program Type:Utility
Program Location: Here 
Program Size: 4.6MB 
Tools Used:
 Softice V3.22 - Win'95 Debugger
W32Dasm V8.93 - Win'95 Dissembler
Regmon - Registry Monitor
Easy (    ) Medium ( X  ) Hard (    )  Pro (    ) 
PerfectDisk 2000
( "Using what the Shareware Author Provides"  )
Written by halifax
The author of    PerfectDisk 2000 V3.00.033    says:-
"PerfectDisk 2000 is designed to make the defragmentation process easy. With Raxco's patented Smart PlacementTM, PerfectDisk 2000 can actually reduce the amount of time it takes to defragment your Windows 9x/NT/2000 systems and can reduce how frequently you need to defragment your systems. The graphical user interface allows for quick, easy and total control over the defragmentation process, Control how and when PerfectDisk runs, Specifically exclude/include partitions, folders and/or files, Set the priority at which PerfectDisk 2000 runs.......yada yada yada. You get the idea.

About this protection system
When you start the program, you are greeted with a nag screen which tells you that the program is a demo and you only have 30 days left to make your decision. What's the reason for the big rush? How many times are you going to defrag your disk in 30 days? Any way, there does not appear to be a nice reg screen anywhere. Must be a reg file or something in the registry. Fire up Regmon and you will see that there is an interesting reg key that is checked.

The program saves an encrypted license key in our registry file in this entry:

HKEY_LOCAL_MACHINE \SOFTWARE\Raxco\PerfectDisk\3.0\License Key

The license key has an 18h value stored in there now so that you can run Demo mode. Note what it is because we will be seeing it again real soon. After some searching around it looks like the file PDCommon.dll is where the real protection is. Disassemble it with W32dasm and you will see all kinds of exciting names like:


When you click on Help/View License using RegMon you will see that the reg key with the license key is called so we can fire up SoftIce and start there. We can work our way through the code to figure out a simple patch to the program so that it accepts the license key that the Author gave us. We can then dive a little deeper into the code and use our brain to figure out how to create encrypted license keys that the program will accept.

This program will allow you to see an encryption and decryption function in action if you have not dealt with them before. Lets go have a closer look at this protection routine and have some fun. 
The Essay 
One way to crack the program is to find where the important registered owner vs bad guy decisions are made. This will determine where the patches must be made to make the program function as if you were a registered owner. The software Author was nice enough to provide well named functions that we can go directly to. The easiest way to get to the well named functions as shown below and as found in W32Dasm is to start the program, click on help. In SoftIce, set "bpx RegQueryValueExa". Press F5 (or CTRL-D), then click on View License. After SI pops up, press F11 to return to PDCommon.dll. Then "bd 0" (disable the first breakpoint) and set "bpx 1000F78D". Press F5 (or CTRL-D) and when SoftIce pops up you are at the below code.

Exported fn(): ?LoadLicenseRegistryVer@CLicense@@QAEXXZ - Ord:017Bh

:1000F781 55               push ebp
:1000F782 8BEC             mov ebp, esp
:1000F784 83EC08           sub esp, 00000008
:1000F787 894DFC           mov dword ptr [ebp-04], ecx
:1000F78A 8B4DFC           mov ecx, dword ptr [ebp-04]

* Reference To: PDCommon.?Load@CLicense@@QAEHXZ

:1000F78D E8F7010000       call 1000F989           <--Land here.

:1000F792 85C0             test eax, eax           <-- eax=0? (Is license not loaded?)
:1000F794 0F8418010000     je 1000F8B2               <-- jmp to bad place if license not loaded?
:1000F79A 8B45FC           mov eax, dword ptr [ebp-04]
:1000F79D 83C018           add eax, 00000018
:1000F7A0 50               push eax                     <-- Second dword of license key
:1000F7A1 8B4DFC           mov ecx, dword ptr [ebp-04]
:1000F7A4 83C114           add ecx, 00000014
:1000F7A7 51               push ecx                     <-- First dword of License key
:1000F7A8 8B4DFC           mov ecx, dword ptr [ebp-04]

* Reference To: PDCommon.?Decrypt@CLicense@@AAEXAAK0@Z

:1000F7AB E8E7070000       call 1000FF97           <-- Decrypt first 2 dwords of License key
:1000F7B0 8B55FC           mov edx, dword ptr [ebp-04]
:1000F7B3 83C228           add edx, 00000028
:1000F7B6 52               push edx                     <-- Sixth dword of License key
:1000F7B7 8B45FC           mov eax, dword ptr [ebp-04]
:1000F7BA 83C024           add eax, 00000024
:1000F7BD 50               push eax                     <-- Fifth dword of License key
:1000F7BE 8B4DFC           mov ecx, dword ptr [ebp-04]

* Reference To: PDCommon.?Decrypt@CLicense@@AAEXAAK0@Z

:1000F7C1 E8D1070000       call 1000FF97           <-- Decrypt last two dwords of License key
:1000F7C6 8B4DFC           mov ecx, dword ptr [ebp-04]
:1000F7C9 83C120           add ecx, 00000020
:1000F7CC 51               push ecx                     <-- Fourth dword of License key
:1000F7CD 8B55FC           mov edx, dword ptr [ebp-04]
:1000F7D0 83C21C           add edx, 0000001C
:1000F7D3 52               push edx                     <-- Third dword of License key
:1000F7D4 8B4DFC           mov ecx, dword ptr [ebp-04]

* Reference To: PDCommon.?Decrypt@CLicense@@AAEXAAK0@Z

:1000F7D7 E8BB070000       call 1000FF97           <-- Decrypt middle two dwords of License key
:1000F7DC 8B4DFC           mov ecx, dword ptr [ebp-04]

* Reference To: PDCommon.?VerifyChkSum@CLicense@@AAEHXZ

:1000F7DF E8DB080000       call 100100BF           <-- Check chksum of License key
:1000F7E4 85C0             test eax, eax           <-- eax=0? (Chksum is bad?)
:1000F7E6 7536             jne 1000F81E             <-- jmp to good place if chksum is not bad

---------   snip  snip  --------

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

:1000F81E 8B4DFC           mov ecx, dword ptr [ebp-04]
:1000F821 8B5114           mov edx, dword ptr [ecx+14]  <-- edx must be between 08-0F
:1000F824 83E208           and edx, 00000008      <-- for edx^08 to not be zero
:1000F827 85D2             test edx, edx              <-- edx=0?
:1000F829 740C             je 1000F837                  <-- jmp to trial time ck if edx=0
:1000F82B 8B45FC           mov eax, dword ptr [ebp-04]
:1000F82E C7401408000000   mov [eax+14], 00000008   <-- mov good flag to [eax+14]
:1000F835 EB7B             jmp 1000F8B2                <-- jmp to registered owner

---------   snip  snip  --------

If the above code is changed:
FROM:  :1000F7E6 7536      jne 1000F81E    <-- jmp to good place if chksum is not bad
  TO:  :1000F7E6 EB36      jmp 1000F81E    <-- jmp to good place ALL of the time
then the License checksum will always seem good.

If the above code is changed:
FROM:  :1000F829 740C      je 1000F837      <-- jmp to bad place if edx=0
  TO:  :1000F829 9090      NOP NOP              <-- ALWAYS pass thru to good place
then the comparison with the decrypted 1st byte ANDed with 08 will always seem good.

Now the software Author was also nice enough to provide functions to generate our own license key and install the new license key directly into our registry. What more could we ask for? Why don't we try making our own encrypted license key. Rather than put all the detail (because this is taking longer than I thought it would), I can outline the theory and provide some detail. First, we need to figure out what makes a good license key. There are three things in the case of this license key. The license key length must be 18h (24d) bytes. The 18h decrypted bytes of the license key must add up to xFF. This is determined by tracing into the chksum function located at :1000F7DF CALL 100100BF. The decrypted license key that the Author provides us with is seen in [eax+14] at 100100CB. We know that the chksum function needs to return a non-zero value (from above detail). Look at the last few lines in the chksum function code below:

:10010164 81E2FF000000     and edx, 000000FF  <-- edx=sum license key decrypted bytes
:1001016A 33C0             xor eax, eax            <-- eax=0, this is initial return value
:1001016C 81FAFF000000     cmp edx, 000000FF  <-- is edx=FF? (good guy?)
:10010172 0F94C0           sete al                      <-- set al=1 if good guy
:10010175 8BE5             mov esp, ebp            <-- stack maintenance
:10010177 5D               pop ebp
:10010178 C3               ret

If we want EDX to equal FF after EDX is AND with FF, then EDX needs to be xFF. The third criteria that the license key must meet is that the first byte of the license key must be a value between 08 and 0F (if it is 01,then demo, 02 is extended demo, 04 is expired demo). We know this from lines that we saw before above. That means one of the simpliest license keys could be:

08 00 00 F7 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

The above license key meets the three criteria of being 18h bytes long, the sum of the bytes is xFF (F7+8+0), and the first byte value is between 08 and 0F. We have enough information to now encrypt this legal license key. The encryption funtion is located at 1000FEF1 and is called three times, same as the decryption funtion. Now we just have to start the program, break in, ensure the stack won't scream bloody murder, and set up our new license key in memory at the correct location and then run the program. It will be like falling off a log.

Use the same technique as earlier to break into PDCommon.dll. Then clear all breakpoints and set "bpx 1000F787", press CTRL-D. Clear the View License screen, then click View License again. When Softice breaks, go to the EIP register and type in "1000F8BA", press F10 once. Now this is the start of the encyption function that is only used during installation, but since we want to take advantage of this function, SoftIce allows us to setup program execution there. Press F10 once more to stop on the InsertChkSumToFlags function. Type "d ecx+14" to show the start of the 18h byte decrypted license key. To use the simple license key above, insert 08 in memory location 00A6F7BC and F7 at memory location 00A6F7BF (or any one of the other 17h bytes in the license key). The other 16h bytes should be zeroed out, but if they are not, go in and zero them. If you want to see what that key looks like after it is encrypted, set "bpx 1000F910 do "d ecx+14". Otherwise, press CTLR-D and your new license key will be written to the registry. It should look like the 18h bytes below.

66 F0 C0 58 6A 34 F9 FB
CD 45 72 D7 E7 E0 35 CF
CD 45 72 D7 E7 E0 35 CF

The next exercise would be to rip the encryption and registry loading code out and use it for a key gen. I will leave that for you.

(Clarification: It is actually the 4th byte that gets checked for being between 08-0F, not the first byte. The 4th byte gets moved to the first byte position when it gets checked in the VerifyChkSum@License function after decryption. I thought that it might be too confusing to explain all this when generating the encrypted key using the instructions above because the first and 4th bytes get switched at the InsertChkSumToFlags@License function just before encryption. Now that you are totally confused ....)

The Patches 
Who needs a patch when you can make a legitimate license key?
Final Notes

It turns out that I never did defrag my disk with this program. I run encrypted magic folders on my PC and I think that they have a conflict. It wasn't worth the hassle of uninstalling EMF and re-installing it. Anyway maybe it will work for you. If it does, and you like it, go ahead and purchase it.

If you have any comments or questions, start a thread at The Sandman's site and I will probably see it.

My thanks to The Sandman for his fantastic site, to all the people their who provide help, and to The Snake for providing this html template that I shamelessly used without his consent.

Essay by:;        halIfax
Page Created: 25th September 2000