
Free Information Xchange '98 presents:

Virtua Squad 2 - CD check crack by Static Vengeance

Requirements:
hex editor and full install

	Okay, time for another quick tutorial in CD check cracking.  Like all my the other tutorials
on CD checks you will need to use W32Dasm to follow along.  Alright, first thing you need to do is to
disassemble the exe file ppj2dd.exe.  Now when you run the game without the CD a dialog box comes up
and says you can cancel or play as a guest on the proving grounds.  Well I thought that would be easy
enough to find from the Refs/String data references in W32Dasm (IE: go up to the menu bar and select
"Refs" and then select "String data references" from the drop down menu).  However there is no direct
reference to that string.  But there was something even better when you scrolled down and checked out
what strings are referenced.  How about "VCOP2\PROJECT\PPJ2DD.EXE", that's a direct reference to the
exe file on the CD with the CD volume and all.  Well you should know by now that that has to be apart
of the CD checking routine, right?  So double clicking on that string will put you right in the middle
of the routine that checks for the CD and it goes something like this:

* Referenced by a CALL at Address:
|:0040E4B7   
|
:0040E420 83EC50                  sub esp, 00000050
:0040E423 53                      push ebx
:0040E424 56                      push esi
:0040E425 57                      push edi
:0040E426 33DB                    xor ebx, ebx          <-- Zero out number of runs through the CD check
:0040E428 55                      push ebp

* Reference To: KERNEL32.GetLogicalDrives, Ord:00FAh          <-- This is one tip off
                                  |
:0040E429 FF1510738000            Call dword ptr [00807310]
:0040E42F 8BE8                    mov ebp, eax

* Reference To: KERNEL32.lstrcatA, Ord:0292h
                                  |
:0040E431 8B350C738000            mov esi, dword ptr [0080730C]

* Reference To: USER32.wsprintfA, Ord:026Dh
                                  |
:0040E437 8B3D58748000            mov edi, dword ptr [00807458]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E48F(C)
|
:0040E43D B801000000              mov eax, 00000001
:0040E442 8ACB                    mov cl, bl
:0040E444 D3E0                    shl eax, cl
:0040E446 85C5                    test ebp, eax
:0040E448 7441                    je 0040E48B
:0040E44A 8D4341                  lea eax, dword ptr [ebx+41]
:0040E44D 8D4C2410                lea ecx, dword ptr [esp+10]
:0040E451 50                      push eax

* Possible StringData Ref from Data Obj ->"%c:\"                <-- Commonly used ref in CD checks
                                  |
:0040E452 687C974500              push 0045977C
:0040E457 51                      push ecx
:0040E458 FFD7                    call edi
:0040E45A 8D4C241C                lea ecx, dword ptr [esp+1C]
:0040E45E 83C40C                  add esp, 0000000C
:0040E461 51                      push ecx

* Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh              <-- Commonly used "text string" to search for
                                  |
:0040E462 FF1508738000            Call dword ptr [00807308]
:0040E468 83F805                  cmp eax, 00000005            <-- 05 is the value for a CD-ROM drive
:0040E46B 751E                    jne 0040E48B
:0040E46D 8D442410                lea eax, dword ptr [esp+10]

* Possible StringData Ref from Data Obj ->"VCOP2\PROJECT\PPJ2DD.EXE"   <-- Check for this file on CD
                                  |
:0040E471 6860974500              push 00459760
:0040E476 50                      push eax
:0040E477 FFD6                    call esi
:0040E479 8D442410                lea eax, dword ptr [esp+10]
:0040E47D 6A00                    push 00000000
:0040E47F 50                      push eax

* Reference To: KERNEL32._lopen, Ord:028Eh
                                  |
:0040E480 FF1504738000            Call dword ptr [00807304]
:0040E486 83F8FF                  cmp eax, FFFFFFFF
:0040E489 7508                    jne 0040E493

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040E448(C), :0040E46B(C)
|
:0040E48B 43                      inc ebx                     <-- Made another check, add 1 to ebx
:0040E48C 83FB20                  cmp ebx, 00000020           <-- Try up to 20h (32) times
:0040E48F 7CAC                    jl 0040E43D                 <-- Keep trying to fid the CD until you hit 32
:0040E491 EB07                    jmp 0040E49A                <-- Tried 32 times and STILL didn't find it

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E489(C)
|
:0040E493 50                      push eax

* Reference To: KERNEL32._lclose, Ord:028Bh
                                  |
:0040E494 FF1500738000            Call dword ptr [00807300]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E491(U)
|
:0040E49A B8FFFFFFFF              mov eax, FFFFFFFF         <-- Set up for a failed CD check
:0040E49F 83FB20                  cmp ebx, 00000020         <-- Did we fail to find the file 32 times?
:0040E4A2 7402                    je 0040E4A6               <-- The all important instruction
:0040E4A4 8BC3                    mov eax, ebx              <-- Anything else is passed CD check

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E4A2(C)
|
:0040E4A6 5D                      pop ebp
:0040E4A7 5F                      pop edi
:0040E4A8 5E                      pop esi
:0040E4A9 5B                      pop ebx
:0040E4AA 83C450                  add esp, 00000050
:0040E4AD C3                      ret

	That's the section of code that checks for the program file on the CD.  If the CD check failed
