-----------------------------------------------------+
These informations are for educational purposes only!|
-----------------------------------------------------+


Free Information Xchange '98 presents:

Mortal Kombat 3 - CD crack by Static Vengeance

Requirements:
Full install and hex editor
W32Dasm if you want to follow along

	While Mortal Kombat 3 for Win95 is a VERY old game it has a useful purpose here.  It's another
example of a CD check and how to bypass it, plus it shows how some games can be moved off a CD to your
hard drive.  First of all, you need to install the game to your hard drive.  When you check what was
installed you'll find just 4 files are placed on your hard drive.  Looking at all the files on the CD
it's clear we will have to do some manual work to get the whole program to be completly runnable from
our hard drives.  The most likley thing we'll need to do is copy all the subdirectories to the same
subdirectory we installed MK3 to.  This'll get things rolling, so let's try to run the program.  No good,
it comes up and asks for the MK3 CD.  So get W32Dasm up and running and disassemble mk3w.exe.  When
W32Dasm is done, go up to the menu bar, select "Refs" and then select "Data String Refs" from the drop
down menu.  Now once the Data String Refs box pops up, grab the slider bar and scroll down to "Please
insert the Mortal Kombat III CD"  Double clicking this will put you in the middle of the CD check:

* Referenced by a CALL at Address:
|:00455778                                        <-- Called once from 455778
|
:004552CA 55                      push ebp
:004552CB 8BEC                    mov ebp, esp
:004552CD 81EC78040000            sub esp, 00000478
:004552D3 53                      push ebx
:004552D4 56                      push esi
:004552D5 57                      push edi
:004552D6 C785A0FCFFFF00000000    mov dword ptr [ebp+FFFFFCA0], 00000000

* Reference To: KERNEL32.GetCommandLineA, Ord:00A1h
                                  |
:004552E0 FF1584B37700            Call dword ptr [0077B384]
:004552E6 8985F0FDFFFF            mov dword ptr [ebp+FFFFFDF0], eax

* Possible StringData Ref from Data Obj ->"mk3w.exe"                     <-- REF to the EXE file
                                  |
:004552EC 68B0116A00              push 006A11B0
:004552F1 8B85F0FDFFFF            mov eax, dword ptr [ebp+FFFFFDF0]
:004552F7 50                      push eax
:004552F8 E83F310000              call 0045843C
:004552FD 83C408                  add esp, 00000008
:00455300 8985ECFDFFFF            mov dword ptr [ebp+FFFFFDEC], eax

* Possible StringData Ref from Data Obj ->"xxxxx"
                                  |
:00455306 68BC116A00              push 006A11BC
:0045530B 8B85F0FDFFFF            mov eax, dword ptr [ebp+FFFFFDF0]
:00455311 50                      push eax
:00455312 E825310000              call 0045843C
:00455317 83C408                  add esp, 00000008
:0045531A 8985ECFDFFFF            mov dword ptr [ebp+FFFFFDEC], eax
:00455320 83BDECFDFFFF00          cmp dword ptr [ebp+FFFFFDEC], 00000000
:00455327 0F8539000000            jne 00455366
:0045532D 68F8A84600              push 0046A8F8
:00455332 6804010000              push 00000104

* Reference To: KERNEL32.GetCurrentDirectoryA, Ord:00C4h
                                  |
:00455337 FF150CB37700            Call dword ptr [0077B30C]

* Possible StringData Ref from Data Obj ->"\"
                                  |
:0045533D 68C4116A00              push 006A11C4
:00455342 68F8A84600              push 0046A8F8
:00455347 E8D82F0000              call 00458324
:0045534C 83C408                  add esp, 00000008
:0045534F 68F8A84600              push 0046A8F8
:00455354 68F8A74600              push 0046A7F8
:00455359 E8CA2F0000              call 00458328
:0045535E 83C408                  add esp, 00000008
:00455361 E92F000000              jmp 00455395

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455327(C)
|
:00455366 8B85ECFDFFFF            mov eax, dword ptr [ebp+FFFFFDEC]
:0045536C C60000                  mov byte ptr [eax], 00
:0045536F 8B85F0FDFFFF            mov eax, dword ptr [ebp+FFFFFDF0]
:00455375 50                      push eax
:00455376 68F8A84600              push 0046A8F8
:0045537B E8A82F0000              call 00458328
:00455380 83C408                  add esp, 00000008
:00455383 68F8A84600              push 0046A8F8
:00455388 68F8A74600              push 0046A7F8
:0045538D E8962F0000              call 00458328
:00455392 83C408                  add esp, 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455361(U)
|
:00455395 68F8A84600              push 0046A8F8

