ESTUDIO COLECTIVO DE DESPROTECCIONES
WKT Tutorialz Site
WKT
Program  English-Spanish Interpreter 2000 W95 / W98 / NT 
Description  Translation & Reading of documents
Type  Fully working demo. Limited number of uses (4)
Url  http://ssl.pair.com/magicw
Protection Serial / Malfunctioning after 4 uses
Difficulty 1) Beginner, 2) Amateur, 3) Advanced, 4) Professional, 5) Specialist 
Tools  SoftIce v3.25  &  TechFacts95
Objetive  Unlimited fully working uses
Cracker  MrCrimson/[WkT!99]
Date August 25 1999 
Introduction
The very first time we run this software a futuristic splash appears. Once it vanishes a fully working program is offered to us :o) 
The second time it happens exactly the same 
The third one we are also shown an ugly NAG which remind us about the limitations of DEMO version. It invite us to choose between entering a valid registration code or keep 
using the program in DEMO mode (there are two more uses left). 

Once we finished the number of allowed uses, the soft provides the following menace: 

"The program will not work properly from now on"... 

Hey, where did you learn about that marketing tips...? Don't you know the product must never be degraded...? Protection is not an excuse to deliberately produce malfunctioning code....:o( 

Ok, let's see how this curse works. During the first 4 authorized sessions I asked for the translation of the following phrase: 

“Do you think I am completely stupid?.”

Which was translated correctly as follows: 

“Piensa usted que soy completamente estúpido?.”

When I asked again the same question in 'expired' mode that asshole answered: 

“Hace usted lo imposible?.”

(Case you do not understand spanish, I tell you that's not right at all) 
After trying some more sentences I realized that, in expired mode, translations were made in an funny randomly way... 
 

A first try: Serial number and the hidden algorithm

The first try, as usual, aimed to uncover the algorithm responsible for serial validationl and then reverse it to produce a nice keymaker. Unfortunately,  the algo seemed to be a genuine example of  so-called spaghetti code. During the calculations a pretty large number of non-binary flags were created to be checked later along the whole program session. 
Ok, that's not unbeatable but.... it could take too long tracing all that stuff! 
You know, there are brute-force cracks but the same way there are brute-force protections like this one. Those programmers think they can solve the lack of originality by adding some thousands of flag-checking code lines (have a look to the main EXE file: 3,4Mb!!!). They are sure happy with that solution since they don't care about the users who downloaded 20Mb to have just 4 uses.... it's simply crazy. 

Anyway it's well known that MrCrimson must attend daily many love dates so there is no time to lose: Let's crack! 
 

A second try: TechFact95
A classical question: How the hell does the proggie know that free uses are expired...? 
That info must have been stored  someway in: 
  • Windows registry
  • Some INI file
  • Some installation file
  • Some esoteric combination of previous ones
To throw some light on this we use TechFacts 95...
I really recommend it to you. I think there is only one thing which is worse thant having NO INFO and that is having TOO MUCH. That is what happen most times when using 'regmon' for example.
Monitoring ALL ocurrencies in registry can be pretty useless if they are hundreds... 
TechFact, among other features, provides you a concise report on changes occured in the system (INI files, disk files, registry) when an particular application were executed.
When applied to this case I got NOTHING  :o( 

Well, what did you expect?  Once the DEMO has expired there is no use in checking anything.... so the mechanism responsible of counting uses is probably disabled. 

At this point what we should do is going back to the beginning and  re-installing the software. 
This time we will  monitor  with TechFacts every single change happened when running the proggie. The results summarizes as follows: 

1st Run: 
Some new entries are created in the registry. They have names as: Custom Colours, Custom Windows, General Settings and things like that... 

wait a second...there is something more....one of the new keys is named: 

HKEY_LOCAL_MACHINE\Config\0001\Other Flags 

This value ("Other Flags") contains more than 2000 bytes and what makes it suspicious (besides that name) is its location. It is not placed together with the rest of configuraton values for the application. It was placed in an area which could be thought as configuration  values for Windows. It would be quite difficult to relate it to ESI....(call it ZEN if you like it) 

  • 2nd, 3rd  and  4th  runs: Each execution makes changes in some values stored in ‘Other Flags’
  • 5th run (The first one illegal): Some values are again modified in ‘Other Flags’ but this time will be the last one....
  • 6th and sucesive runs: There are NO changes to 'Other Flags'
Whatever it means it is clear that keeps some relationship with the number of uses...! 
 
First success

If  I am right we could 'RESET' the counter of uses by entering in the registry the original values for 'Other flags', I mean the data after the first run (when they were created). 
After that first run, I exported the key and now I can restore it by 'executing' the REG script.

Voilà. When done, I started the program to see how it worked as the fucking first time... 
Even that ugly window title 'expired version' has desappeared!!!

When asked the proggie about the current status it says there are 4 more uses left...:o) 
If we re-run the soft 4 more times we reach again that expired status, of course. 
Ok, we can reset the proggie and get as many uses as we want although it is not comfortable at all. 
In order to get a working crack, we have to find the code which change these values in 'Other flags' since it is the responsible of countdown... 
 

Hands on!

Gonna have some action...! 
We are going to find the updating code for those values in the registry so have to install a BPX in the API function  RegQueryValueEx  which is the responsible of  loading in memory the content of registry keys. If we know where the data is stored it will be easy to check for changes. The sintax of this function is as follows: 

LONG RegQueryValueEx( 
    HKEY hKey,          // handle of key to query  
    LPTSTR lpValueName, // address of name of value to query  
    LPDWORD lpReserved, // reserved  
    LPDWORD lpType,     // address of buffer for value type  
    LPBYTE lpData,      // address of data buffer  
    LPDWORD lpcbData    // address of data buffer size  
   ); 

There are many calls to this function but after tracing a while it makes clear that  interesting ones  happens in: 

* Reference To: advapi32.RegQueryValueExA, Ord:0000h 
                                  | 
:0045210A E83150FBFF              Call 00407140 
:0045210F 85C0                    test eax, eax 
:00452111 742E                    je 00452141 
:00488D8D B1B4                    mov cl, B4 
:00488D8F E8B09EF7FF              call 00402C44 --> Modificación 
:00488D94 FF45EC                  inc [ebp-14] 

In order to filter for our particular query to 'Other flags' we do: 

Bpx 0045210A IF *(*(ESP+4))==6568744F 

Here, the second parameter, pushed to the stack, should points to "Other Flags" 
(i.e. 6568744F are the ascii codes of the first 4 characters in reversed order, "ehtO") 
The value loaded by RegQueryValueExa is pointed on return by the 5th parameter and at this memory location we place a "BPM [address] W" in order to detect when any attempt of writing. 
The result is not amazing at all. The CALL at 488D8F is responsible of  all updating in the key. To neutralize this CALL, we first check that no balance in the stack is needed after executing the routine. Then we can write a crack which changes: 

:00488D8F E8B09EF7FF              call 00402C44  

to 

:00488D8F 9090909090              nop nop nop nop nop 

Now, restoring the registry key to its original value and running the code patched as indicated, we will be at our first try FOREVER... :o) 
 

