Hackers View 6.15.
Commandos: Behind Enemy Lines.
Another famous game in the world, Commandos. This one was released to the public in June 1998. It's been available for download on the internet ever since. I got the original (protected) .exe and started cracking this CD-check because I had never even heard of the CD-Lock protection. Anyway I cracked it fairly easily, but I have to admit that this must have been one of the hardest CD checks I had ever done.
A few months later I heard that this protection actually had a name. I actually love cracking protections that have their own name like CD-Lock. Anyway run Commandos.exe, bpx on GetDriveTypeA, press the start and new game and you should land here.
* Referenced by a CALL at Address: |:0044CAFF <-- Where this whole protections was called from. * Reference To: KERNEL32.GetDriveTypeA, Ord:00CEh :00494A01 MOV ESI, DWORD PTR  * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00494A8C(C) :00494A10 CALL ESI <-- You are here. :00494A12 CMP EAX, 00000005 <-- Check if drive is a CD-drive. :00494A15 JNE 00494A87 <-- Jump if not equal. * Possible StringData Ref from Data Obj ->"rb" <-- String that means READ. :00494A17 PUSH 005F0F90 * Possible StringData Ref from Data Obj ->"D:\TBTP.AFP" <-- Our friend. :00494A22 PUSH 00602610 <-- cdletter:\TBTP.AFP :00494A27 MOV BYTE PTR , BL <-- cdletter:\BBVN.AFP :00494A2D MOV BYTE PTR , BL <-- cdletter:\ETAO.AFP :00494A33 MOV BYTE PTR , BL <-- cdletter:\BTBW.AFP :00494A39 CALL 005CF310 <-- Check if they are there. :00494A41 MOV EDI, EAX <-- Move checksum result to EDI. :00494A43 TEST EDI, EDI <-- If EDI == 1. :00494A45 JNE 00494A51 <-- The files exists. :00494A4F JMP 00494A7F <-- Jump and try again. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00494A45(C) :00494A59 CALL 005CF820 <-- SetFilePointer. :00494A62 CALL 005CF7E0 <-- ReadFile. :00494A6C CMP EAX, 00000029 <-- Compare. :00494A7F MOV EAX, DWORD PTR [ESP+10] <-- If [ESP+10] = 1 you are a good cracker. :00494A83 TEST EAX, EAX <-- If EAX == 1 then jump. :00494A85 JNE 00494A9B <-- Continue with game. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00494A15(C) :00494A87 INC BL :00494A89 CMP BL, 5A <-- Compare BL, 5Ah. :00494A8C JLE 00494A07 <-- Jump and try again with next drive. :00494A92 XOR EAX, EAX <-- Bad cracker. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00494A85(C) :00494A9B MOV EAX, 00000001 <-- Good cracker.
Now goto the code location where all this was called from, you should be here :-
* Referenced by a CALL at Addresses: |:00447E9C , :00448015 <-- Here are the 2 calls. :0044CAFF CALL 004949F0 <-- CALL check. :0044CB04 TEST EAX, EAX <-- EAX = 1. :0044CB06 JE 0044CB12 <-- Continue with game. * Possible StringData Ref from Data Obj ->"rb" :0044CB12 PUSH 005F0F90 * Possible StringData Ref from Data Obj ->"d:\TBTP.AFP" :0044CB1C PUSH 00602610 .....
The best and the simplest way to crack this protection is probably to find where the protection was called from then just simply feel the code :-
:00447E9C CALL 0044CAF0 <-- Where it was called from the first time. :00447EA1 TEST EAX, EAX <-- EAX = 1 = good, EAX = 0 = bad. :00447EA3 JE 00447EBD <-- Continue with game. Second CALL: * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044800C(U) :00448015 CALL 0044CAF0 <-- That's where it got called from the 2nd time. :0044801A TEST EAX, EAX <-- Same as above. :0044801C JE 00448036 <-- As above.
You simply change both CALL's to MOV EAX, 1, and the game should run smoothly.