http://www.cyberpatrol.com - Webpage - cp-setup.exe (895k).
Welcome once again. My target for this tutorial is Cyber Patrol, a 16-bit application designed to prevent undesired and unproductive Internet access. I was therefore expecting a fairly decent protection scheme or at least one that might be a challenge, unfortunately this program still exhibits the same tedious -1 for bad guy / 1 for good guy flags that we've seen many a time before.
So lets start, from the Options menu the Phone Registration option seems like a good choice. On my system the Serial Number field is already filled in by the program (2289) so lets enter some details in the remaining fields (I'm using ABCDEF and CrackZ). Lets also disassemble the file cp.exe and see what String References we can locate, I used WCB here because WDasm32 rarely likes 16-bit disassembling.
In this case your lucky though, W32Dasm will be adequate, and you'll be able to easily find our error message at address 0001.8C6A. Its easy to see where this message is referenced from.
:8C12 CALL 0003.05CC <-- VERY_Interesting_Function.
:8C17 ADD SP, 0008 <-- Correct Stack.
:8C1A MOV WORD PTR , AX <-- Here's_our_deciding_flag.
:8C1D CMP WORD PTR , 0000 <-- Check flag for 0.
:8C22 JG 8C27 <-- Jump_nice_guy.
:8C24 JMP 8C67 <-- Bad_guy.
With this information lets start using SoftICE. You can use either >bpx Hmemcpy or GetDlgItemText to gain an entry point, for simplicity use the latter and allow 3 breaks. You'll be looking at this code.
:89E4 CALL USER.GETDLGITEMTEXT <-- API.
:89E9 LEA AX, [BP+FF12] <-- Name.
:89ED MOV DX, SS
:89EF PUSH DX
:89F0 PUSH AX <-- Stack name for function.
:89F1 CALL 0C7E <-- Get name length.
:89F6 ADD SP, 0004 <-- Correct stack.
:89F9 CMP AX, 0000 <-- Check_name_entered.
:89FC JZ 8A01 <-- Jump_no_name.
:89FE JMP 8A2C <-- Good_guy.
As expected, just a check that a name was indeed entered, so lets continue with F10. You'll continue and find several calls to IsDlgButtonChecked which can be safely stepped, although I'll explain later what these calls do. At 8AE3 another call to GetDlgItemText is made, at this stage I couldn't actually see what this call was retrieving, thats because its only relevant after we have registered our user name. So just step to this next piece of code.
:8BD7 LEA AX, [BP-16] <-- Unlock Code.
:8BDA MOV DX, SS
:8BDC PUSH DX
:8BDD PUSH AX <-- Code pattern.
:8BDE LEA AX, [BP+FF12] <-- User Name.
:8BE2 MOV DX, SS
:8BE4 PUSH DX
:8BE5 PUSH AX <-- Pattern again.
:8BE6 MOV AX, 5C3E
:8BE9 MOV DX, DS
:8BEB PUSH DX
:8BEC PUSH AX <-- Pattern again.
:8BED LEA AX, [BP+FF54] <-- Serial Number.
:8BF1 MOV DX, SS
:8BF3 PUSH DX
:8BF4 PUSH AX <-- Pattern again.
This section of code does all of the preparatory work for the deciding function call. To find the good code you'll need to trace 05CC although the unfortunate reality is that you can just force the JG to a JMP and you'll always be able to register. The good code is always echoed in AX at this code:
:0741 MOV AX,72B8 <-- Good code is always here.
Note that when you trace 05CC certain functions are called repeatedly, this is actually a very important feature of the protection scheme as you'll see. If you are looking for a faster solution all you really need to do is set a bpm to location 72B8 or a watch and you can examine the compare routine and snatch the good code.
After registering your name select Phone Registration again. Now that we are registered we have an option to update our site lists, this in fact is the essence of the protection, the idea is that each year you call Cyber Patrol and they give you another unlock code for the year, note that there are now 2 Dialog Buttons (hence IsDlgButtonChecked being called twice earlier in our scheme). Unfortunately for the authors its the same routine doing the check for a valid code as before, so readers of my site will be able to continually update for free, not that they would purchase this software in the first place.