Free Information Xchange '98 presents:

Shipwreckers! - CD crack by Static Vengeance

Requirements:
hex editor and full install

	Time for another tutorial on CD check removal.  This time we will be looking at a game called
Shipwreckers! by Psygnosis.  This game requires a 3D accelerator card and is kind of hard to describe.
It's and action puzzle type game somewhat like a platform jumper but no platforms.  Instead of a guy
to run around you drive a ship and blow things up and solve sequence puzzles and such.  Anywyas, the
graphics rock on a 3Dfx card, and the game is fun to play.  However as you can see by this article,
there is a bug or two in Shipwreckers!  Bugs that need to be FiX'ed.  There's that same old pesky CD
check that must pass before you can play a game.  And as you know the whole point of doing a full
install is so you can run the game off your hard drive.  I just hate digging through a stack of CD's
just so I can put the game CD in for a second for the copy protection to pass.  I can live without
the music tracks that come with the game.  So load up W32Dasm and start disassembling sw.exe.  When
W32Dasm has finished it's work go up to the menu bar and select "Refs" and then select "String data
references" from the drop down menu.  From the refs box, grab the slider bar and scroll down to the
string "SHIPWRECKERS! CD NOT PRESENT" and double click on it.  This puts you in the middle of the
routine that checks for the CD, and that routine goes something like this:

* Referenced by a CALL at Address:
|:004405C5                                        <-- Where this routine was called from
|
:00406FCC 53                      push ebx
:00406FCD 51                      push ecx
:00406FCE 52                      push edx
:00406FCF 55                      push ebp
:00406FD0 89E5                    mov ebp, esp
:00406FD2 89C3                    mov ebx, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040700C(U)
|
:00406FD4 E86BFDFFFF              call 00406D44                      <-- Check through WINMM.mciSendCommandA
:00406FD9 833DA0644B0001          cmp dword ptr [004B64A0], 00000001
:00406FE0 752C                    jne 0040700E                       <-- Take this jump if CD is there
:00406FE2 85DB                    test ebx, ebx
:00406FE4 7424                    je 0040700A
:00406FE6 6A35                    push 00000035

* Possible StringData Ref from Data Obj ->"Shipwreckers! CD Validator"
                                  |
:00406FE8 6834204B00              push 004B2034

* Possible StringData Ref from Data Obj ->"SHIPWRECKERS! CD NOT PRESENT"  <-- String that got us here
                                  |
:00406FED 6850204B00              push 004B2050
:00406FF2 53                      push ebx

* Reference To: USER32.MessageBoxA, Ord:0010h
                                  |
:00406FF3 2EFF1588134B00          Call dword ptr cs:[004B1388]
:00406FFA 85C0                    test eax, eax
:00406FFC 7405                    je 00407003
:00406FFE 83F802                  cmp eax, 00000002                 <-- You hit Cancel from dialog box
:00407001 7507                    jne 0040700A                      <-- If not Cancel then jump to retry

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406FFC(C)
|
:00407003 31C0                    xor eax, eax                      <-- Set for failed CD check
:00407005 5D                      pop ebp
:00407006 5A                      pop edx
:00407007 59                      pop ecx
:00407008 5B                      pop ebx
:00407009 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00406FE4(C), :00407001(C)
|
:0040700A 89D8                    mov eax, ebx
:0040700C EBC6                    jmp 00406FD4                     <-- Go back and try again

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406FE0(C)
|
:0040700E B801000000              mov eax, 00000001                <-- Everything is fine CD is present
:00407013 5D                      pop ebp
:00407014 5A                      pop edx
:00407015 59                      pop ecx
:00407016 5B                      pop ebx
:00407017 C3                      ret

	Fairly simple when you look at it.  The CD check is done through WINMM.DLL (WINdows Multi-Media)
calls like WINMM.mciSendCommandA and WINMM.mciGetErrorStringA.  The routine at 406D44 checks for a music
track and compares against known values.  If the routine doesn't find what it's looking for, then it's
assumed you don't have the original CD in your CD-ROM drive.  Okay, now let's take a quick look at the
section of code that calls the CD check routine.  That call and surounding code looks like this:

