Title: Use of the Win32 API
Subtitle: WebGenie Software's Downfall
By Saltine [PC]
Software:ftp://www.webgenie.com/pub/csp32.exe CGI*Star Pro
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 lets 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
014F:00402E8F CALL KERNEL32!LSTRCMP
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
014F:00403726 CALL KERNEL32!LSTRCMP
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 dont 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. Dont 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 thats it for this tutorial. If any author or cracker has learned from this, then I am satisfied.
T-001 : May 27, 1997