HOW TO DEFEAT THE CD-LOCK PROTECTiON.
written by (c) zoltan
  _ __ ___ __________________________________________________________________________________ ___ __ _

-COMMANDOS: Behind Enemy Lines
  _ __ ___ __________________________________________________________________________________ ___ __ _

 TOOLS REQUIRED:
              -
              SoftIce 4.0
                - se below for url.

              W32Dasm, (if you want to folow)
                - se below for url.

              Hackers View 6.15
                - se below for url.

              Commandos: Behind Enemy Lines
                - buy it or get the ripp + original exe.
 TOOL SITE:

              HTTP://PROTOOLS.CJB.NET  a nice tool site...

  _ __ ___ __________________________________________________________________________________ ___ __ _

Briefing about cd-lock:

Today nearly all games that get published has a form of protection called iSO protection (in the scene). It is there to prevent
end-users for pirating cd's by just copying them at home with cd-burners. Today im going to Teach you how to "FiX" one of these
protection's called CD-LOCK. How can you check if the cd you have is protected by CD-LOCK, simply explore your cd-drive and look
for  4 huge (.afp) files.

Inctroduction:

Another famous game in the world, Commandos. This one was released to the public by CLASS PC on the 24th of June 1998. It's been
availible for download on  the internet ever since.  Think i leeched it the same day, and got the original (protected) exe from
some friends i have in the scene. I started cracking this (cd-check) like i thoght it was, because i haad never even heard of
this cd-lock protection. Anyway i cracked it fairly easy, but i haad to admit to my self that this must been one of the hardest
(cd-check, like i thoght) i  haad ever done. Few months later i heard about this cd-lock protection, and i was like uhh ohh ?
that protection got it's own name, cool! ;). I actuly love cracking protections that got their own name like CD-lock. Anyways
enough shit chat, Start off by deleting the commandos.exe witch is Class' intro, or simply copy it over to another dir, if you
want to collect  that junk like it do. Now u delete the betasux.exe, because that is the cracked exe from Class, and we dont
need  it since  we are going to crack this game ourselfs. Run commandos.exe, break on GetDriveTypea, press the start a new
gamen and you should be landing here:


* Referenced by a CALL at Address:
|:0044CAFF                                     <- where this whole protections was
|                                               \ called from ..
:004949F0 83EC08                  sub esp, 00000008
:004949F3 A1D0266000              mov eax, dword ptr [006026D0]
:004949F8 89442400                mov dword ptr [esp], eax
:004949FC 53                      push ebx
:004949FD 56                      push esi
:004949FE B341                    mov bl, 41
:00494A00 57                      push edi

* Reference To: KERNEL32.GetDriveTypeA, Ord:00CEh                  
                                  |
:00494A01 8B3514266600            mov esi, dword ptr [00662614]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494A8C(C)
|
:00494A07 8D44240C                lea eax, dword ptr [esp+0C]
:00494A0B 885C240C                mov byte ptr [esp+0C], bl
:00494A0F 50                      push eax
:00494A10 FFD6                    call esi                       <- you are here.
:00494A12 83F805                  cmp eax, 00000005              <- compare if drive is a cd-drive
:00494A15 7570                    jne 00494A87                   <- jump if not equal

* Possible StringData Ref from Data Obj ->"rb"                   <- string that means READ
                                  |
:00494A17 68900F5F00              push 005F0F90
:00494A1C 881D10266000            mov byte ptr [00602610], bl

* Possible StringData Ref from Data Obj ->"d:\TBTP.AFP"          <- our friend.
                                  |