:004405B6 A174274E00              mov eax, dword ptr [004E2774]
:004405BB E8D05FFCFF              call 00406590
:004405C0 A174274E00              mov eax, dword ptr [004E2774]
:004405C5 E8026AFCFF              call 00406FCC                    <-- Do the CD check
:004405CA 85C0                    test eax, eax                    <-- Check the return value for pass/fail
:004405CC 752E                    jne 004405FC                     <-- Take this jump if it passed
:004405CE 8B0D74274E00            mov ecx, dword ptr [004E2774]
:004405D4 85C9                    test ecx, ecx
:004405D6 0F84E4FEFFFF            je 004404C0
:004405DC 6A10                    push 00000010

* Possible StringData Ref from Data Obj ->"Shipwreckers!"
                                  |
:004405DE 6825414B00              push 004B4125

* Possible StringData Ref from Data Obj ->"Shipwreckers! requires the original "  <-- Otherwise ask for the CD
                                        ->"CD to run."
                                  |
:004405E3 6833414B00              push 004B4133
:004405E8 51                      push ecx

* Reference To: USER32.MessageBoxA, Ord:0010h
                                  |
:004405E9 2EFF1588134B00          Call dword ptr cs:[004B1388]
:004405F0 E83B000000              call 00440630
:004405F5 31C0                    xor eax, eax                     <-- Setup for quiting back to Win95
:004405F7 5F                      pop edi
:004405F8 5E                      pop esi
:004405F9 59                      pop ecx
:004405FA 5B                      pop ebx
:004405FB C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004405CC(C)
|
:004405FC E80B020000              call 0044080C                   <-- If you got this far the CD is there
:00440601 85C0                    test eax, eax
:00440603 0F84B7FEFFFF            je 004404C0
:00440609 E8DA020000              call 004408E8
:0044060E 85C0                    test eax, eax
:00440610 0F84AAFEFFFF            je 004404C0
:00440616 E805040000              call 00440A20
:0044061B 85C0                    test eax, eax
:0044061D 0F849DFEFFFF            je 004404C0
:00440623 BE01000000              mov esi, 00000001
:00440628 89F0                    mov eax, esi                   <-- Set eax "for continue with the game"
:0044062A 5F                      pop edi
:0044062B 5E                      pop esi
:0044062C 59                      pop ecx
:0044062D 5B                      pop ebx
:0044062E C3                      ret

	There you have it, the easy way to crack this one is to change the call to the CD check
routine to mov eax, 00000001, this forces the jne 004405FC at 4405CC to always be taken.  This
in turns makes the game playable without the CD present, which is the whole purpose of this article.
Now you to need to make a registry edit to get the full motion videos to display: Open
HKEY_LOCAL_MACHINE\SOFTWARE\Psygnosis\Studios\Shipwreckers! and redirect "FMV Path" to the same
directory as "Path" and you'll have a 100% full working copy without the CD check.
	There is one last little problem I wanted to correct:  While the intro to the game is cool,
I could do without it and the same goes for the Psygnosis logo and Dolby intros.  So I set out to
kill the call to those.  Idealy I would have liked to have been able to disable just the Psygnosis
and Dolby intros and keep the game intro.  However if you have seen the game intro a couple of times
you just want to skip it anyways.  So here is how to get Shipwreckers! to start right up skipping all
the logo intros and go straight into the main menu screen.  First locate the refs to the intros:

* Referenced by a CALL at Address:
|:0043DC93                                                  <-- Where the routine is called from
|
:0043E35C 53                      push ebx
:0043E35D 51                      push ecx
:0043E35E 52                      push edx
:0043E35F 55                      push ebp
:0043E360 89E5                    mov ebp, esp
:0043E362 81EC18010000            sub esp, 00000118
:0043E368 81ED96010000            sub ebp, 00000196
:0043E36E 68402E4E00              push 004E2E40