eax is loaded with FFFFFFFF, otherwise anything else means the CD is in your CD-ROM drive...  If you
don't have a CD in the drive, the ONLY choice you have is to play over the modem/net or exit to Win95.
So lets check out the code the calls the above routine and see what it does:

* Referenced by a CALL at Address:
|:0040D61A   
|
:0040E4B0 56                      push esi

* Reference To: USER32.DialogBoxParamA, Ord:008Eh
                                  |
:0040E4B1 8B3530748000            mov esi, dword ptr [00807430]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E4FB(C)
|
:0040E4B7 E864FFFFFF              call 0040E420                   <-- Check for original CD
:0040E4BC 8B15C0B85200            mov edx, dword ptr [0052B8C0]
:0040E4C2 8B0D7CB85200            mov ecx, dword ptr [0052B87C]
:0040E4C8 A3D8B85200              mov dword ptr [0052B8D8], eax   <-- Store the returned value
:0040E4CD 83F8FF                  cmp eax, FFFFFFFF               <-- Was it present?
:0040E4D0 A1DCB85200              mov eax, dword ptr [0052B8DC]
:0040E4D5 752D                    jne 0040E504                    <-- This jump taked for passed CD check
:0040E4D7 6A00                    push 00000000
:0040E4D9 8B0485B8954500          mov eax, dword ptr [4*eax+004595B8]
:0040E4E0 6820E54000              push 0040E520
:0040E4E5 51                      push ecx
:0040E4E6 50                      push eax
:0040E4E7 52                      push edx
:0040E4E8 FFD6                    call esi
:0040E4EA 8B0D48964500            mov ecx, dword ptr [00459648]
:0040E4F0 85C0                    test eax, eax
:0040E4F2 7405                    je 0040E4F9
:0040E4F4 83F902                  cmp ecx, 00000002    <-- Hit cancel, so set up to quit to Win95
:0040E4F7 7412                    je 0040E50B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E4F2(C)
|
:0040E4F9 85C0                    test eax, eax
:0040E4FB 75BA                    jne 0040E4B7          <-- Loop up and retry to read for the CD
:0040E4FD B8FFFFFFFF              mov eax, FFFFFFFF     <-- Play as the guest in the multiplayer
:0040E502 5E                      pop esi               <-- mode of the "Proving Gounds"
:0040E503 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E4D5(C)
|
:0040E504 B801000000              mov eax, 00000001    <-- Everything is good, let the user PLAY!
:0040E509 5E                      pop esi
:0040E50A C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E4F7(C)
|
:0040E50B 33C0                    xor eax, eax         <-- Set up for exit to Win95
:0040E50D 5E                      pop esi
:0040E50E C705D8B8520000000000    mov dword ptr [0052B8D8], 00000000
:0040E518 C3                      ret

	Okay, there are four possible choices from the CD checking rountine.  First choice is
the CD is there and everything is just fine: eax is loaded with 00000001.  However the other
three choices come into play if no CD is found.  You either retry to read the CD in which case
the code simply loops back up and tries again.  You can choose to play as a guest in the multi-
player mode on the proving grounds: eax is loaded with FFFFFFFF, or you hit cancel and you're
booted back to Win95: eax is zeroed out.  So once agian we trace the program further back and
take a look at the calling code to see what it does:

  -- Program Code --
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D5E5(C)
|
:0040D60B E8C0110000              call 0040E7D0
:0040D610 E82BFD0100              call 0042D340
:0040D615 A344964500              mov dword ptr [00459644], eax
:0040D61A E8910E0000              call 0040E4B0                     <-- Do CD check
:0040D61F A340964500              mov dword ptr [00459640], eax     <-- Store returned value here
:0040D624 83F8FF                  cmp eax, FFFFFFFF                 <-- What happenned with CD check?
:0040D627 0F840D030000            je 0040D93A                       <-- No CD, but play as guest
:0040D62D 8BBC24B0000000          mov edi, dword ptr [esp+000000B0] <-- Continue with program
:0040D634 8D442410                lea eax, dword ptr [esp+10]
:0040D638 33DB                    xor ebx, ebx
:0040D63A 893DC0B85200            mov dword ptr [0052B8C0], edi
:0040D640 897C2428                mov dword ptr [esp+28], edi
:0040D644 6A7B                    push 0000007B
:0040D646 57                      push edi

* Reference To: USER32.LoadIconA, Ord:017Ch
                                  |
:0040D647 8B2D00748000            mov ebp, dword ptr [00807400]
  -- More Program Code --

	This is the section of code we want to deal with right here.  This is the only call
to the CD check routine (from 40D61A) and then the program code decides what to do with the
value that was returned from the CD check.  What I thought would be a good crack for this
game was to change the Call 0040E4B0 to mov eax,00000001.  That way the CD check is never
made and the 00000001 in eax simulates a successful CD check.  I made the patch to the
program file and tested it.  All functions work and it never cares if you have the CD in
the CD-ROM drive or not.  Make the edit to the file ppj2dd.exe and you have cracked this
one.  The only other thing I did was rename the file to VirtuaCop.exe and changed the Win95
shortcut to match.

Edit ppj2dd.exe at offset 51,738
================================
Search for: E8 91 0E 00 00
chagne to : B8 01 00 00 00

That's all it takes to FiX Virtua Squad 2

Static Vengeance
