Nico's Commander v4.02 - Tutorial

http://www.geocities.com/SiliconValley/Way/2686/ - Webpage.

Welcome once again. Firstly, I'd just like to stress how useful a program Nico's Commander actually is, with so much dross on the web, this is a commendable attempt to emulate my favourite DOS editor. Nico's Commander uses as the basis for its protection a serial number, although I haven't delved overly into the maths behind the scheme, I suspect there may only be one universal code.

The first part of this tutorial ought to present no problem to most visitors to my site, you can easily locate the following from a disassembly listing (just search the String References).

:004203DA MOVSX ESI, BYTE PTR [EAX+ECX-01] <-- Serial Number pointer.
:004203DF IMUL ESI,EAX <-- Multiply by position.
:004203E2 IMUL ESI, DWORD PTR [EBP-20] <-- EBP-20 starts at 00600937.
:004203E6 ADD DWORD PTR [EBP-1C], ESI <-- Evidently the store.
:004203E9 MOV ESI, DWORD PTR [EBP-20]
:004203EC IMUL ESI, 00600937
:004203F2 INC EAX <-- Loop.
:004203F3 MOV DWORD PTR [EBP-20], ESI
:004203F6 CMP EAX,EDX <-- Check loop.
:004203F8 JLE 004203DA <-- Loop a bit more.
:004203FA MOV ESI, DWORD PTR [EBP-28] <-- Set EBP-28's value.
:004203FD XOR EDI,EDI <-- Clear EDI.
:004203FF CMP DWORD PTR [EBP-1C], A2289ADC <-- Compare EBP-28 with the default.
:00420406 JNZ 00420421 <-- Jump away bad guy.

Well this code evidently isn't rocket science, and many readers can probably think of at least 3 ways in which to patch this. Finding the good code probably isn't a possibility, unless you code a program that simulates the scheme, this of course throws open the possibilities that maybe a combination of numbers and letters generates the desired result. It maybe also be possible to quickly narrow down the range of acceptable values using SoftICE and the g 004203FF command (a game of higher/lower breaking initially with Hmemcpy).

You'll find in my key generators pack some quick and dirty code I produced to test all of the decimal numbers between 100,000 and 999,999 for validity, I recommend you assemble and link this just to see how it works, it takes my PC just over 5 seconds to test all of the numbers (none of which is correct unfortunately), this code is also easily modified to test higher numbers although the execution time increases (between 10,000,000 and 99,999,999 took my PC some 15 minutes).

The next thing I thought was to simply patch the result of the compare to a result which I knew, say BF6831FF (1234567890), I applied the patch and when I tried to reload Nico's Commander something evidently snapped and the program refused to start, something didn't like my intrusion. When this happens you can usually attribute it too 1 of 2 things, either a type of CRC check or a parity routine. CRC basically involves adding up bytes or a portion of bytes and checking the value against a checksum where as parity routines correct themselves on the fly thus negating the effect of any patch.

Both methods have their drawbacks, a full scale CRC check represents a phenomenal waste of CPU time and is vulnerable to attack because the entire file must be copied into memory for the compare. Parity routines on the other hand are trickier to code and may be easier to pinpoint because of their correction capabilities. Needless to say we can try and locate the code using several methods.

The first method I used was to search for API calls to either unload a program from memory or unregister a windows class. As it turned out nothing panned out so I decided to use the Symbol Loader and observe the loading process of the good file, you won't need to trace for very long before you can identify the CALL responsible for loading the program and more importantly displaying the opening welcome screen.

:0041D0FD CALL 00430980 <-- Check programs O.K. and get called a lot of times.
:0041D102 CMP DWORD PTR [00471318],ESI <-- This compare should be 0.
:0041D108 POP ECX
:0041D109 POP ECX <-- Stack pops.
:0041D10A JZ 0041D110 <-- This is a good jump.

Although patching here is evidently at a higher level than might be desirable it is evidently effective because the critical flag 00471318 is only checked at this location although I'd guess its referenced with an address relative to the BP or SP. If you look and see how many times 00430980 is called you'll realise why I considered it a risk to try and patch below this level. In order to beat this check I recommend forcing the JZ into a JMP, (remember of course to be elegant and that 00471318 is at [ESP+08]). You can of course now patch the result of the CMP identified at the outset to your desired serial #.

As an aside, interestingly once we apply our bogus patch and enter our bogus code, a clean unpatched copy of Nico's Commander will also function as a full version, a little something to investigate perhaps.

From my e-mail

Greetings. Just surfed by your webpage, and I must say I enjoyed the visit. Its the first time I have seen mention of Nico's Commander on a reverse engineering site. I have been running the program for a week now and just wanted to mention to you that I got rid of the nag and time limit by changing the name. The version I have is 4.03. I was working away on it one night, changed the nc.exe to 1.exe, which is what I usually call a work in progress, and the next thing I new, the program worked perfectly. But add a second character for the name and bam, back into limitations. Easiest crack ever. Must have a call from a dll for that original name or something, but I haven't looked into it further. Anyway, just thought I'd mention it to you since you had a splash about it on your page.

(Another interesting aside -- CrackZ).


Return to Miscellaneous


© 1998 CrackZ. 27th September 1998.