####################
   #iMBUE##############
   ##Crazy#Taxi#No#CD##
   ##############dohze.

Intro::
Erm, I got the demo of this off some free cd on a magazine and thought it was pretty good so
I downloaded the image of it and burned it off.  As always it's a bitch having to reach for
the cd so I went a head and cracked it.

Tools needed::
I used these:
Hiew
WDasm
OllyDBG
but you can probably just use softice or something :)

On with the show::
Okay, now run the game without the cd and you'll get an error, something like "PLease insert
original disk".  Now I like to make a copy of the original .exe file and crack that, then make
the patch and apply it to the original to test that the patch actually works, if you know what
I mean...but anyway, however you please.
Dissassemble the .exe file (Crazy_Taxi_PC.exe) and look in string references for the error
message.  You won't find it so instead look in imported functions for GetDriveTypeA.  Luckily
there is only one reference of it and this is around 00429DB9.  Now we gotta see where it checks
and decides whether to show the error or let the program run, so get your debugger sorted and
set a breakpoint on GetDriveTypeA.  You should break in the middle of a kind of loop, shown
below:

00429DC7  |> A1 589D9700    /MOV EAX,DWORD PTR DS:[979D58]
00429DCC  |. 85C0           |TEST EAX,EAX
00429DCE  |. 74 50          |JE SHORT Crazy_Ta.00429E20
00429DD0  |. B8 01000000    |MOV EAX,1
00429DD5  |. D3E0           |SHL EAX,CL
00429DD7  |. 85C0           |TEST EAX,EAX
00429DD9  |. 74 45          |JE SHORT Crazy_Ta.00429E20
00429DDB  |. 8AD9           |MOV BL,CL
00429DDD  |. 8D5424 18      |LEA EDX,DWORD PTR SS:[ESP+18]
00429DE1  |. 80C3 41        |ADD BL,41
00429DE4  |. 0FBECB         |MOVSX ECX,BL
00429DE7  |. 51             |PUSH ECX
00429DE8  |. 68 4C4F4F00    |PUSH Crazy_Ta.004F4F4C                  ;  ASCII "%c:\"
00429DED  |. 52             |PUSH EDX
00429DEE  |. FFD6           |CALL ESI
00429DF0  |. 83C4 0C        |ADD ESP,0C
00429DF3  |. 8D4424 18      |LEA EAX,DWORD PTR SS:[ESP+18]
00429DF7  |. 50             |PUSH EAX
00429DF8  |. FFD7           |CALL EDI                     <<Here is where it calls GetDriveTypeA
00429DFA  |. 83F8 05        |CMP EAX,5
00429DFD  |. 75 1D          |JNZ SHORT Crazy_Ta.00429E1C
00429DFF  |. 8D4C24 18      |LEA ECX,DWORD PTR SS:[ESP+18]
00429E03  |. 51             |PUSH ECX
00429E04  |. 55             |PUSH EBP
00429E05  |. E8 E6FEFFFF    |CALL Crazy_Ta.00429CF0
00429E0A  |. 83C4 08        |ADD ESP,8
00429E0D  |. 84C0           |TEST AL,AL
00429E0F  |. 74 0B          |JE SHORT Crazy_Ta.00429E1C
00429E11  |. C64424 13 01   |MOV BYTE PTR SS:[ESP+13],1
00429E16  |. 881D 509D9700  |MOV BYTE PTR DS:[979D50],BL
00429E1C  |> 8B4C24 14      |MOV ECX,DWORD PTR SS:[ESP+14]
00429E20  |> 41             |INC ECX
00429E21  |. 83F9 1A        |CMP ECX,1A
00429E24  |. 894C24 14      |MOV DWORD PTR SS:[ESP+14],ECX
00429E28  |.^7C 9D          \JL SHORT Crazy_Ta.00429DC7
(copied from OllyDBG)

Now if you step through the code you will notice that this is simply where the game checks to
determine if the cd is in the drive and which drive it is in.  So really this is close to where
we need to be, but not it.
Keep stepping through the code (it will perform the loop 26 times, a check for each letter of the
alphabet :P) until you come out of the loop and reach a return which will make you end up at
0042A183

Now we're where we need to be :)
The code below should look like this:

0042A17E  |. E8 1DFCFFFF    CALL Crazy_Ta.00429DA0           <<This is the call you were in
0042A183  |. 83C4 04        ADD ESP,4                        <<You returned here
0042A186  |. 84C0           TEST AL,AL                       <<Tests to see if cd is in
0042A188  |. 75 46          JNZ SHORT Crazy_Ta.0042A1D0      <<Takes you to the game if cd is in
0042A18A  |. 68 FF000000    PUSH 0FF                                 ; /Count = FF (255.)
0042A18F  |. 8D8D 94FCFFFF  LEA ECX,DWORD PTR SS:[EBP-36C]           ; |
0042A195  |. 51             PUSH ECX                                 ; |Buffer
0042A196  |. 6A 03          PUSH 3                                   ; |RsrcID = 3
0042A198  |. 8B15 249D9700  MOV EDX,DWORD PTR DS:[979D24]            ; |en.10000000
0042A19E  |. 52             PUSH EDX                                 ; |hInst => 10000000
0042A19F  |. FF15 2C124C00  CALL DWORD PTR DS:[<&USER32.LoadStringA>>; \LoadStringA  <<error msg
0042A1A5  |. 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
0042A1A7  |. 68 30314F00    PUSH Crazy_Ta.004F3130                   ; |Title = "Crazy Taxi"
0042A1AC  |. 8D85 94FCFFFF  LEA EAX,DWORD PTR SS:[EBP-36C]           ; |
0042A1B2  |. 50             PUSH EAX                                 ; |Text
0042A1B3  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
0042A1B5  |. FF15 E0114C00  CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
0042A1BB  |. 33C0           XOR EAX,EAX
0042A1BD  |. 8B4D F0        MOV ECX,DWORD PTR SS:[EBP-10]

Now, as you can see from above, all we need to do is patch the jump at 0042A188 from a jnz to
a regular jmp (bytes 7546 changed to EB46).  I'm not sure how we get the offset from OllyDBG
(if anyone knows pls mail me, dohze@imbue.cjb.net) so we go into WDasm and look up code
0042A188 and get the offset: 0002A188
Now all we gotta do is patch at that offset from 75 to EB and that's it!

Credits::
Feel free to criticise my work, comment on it, maybe even request something or other @
dohze@imbue.cjb.net

Disclaimer::
Please note:  If I ever download a game I intend to use that game only as a trial for a period
of maybe 24hrs, if I decide I like the game I will therefore buy it and recommend you do too.
Whatever you do with this knowledge is your business and therefore I cannot be held responsible
if anything goes wrong...