* Reference To: KERNEL32.GetDriveTypeA, Ord:00D0h             <-- Common called used in CD check routines
                                  |
:0045539A FF1504B37700            Call dword ptr [0077B304]
:004553A0 83F805                  cmp eax, 00000005           <-- 05 is the value for a CD-ROM drive
:004553A3 0F84A5000000            je 0045544E                 <-- Take this jump is a CD-ROM drive is found
:004553A9 68F8A84600              push 0046A8F8

* Reference To: KERNEL32.GetDriveTypeA, Ord:00D0h
                                  |
:004553AE FF1504B37700            Call dword ptr [0077B304]
:004553B4 83F802                  cmp eax, 00000002
:004553B7 0F8491000000            je 0045544E
:004553BD 68F8A84600              push 0046A8F8

* Reference To: KERNEL32.GetDriveTypeA, Ord:00D0h
                                  |
:004553C2 FF1504B37700            Call dword ptr [0077B304]
:004553C8 83F806                  cmp eax, 00000006
:004553CB 0F847D000000            je 0045544E
:004553D1 8D8594FBFFFF            lea eax, dword ptr [ebp+FFFFFB94]
:004553D7 50                      push eax
:004553D8 8D858CFBFFFF            lea eax, dword ptr [ebp+FFFFFB8C]
:004553DE 50                      push eax
:004553DF 6A00                    push 00000000
:004553E1 683F000F00              push 000F003F
:004553E6 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"MK3"
                                  |
:004553E8 68C8116A00              push 006A11C8
:004553ED 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"\SOFTWARE\Mortal Kombat III"   <-- Open registry path
                                  |
:004553EF 68CC116A00              push 006A11CC
:004553F4 6802000080              push 80000002

* Reference To: ADVAPI32.RegCreateKeyExA, Ord:00B7h
                                  |
:004553F9 FF159CB27700            Call dword ptr [0077B29C]
:004553FF 898590FBFFFF            mov dword ptr [ebp+FFFFFB90], eax
:00455405 68F8A84600              push 0046A8F8
:0045540A E8C52E0000              call 004582D4
:0045540F 83C404                  add esp, 00000004
:00455412 50                      push eax
:00455413 68F8A84600              push 0046A8F8
:00455418 6A01                    push 00000001
:0045541A 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"path"              <-- Get installation path
                                  |
:0045541C 68E8116A00              push 006A11E8
:00455421 8B858CFBFFFF            mov eax, dword ptr [ebp+FFFFFB8C]
:00455427 50                      push eax

* Reference To: ADVAPI32.RegSetValueExA, Ord:00DBh
                                  |
:00455428 FF15A4B27700            Call dword ptr [0077B2A4]
:0045542E 898590FBFFFF            mov dword ptr [ebp+FFFFFB90], eax
:00455434 8B858CFBFFFF            mov eax, dword ptr [ebp+FFFFFB8C]
:0045543A 50                      push eax

* Reference To: ADVAPI32.RegFlushKey, Ord:00C4h
                                  |
:0045543B FF1598B27700            Call dword ptr [0077B298]
:00455441 8B858CFBFFFF            mov eax, dword ptr [ebp+FFFFFB8C]
:00455447 50                      push eax

* Reference To: ADVAPI32.RegCloseKey, Ord:00B3h
                                  |
:00455448 FF15A0B27700            Call dword ptr [0077B2A0]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004553A3(C), :004553B7(C), :004553CB(C)
|

* Reference To: KERNEL32.GetLogicalDrives, Ord:00E9h                   <-- Commonly used call in CD checks
                                  |