:00494A22 6810266000              push 00602610                  <- cdletter:\TBTP.AFP
:00494A27 881D20266000            mov byte ptr [00602620], bl    <- cdletter:\BBVN.AFP
:00494A2D 881D30266000            mov byte ptr [00602630], bl    <- cdletter:\ETAO.AFP
:00494A33 881D40266000            mov byte ptr [00602640], bl    <- cdletter:\BTBW.AFP
:00494A39 E8D2A81300              call 005CF310                  <- check if they are there ..
:00494A3E 83C408                  add esp, 00000008
:00494A41 8BF8                    mov edi, eax                   <- mov checksum result to edi
:00494A43 85FF                    test edi, edi                  <- if edi == 1
:00494A45 750A                    jne 00494A51                   <- the files exists! ..
:00494A47 C744241000000000        mov [esp+10], 00000000      <- mov [esp+10], 0 = file doesnt exist
:00494A4F EB2E                    jmp 00494A7F                   <- jump and try again.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494A45(C)
|
:00494A51 6A00                    push 00000000
:00494A53 6800A08329              push 2983A000
:00494A58 57                      push edi
:00494A59 E8C2AD1300              call 005CF820                  <- SetFilePointer
:00494A5E 83C40C                  add esp, 0000000C
:00494A61 57                      push edi
:00494A62 E879AD1300              call 005CF7E0                  <- ReadFile
:00494A67 83C404                  add esp, 00000004
:00494A6A 33C9                    xor ecx, ecx
:00494A6C 83F829                  cmp eax, 00000029              <- compare ...
:00494A6F 0F94C1                  sete cl
:00494A72 894C2410                mov dword ptr [esp+10], ecx
:00494A76 57                      push edi
:00494A77 E8F4A71300              call 005CF270
:00494A7C 83C404                  add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494A4F(U)
|
:00494A7F 8B442410                mov eax, dword ptr [esp+10]   <- if [esp+10] = 1 your good cracker.
:00494A83 85C0                    test eax, eax                 <- if eax == 1 then jump ..
:00494A85 7514                    jne 00494A9B                  <- continue with game ...

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494A15(C)
|
:00494A87 FEC3                    inc bl
:00494A89 80FB5A                  cmp bl, 5A                    <- compare bl, 5Ah
:00494A8C 0F8E75FFFFFF            jle 00494A07                  <- jump and try again with next drive.
:00494A92 33C0                    xor eax, eax                  <- baad cracker.
:00494A94 5F                      pop edi
:00494A95 5E                      pop esi
:00494A96 5B                      pop ebx
:00494A97 83C408                  add esp, 00000008
:00494A9A C3                      ret



* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494A85(C)
|
:00494A9B B801000000              mov eax, 00000001             <-  good cracker.
:00494AA0 5F                      pop edi
:00494AA1 5E                      pop esi
:00494AA2 5B                      pop ebx
:00494AA3 83C408                  add esp, 00000008
:00494AA6 C3                      ret







NOW. goto the code location where all this shit was called from, you should be here:




* Referenced by a CALL at Addresses: 
|:00447E9C   , :00448015                                         <- (here are the 2 calls)
|
:0044CAF0 83EC0C                  sub esp, 0000000C
:0044CAF3 A1980A5F00              mov eax, dword ptr [005F0A98]
:0044CAF8 85C0                    test eax, eax
:0044CAFA 90                      nop
:0044CAFB 53                      push ebx
:0044CAFC 56                      push esi
:0044CAFD 7413                    je 0044CB12
:0044CAFF E8EC7E0400              call 004949F0                  <- call check ..
:0044CB04 85C0                    test eax, eax                  <- eax=1
:0044CB06 740A                    je 0044CB12                    <- continue with game ..
:0044CB08 C705980A5F0000000000    mov dword ptr [005F0A98], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0044CAFD(C), :0044CB06(C)
|

* Possible StringData Ref from Data Obj ->"rb"
                                  |
:0044CB12 68900F5F00              push 005F0F90
:0044CB17 BB00000000              mov ebx, 00000000

* Possible StringData Ref from Data Obj ->"d:\TBTP.AFP"
                                  |
:0044CB1C 6810266000              push 00602610
:0044CB21 E8EA271800              call 005CF310
:0044CB26 83C408                  add esp, 00000008
:0044CB29 8BF0                    mov esi, eax
more code more code ...who cares about it ...






The best and the simplest way to crack this protection is probably to find where the protection was called
from then just simply do like this:

:00447E91 8883100D0000            mov byte ptr [ebx+00000D10], al
:00447E97 E834321200              call 0056B0D0
:00447E9C E84F4C0000              call 0044CAF0              <- where it was called from the first time.
:00447EA1 85C0                    test eax, eax              <- eax=1 = good cracker, eax=0 = baad cracker
:00447EA3 7418                    je 00447EBD                <- continue with game ..
:00447EA5 8D442418                lea eax, dword ptr [esp+18]
:00447EA9 8B4C2434                mov ecx, dword ptr [esp+34]


Second Call:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044800C(U)
|
:00448015 E8D64A0000              call 0044CAF0             <- that's where it got called from the 2th time.
:0044801A 85C0                    test eax, eax             <- same as above. 
:0044801C 7418                    je 00448036               <- same as above..
:0044801E 8D442418                lea eax, dword ptr [esp+18]



You simply change both calls to mov eax, 1, and the game should run smooth. ;)


Special greets to: BMonkey, Carphatia, +Fravia, Neural_Noise ...