* Possible StringData Ref from Data Obj ->"%spsyglogo.mpx"  <-- Psygnosis logo (mpeg file?)
                                  |
:0043E373 6884404B00              push 004B4084
:0043E378 8D457E                  lea eax, dword ptr [ebp+7E]
:0043E37B 50                      push eax
:0043E37C E8EF0B0100              call 0044EF70
:0043E381 83C40C                  add esp, 0000000C
:0043E384 BBE0010000              mov ebx, 000001E0
:0043E389 BA80020000              mov edx, 00000280
:0043E38E 6A02                    push 00000002
:0043E390 31C9                    xor ecx, ecx
:0043E392 8D457E                  lea eax, dword ptr [ebp+7E]
:0043E395 E85A320000              call 004415F4
:0043E39A 68402E4E00              push 004E2E40

* Possible StringData Ref from Data Obj ->"%sdolby.mpx"    <-- Dolby logo
                                  |
:0043E39F 6894404B00              push 004B4094
:0043E3A4 8D457E                  lea eax, dword ptr [ebp+7E]
:0043E3A7 50                      push eax
:0043E3A8 E8C30B0100              call 0044EF70
:0043E3AD 83C40C                  add esp, 0000000C
:0043E3B0 BBE0010000              mov ebx, 000001E0
:0043E3B5 BA80020000              mov edx, 00000280
:0043E3BA 6A02                    push 00000002
:0043E3BC 31C9                    xor ecx, ecx
:0043E3BE 8D457E                  lea eax, dword ptr [ebp+7E]
:0043E3C1 E82E320000              call 004415F4
:0043E3C6 68402E4E00              push 004E2E40

* Possible StringData Ref from Data Obj ->"%sintro.mpx"    <-- Game intro (cool to watch a couple of times)
                                  |
:0043E3CB 68A0404B00              push 004B40A0
:0043E3D0 8D457E                  lea eax, dword ptr [ebp+7E]
:0043E3D3 50                      push eax
:0043E3D4 E8970B0100              call 0044EF70
:0043E3D9 83C40C                  add esp, 0000000C
:0043E3DC BBE0010000              mov ebx, 000001E0
:0043E3E1 BA80020000              mov edx, 00000280
:0043E3E6 6A02                    push 00000002
:0043E3E8 31C9                    xor ecx, ecx
:0043E3EA 8D457E                  lea eax, dword ptr [ebp+7E]
:0043E3ED E802320000              call 004415F4
:0043E3F2 8DA596010000            lea esp, dword ptr [ebp+00000196]
:0043E3F8 5D                      pop ebp
:0043E3F9 5A                      pop edx
:0043E3FA 59                      pop ecx
:0043E3FB 5B                      pop ebx
:0043E3FC C3                      ret

	That's the routine that plays all the logo and intro files.  It has a single call to it so it
should be easy enough to disable.  The section the calls the above logo display routine looks like:

:0043DC87 31C0                    xor eax, eax
:0043DC89 A0E6844B00              mov al, byte ptr [004B84E6]
:0043DC8E E81564FDFF              call 004140A8
:0043DC93 E8C4060000              call 0043E35C                <-- Play the three logo files/movies
:0043DC98 E8DFB10200              call 00468E7C
:0043DC9D B838F64B00              mov eax, 004BF638
:0043DCA2 E825FB0000              call 0044D7CC

	Changing the call to five NOP's results in a program that starts at the main menu screen.  This
will save you about 20 megs on the hard drive after you delete those files (intro.mpx, dolby.mpx, and
psyglogo.mpx).  The edit needed to crack this game would be:

Edit sw.exe at offset 260,549
=============================
Search for: E8 02 6A FC FF
Change to : B8 01 00 00 00

OPTIONAL: To kill the intro files:

Edit sw.exe at offset 250,003
=============================
Search for: E8 C4 06 00 00
Change to : 90 90 90 90 90

	Now Shipwreckers! has been completly FiX'ed

Static Vengeance