:0045544E FF1508B37700            Call dword ptr [0077B308]
:00455454 89859CFCFFFF            mov dword ptr [ebp+FFFFFC9C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004555CE(C)
|
:0045545A C78588FBFFFF00000000    mov dword ptr [ebp+FFFFFB88], 00000000
:00455464 E906000000              jmp 0045546F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455587(U)
|
:00455469 FF8588FBFFFF            inc dword ptr [ebp+FFFFFB88]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455464(U)
|
:0045546F 83BD88FBFFFF20          cmp dword ptr [ebp+FFFFFB88], 00000020
:00455476 0F8D10010000            jnl 0045558C
:0045547C B801000000              mov eax, 00000001
:00455481 8A8D88FBFFFF            mov cl, byte ptr [ebp+FFFFFB88]
:00455487 D3E0                    shl eax, cl
:00455489 85859CFCFFFF            test dword ptr [ebp+FFFFFC9C], eax
:0045548F 0F84F2000000            je 00455587
:00455495 8B8588FBFFFF            mov eax, dword ptr [ebp+FFFFFB88]
:0045549B 83C061                  add eax, 00000061
:0045549E 50                      push eax

* Possible StringData Ref from Data Obj ->"%c:\"                    <-- Another common REF in CD checks
                                  |
:0045549F 68F0116A00              push 006A11F0
:004554A4 8D85F8FDFFFF            lea eax, dword ptr [ebp+FFFFFDF8]
:004554AA 50                      push eax

* Reference To: USER32.wsprintfA, Ord:0248h
                                  |
:004554AB FF1504B47700            Call dword ptr [0077B404]
:004554B1 83C40C                  add esp, 0000000C
:004554B4 8D85F8FDFFFF            lea eax, dword ptr [ebp+FFFFFDF8]
:004554BA 50                      push eax

* Reference To: KERNEL32.GetDriveTypeA, Ord:00D0h                   <-- Commonly used call in CD checks
                                  |
:004554BB FF1504B37700            Call dword ptr [0077B304]
:004554C1 83F805                  cmp eax, 00000005                 <-- 05 is the code for CD-ROM drive
:004554C4 0F85BD000000            jne 00455587
:004554CA C685FCFEFFFF00          mov byte ptr [ebp+FFFFFEFC], 00
:004554D1 6A00                    push 00000000
:004554D3 6A00                    push 00000000
:004554D5 8D85E4FDFFFF            lea eax, dword ptr [ebp+FFFFFDE4]
:004554DB 50                      push eax
:004554DC 8D85E8FDFFFF            lea eax, dword ptr [ebp+FFFFFDE8]
:004554E2 50                      push eax
:004554E3 6A00                    push 00000000
:004554E5 6804010000              push 00000104
:004554EA 8D85FCFEFFFF            lea eax, dword ptr [ebp+FFFFFEFC]
:004554F0 50                      push eax
:004554F1 8D85F8FDFFFF            lea eax, dword ptr [ebp+FFFFFDF8]
:004554F7 50                      push eax

* Reference To: KERNEL32.GetVolumeInformationA, Ord:0135h           <-- Get the volume name
                                  |
:004554F8 FF1514B37700            Call dword ptr [0077B314]
:004554FE 8D85FCFEFFFF            lea eax, dword ptr [ebp+FFFFFEFC]
:00455504 50                      push eax
:00455505 E8A47B0000              call 0045D0AE
:0045550A 83C404                  add esp, 00000004

* Possible StringData Ref from Data Obj ->"MK3PCCDROM"              <-- Volume name of CD
                                  |
:0045550D 68F8116A00              push 006A11F8
:00455512 8D85FCFEFFFF            lea eax, dword ptr [ebp+FFFFFEFC]
:00455518 50                      push eax
:00455519 E89A2E0000              call 004583B8
:0045551E 83C408                  add esp, 00000008
:00455521 85C0                    test eax, eax
:00455523 0F855E000000            jne 00455587
:00455529 C785A0FCFFFF01000000    mov dword ptr [ebp+FFFFFCA0], 00000001
:00455533 8B8588FBFFFF            mov eax, dword ptr [ebp+FFFFFB88]
:00455539 83C061                  add eax, 00000061
:0045553C 50                      push eax

* Possible StringData Ref from Data Obj ->"%c:\attract\controlp.bin"  <-- Check for this file (CD path)
                                  |
:0045553D 6804126A00              push 006A1204
:00455542 8D8598FBFFFF            lea eax, dword ptr [ebp+FFFFFB98]
:00455548 50                      push eax

* Reference To: USER32.wsprintfA, Ord:0248h
                                  |
:00455549 FF1504B47700            Call dword ptr [0077B404]
:0045554F 83C40C                  add esp, 0000000C
:00455552 8D85A4FCFFFF            lea eax, dword ptr [ebp+FFFFFCA4]
:00455558 50                      push eax
:00455559 8D8598FBFFFF            lea eax, dword ptr [ebp+FFFFFB98]
:0045555F 50                      push eax

* Reference To: KERNEL32.FindFirstFileA, Ord:007Bh
                                  |
:00455560 FF1500B37700            Call dword ptr [0077B300]
:00455566 85C0                    test eax, eax
:00455568 0F8414000000            je 00455582
:0045556E 8D85F8FDFFFF            lea eax, dword ptr [ebp+FFFFFDF8]
:00455574 50                      push eax
:00455575 68F8A84600              push 0046A8F8
:0045557A E8A92D0000              call 00458328
:0045557F 83C408                  add esp, 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455568(C)
|
:00455582 E905000000              jmp 0045558C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0045548F(C), :004554C4(C), :00455523(C)
|
:00455587 E9DDFEFFFF              jmp 00455469

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00455476(C), :00455582(U)
|
:0045558C 83BDA0FCFFFF00          cmp dword ptr [ebp+FFFFFCA0], 00000000
:00455593 0F852E000000            jne 004555C7
:00455599 6A05                    push 00000005

* Possible StringData Ref from Data Obj ->"MKIII Win95"
                                  |
:0045559B 6820126A00              push 006A1220

* Possible StringData Ref from Data Obj ->"Please insert the Mortal Kombat "  <-- String that got us here in
                                        ->"III CD"                            <-- the first place
                                  |
:004555A0 682C126A00              push 006A122C
:004555A5 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:0186h
                                  |
:004555A7 FF1524B47700            Call dword ptr [0077B424]
:004555AD 8985F4FDFFFF            mov dword ptr [ebp+FFFFFDF4], eax
:004555B3 83BDF4FDFFFF02          cmp dword ptr [ebp+FFFFFDF4], 00000002  <-- 02 means you hit cancel
:004555BA 0F8507000000            jne 004555C7
:004555C0 33C0                    xor eax, eax                            <-- Zero in eax means failed CD check
:004555C2 E917000000              jmp 004555DE

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00455593(C), :004555BA(C)
|
:004555C7 83BDA0FCFFFF00          cmp dword ptr [ebp+FFFFFCA0], 00000000
:004555CE 0F8486FEFFFF            je 0045545A
:004555D4 B801000000              mov eax, 00000001                      <-- 01 in eax means CD check passed
:004555D9 E900000000              jmp 004555DE

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004555C2(U), :004555D9(U)
|
:004555DE 5F                      pop edi
:004555DF 5E                      pop esi
:004555E0 5B                      pop ebx
:004555E1 C9                      leave
:004555E2 C3                      ret                                    <-- Return to the caller

	That's plenty of information, in fact we now know everything we need to know to crack this one.
First, the call to the check is made from 455778 and we know a zero in eax means the CD check failed.
Now we need to look at the section of code that calls the above CD check.

  -- Program Code --

:00455771 33C0                    xor eax, eax
:00455773 E9B8080000              jmp 00456030

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0045574A(C), :00455757(C)
|
:00455778 E84DFBFFFF              call 004552CA          <-- Call the CD check routine
:0045577D 85C0                    test eax, eax          <-- Check the result in eax
:0045577F 0F8507000000            jne 0045578C           <-- Take this call to continue
:00455785 33C0                    xor eax, eax           <-- CD check failed so set up to quit
:00455787 E9A4080000              jmp 00456030           <--   to Win95 through this jump

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045577F(C)
|
:0045578C 8B4508                  mov eax, dword ptr [ebp+08]   <-- Jump here to continue with the game
:0045578F A3F0A64600              mov dword ptr [0046A6F0], eax
:00455794 C70508A7460000000000    mov dword ptr [0046A708], 00000000
:0045579E C705F4A6460000000000    mov dword ptr [0046A6F4], 00000000

  -- Continuing Program Code --

	Well there you go, all you have to do is make sure the CD check call is never made and force the
conditional jump at 45577F is always taken.  To do this just change the call 004552CA (E8 4D FB FF FF) to
mov eax, 00000001 (B8 01 00 00 00).  This way eax is loaded with 01, tested against itself which will force
the jne (Jump Not Equal) to always be true (taken).  This of course means you can play the game from the
hard drive without having the original MK3 CD in the CD-ROM drive.  To crack Mortal Kombat 3 do the following:

1.  Install MK3
2.  Copy all subdirectories from the CD EXCEPT "Directx" to the same
    subdirectory you installed MK3 to.  ~60 megs worth of files

3.  Edit mk3w.exe at offset 347,000
====================================
Search for: E8 4D FB FF FF
Change to : B8 01 00 00 00

	Running mk3w.exe results in a game that can be played completely from your hard drive and you'll
never have to put the MK3 CD in your CD-ROM drive.  That's how you get Mortal Kombat 3 FiX'ed

Static Vengeance