Putting all together

Things go fine but we still have to take into the crack that 2Kb of data and that's not too elegant, I think. 
Let's see... the key is created during the very first run of the program and since then it is changed in each use. The REAL, original state is not that one with the 'virgin' key but WITH NO KEY at all !. 
I decided to delete that boring "Other flags"  key and.......Yeah! 

When running the proggie, the key was newly created (meaning 'starting 4 uses demo period') 
Since the patch explained above prevents any updating (decrementing of uses) the desired first time status will keep working forever. 
Our crack is smaller and easier by far: 5 bytes patched and a registry value deleted. 
 

Deleting registry values
Registry scripts (*.reg) can easily handled to add entries but it cannot delete them. 
We are also interested in join the whole prot-remover in a single file. How can we manage to erase the key...? 
Easy, another API function. Its name says it all 

LONG RegDeleteKey( 
    HKEY hKey,        // handle of open key  
    LPCTSTR lpSubKey  // address of name of subkey to delete  
   ); 

The following snippet solves that point: 

.const 
Clave      db   "Config\0001",0 
Flags      db   "Other Flags",0 

.data? 
Hwndr      dd ? 

;Abre 
invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,  ;rama 
                    offset Clave,        ;clave 
                    NULL,  
                    KEY_SET_VALUE,       ;modo apertura 
                    offset Hwndr         ;handle de clave abierta 

;Borra 
invoke RegDeleteValue,Hwndr,             ;handle de clave a borrar  
                      offset Flags       ;nombre de valor a borrar 
;Cierra 
invoke RegCloseKey,Hwndr                 ;cierra clave abierta  

Beautiful isn't it? 
 

Last breath

During the test period, a friend of mine realized that after each 100 sentences translated a windows popped up with an annoying message about demo version. Relax. It did not hang the program.... just asked for confirmation. After click OK all kept on working fine 
"A  MessageBox...", I thought and started looking for the trigger which activates that MessageBox call. It wasn't easy at start....
That windows looked like a MessageBox BUT IT DIDN'T. It was really a window 'taylored' from pieces: the icon, the button, the text.... 
Parts were added step by step along the code making extremely hard to detect the trigger. 
I took the time to trace the normal run of sentence Nº98 and then compared it to that of the sentence Nº99 (pop window). It finally found it: 

:0063BE96 FF058C7F6400            inc dword ptr [00647F8C] 
:0063BE9C 833D8C7F640064          cmp dword ptr [00647F8C], 00000064 
:0063BEA3 0F8C34010000            jl 0063BFDD   <--- bifurcation 
 
I was amazed to find a direct comparison with 100 (64h)... 
Christ!, I didn't even try to find the literal because imagine they were much better...
Obviously,  [647F8C] holds the counter for sentences and code is redirected whenever the count is less than 100. To nuke it, just killed the INC instruction. 

:0063BE96 FF058C7F6400            inc dword ptr [00647F8C] 

Changes to: 

:0063BE96 909090909090            nop nop nop nop nop nop 

An that's all you need.
 

Finale
  • There are some cosmetic details which do not affect to the protection nor the working of the program so I will not go into details with them. 
  • I didn't remove the NAG since it is not part of protection scheme (anyway it's quite easy).
  • This software is presented as a suite which in Demo version contains another program (WordMagic). The protection scheme is exactly the same so I will not explain it here
  • The complete suite includes other proggies NOT included in the DEMO version and so they weren't analyzed
As conclusion I'd like to say the following: 

This kind of massive checking protections is 100% pure shit: 

It Makes codes slower 
It Makes codes BIGGER 
It Does not protect at all :o) 
 

Hope this doc will be  helpful and add some new trick to your skills. 
I guess it is unnecessary to say that but: 

If you like the program then pay for it! 

Up The Hammer! 
MrCrimson/[WkT!99]