http://www.webgenie.com - (3.8Mbs).
Another requested program and one genre which I think all reversers should crack against. WebGenie ShoppingCart is a truly loathsome commercial product for slaves wishing to turn their websites into money-making enterprises, as if there are actually any that could provide *real* information for free. The protection at first seems banal, a time-trial which looks as if it can be deactivated using a registration code, however the code isn't verified at input time but at run-time, the aptly named wscpro.ini acts as the store.
I won't bore you with the rudimentary process of obtaining what seems to be a valid code, the reliance on IsCharAlphaNumericA will find you a lengthy checking algorithm which gives a valid code of form below (every position in the code will be checked against validity criteria).
WP1212-US173-57CN7-12121-WSP0298 is one example.
I entered the code and restarted but *sigh*, a nasty message box saying that the code was not accepted, how can this be so..... well the message box gave me a url to try for an update, looks like this verification scheme was for old codes and downloading the update isn't possible unless your details match the validity database. As no-one in their right mind would pay for this we are going to have to look a little closer. First up we'll use the +ORC technique of nag snatching, here's one piece of squalor.
:0040A12A MOV EAX, 00470E04
:0040A12F CALL 0043B458 <-- Call something or other.
:0040A134 CMP DWORD PTR [0046C1EC], 00000000 <-- Flag elmopio.
:0040A13B JNZ 0040A17B <-- WebGenie Shopping*Cart Professional.
:0040A13D CMP DWORD PTR [0046C1E8], 00000000 <-- Flag yoshi.
:0040A144 JNZ 0040A15E <-- We don't ever want to check yoshi.
:0040A146 PUSH DWORD PTR [0046C1E0] <-- Flag zen.
:0040A156 CALL 0043CC34 <-- Has user any time left.
:0040A15E CMP DWORD PTR [0046C1E8], 00000000 <-- Ask flag yoshi.
:0040A165 JZ 0040A18D <-- User is still on time-trial.
When commenting the above I named the 3 critical flags (this technique adds life to otherwise dull listings), ordinarily I'd say trigger the time-out but it won't hurt for us to verify in SoftICE whilst our trial period is valid how these flags work (even if it appears obvious). Now be ready for this next bit, the developers left their demo with debug information, there are no words to describe this from the Loader, just read it and forget it.
015F:0040A12F CALL @__InitExceptBlock
015F:0040A134 CMP DWORD PTR [_RegisteredVersion],00
015F:0040A13B JNZ 0040A17B
015F:0040A13D CMP DWORD PTR [_ProgramExpired],00
015F:0040A144 JNZ 0040A15E
015F:0040A146 PUSH DWORD PTR [_numberOfDaysLeft]
015F:0040A156 CALL ___org_sprintf
015F:0040A15E CMP DWORD PTR [_ProgramExpired],00
Obviously the entire protection depends on flag elmopio being non-zero, note that reversing this jump live still produces a message box (secondary flag checking). We'll now just perform a simple search for 0046C1EC and note the references.
00409BF0 (check), 00409FD7 (set), 00409FE1 (set), 00423FA2 (check), 004253C0 (check), 0042E8A7 (check), 0043246E (check), 00432511 (check).
Naturally we are most interested in those instances where our critical flag is set, take a look at this code:
:00409FD5 XOR ECX,ECX <-- Zero ECX.
:00409FD7 MOV DWORD PTR [0046C1EC], ECX <-- Flag it to 0.
:00409FDF XOR EAX,EAX <-- Zero EAX.
:00409FE1 MOV DWORD PTR [0046C1EC], EAX <-- Flag it to 0.
These 2 flag setters are immediately after the serial number checking algorithm, if we appear to pass all the validity checks then ECX is zero-ed which is probably where the protectionist made his change in order to make this demo unregisterable, the failure with EAX only occurs if the program reads UnRegistered from the ini file. The verdict then is simple, this demo was crippled very hurredly so that it could never be registered without having to log on to their website, the programmer did this by simply reversing the _RegisterVersion flag at the end of the serial number checking algorithm (incredibly stupid), cracking this using a valid code or any other invalid code is therefore very trivial.
:00409FC9 XOR ECX,ECX <-- the JNZ here can be safely
killed (33 C9).
:00409FD5 INC ECX <-- Set flag true i.e. non-zero (41).
:00409FD6 NOP <-- required (90).
That completes another tutorial, although why you would ever want to keep this program I'll never know :).