Use of the Win32 API(WebGenie Software's Downfall)
by Saltine, 28 May 1997

Courtesy of fravia's page of reverse engineering

Saltine is a legend, and I'm very happy that he has started contributing to this page :-)

Title: Use of the Win32 API
Subtitle: WebGenie Software's Downfall
By Saltine [PC]


Software:*Star Pro
Or any of the software at

Tools: SoftICE 2.0/Win95 or greater, a good WinAPI handbook and/or the API help files that ship with many programming languages

Target audience: Intermediate cracker. Knowledge of the use of SI and the WinAPI required.

I am writing this tutorial not because the subject matter is difficult or tricky, but because it is unique and I have not seen it before now. It will show you how an author can have a reasonably sound idea, but implement it poorly so that it is easily cracked. My method will show you step-by-step my approach to cracking this software. I am taking a somewhat of a long route with this, but I will show you a quicker way to crack this at the end, and that technique will further show you that the bulk of cracking is done outside of a debugger.

After installing, run it to get a feel for it and to see what kind of protection we are dealing with here. You should notice the nag, and the fact that it has a 30 day timebomb (easily cracked – more on those later). Okay, now that you have it running, you will notice that it does have a registration dialog. Good. This part of cracking is critical, any cracker will tell you that. You must always first take a hard look at the program, it's operation, its files, before diving in with the debugger. The observation part is over, now phase II of cracking begins.

So you start the registration dialog and set a breakpoint for GetDlgItemTextA and GetWindowTextA. It is the latter that you end up using. As soon as you enter a code (I entered 12345) and click Register you end up in the debugger. Tracing through gets you nowhere. All that happens is that the code gets stored in cspro.ini in the windows directory. The validation is done at startup. Hmm….

So you open up cspro.ini and take a look. There, in the second line is the bogus code we entered. You should notice that this file is not in the normal INI format widely used by windows programs. There are no [section] blocks at all, so trapping GetPrivateProfileStringA will get you nowhere as well. Hmm…at this point I get my usual "Well, let's get to work" mentality. Once I realize I won't crack a program in only a few minutes (most shareware programs are done in minutes, sadly), I get to work.

So now I think that breaking on ReadFile or Lstrcmp will probably get me in some applicable code. Set a breakpoint for ReadFile and run the program. 3 reads before the program starts, reading the cspro.ini file in chunks. Interesting, but not exactly what we are looking for, but is good knowledge to have should you have to go back to square one. Okay, the program must be comparing strings, so let’s set a breakpoint for Lstrcmp and run it. Bingo! It checks several of the lines in the cspro.ini file. We need to find the code that is looking at our bogus registration code.

Enable the Lstrcmp breakpoint and run it again. The CSPRO module will call that API function at least 16 times. At each call you will see code similar to this:

014F:00402E89 PUSH EAX
014F:00402E8A PUSH 00446BE4

You can check each of these calls by doing this, as an example only because the memory location will be a little different each time:

: d 00446BE4

By doing this you will see what the program is checking each time it calls Lstrcmp. Continue this until you see it check your registration code (12345). You will eventually see code similar to this:

014F:00403724 PUSH ECX
014F:00403725 PUSH EBX

Now by checking the contents of EBX you know that it contains your bogus registration code. We are at a very good point in the code at last. Set a breakpoint for that line (Lstrcmp), and disable all others.

But wait, underneath this last Lstrcmp call you see something odd – a call to IsCharAlphaA (verifies that a character is a letter). Hmm…interesting. Holding down the Ctrl key and paging down allows you to see more of these same calls, with some being to IsCharAlphaNumericA (verifies that a character is alphabetic or a number).

Wow! Could it be? Yes it is. Stepping through the code you will see it call one of these functions for each character in the registration code, bombing out if any portion of it fails. In between calls you will see it checking for dashes (- , 2Dh), with a CMP EAX, 2D check.

So you know at least 2 things at this point: The first character in the registration code must be a letter, and the code is going to have dashes in it.

Now, the only thing left to do is generate a code matrix for the registration code. Do this by holding down the Ctrl key and paging down through the code, writing down each character requirement as you go. You don’t want to step through the code with F10, as it will just bomb out on you when it gets an incorrect character in the code. Don’t forget to add the dashes where you see it checking for them. Technically, any letter would work for the places it calls IsCharAlphaNumericA, but I chose to use it as a required number field. So the final matrix is this:


A = any letter
# = any number (or letter)

Any code with this format will register the software. Simple huh? I was surprised too. Now you must be thinking about a key generator. I released one that simply generated random codes, using the required format for all of the software on the site. Each program there uses a variation on this idea, with slightly different code matrices.

Now, for the promised simple way to crack this:

Open up the executable in your favorite hex editor, search for kernel32.dll. You will find it once or twice, and below it in one of the areas you will see a list of API calls the program uses. Notice the IsCharAlphaA and IsCharAlphaNumericA strings? These declarations, from my experience, are unusual, and gave me a quick entry into the registration checking code. This is always a good method to use to see what API calls a program may use. Furthermore, searching for ".key", ".reg", ".dat", or ".lic" will help you out sometimes. So all you have to do now is set a breakpoint for IsCharAlphaA or IsCharAlphaNumericA and you are instantly in applicable code. I always take a look inside an executable or dynamic linked library before I try to crack them. You never know what you might find; even registration codes sometimes.

Lessons learned: Authors are lazy, stupid people sometimes. As you know by now, the author properly used rule #1 when it comes to key registration systems - never compare a valid key to the entered key in memory. He adhered to this rule, but then he used the API, in what I am sure he thought to be a most excellent protection system. Had he coded it out himself, this would have been slightly (only slightly, it still would have been easily cracked) more difficult. I've talked to many authors via e-mail and that is a point I always stress - do it the hard way. If it's hard for you, or inconvenient, then surely it will be difficult for the crackers.

This protection is not difficult. Most protection schemes are not. That is exactly my point - do not ever think that you cannot crack something, because you probably can, regardless of your experience, because authors take the easy way out far too often.

In my next tutorial I would like to cover trial software. You know, the 30 day timebombed stuff. There are many generic methods to crack these, and I will be discussing them in depth. You will see that those are the easiest programs in the world to crack and that it is pointless to try and limit software in that manner.

Well that’s it for this tutorial. If any author or cracker has learned from this, then I am satisfied.

Saltine [PC]
T-001 : May 27, 1997

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links red anonymity +ORC student tools cocktails search_forms mailFraVia
Is reverse engineering illegal?

Fravia 28 May 1997