Free Information Xchange '98 presents:
Cyber Troopers: Virtual On - CD crack by Static Vengeance
Requirements:
hex editor and full install
Sega Entertainment has released another fighter game. This time you take control of huge
battle droids in a one on one fight for control over the moon. I'm still looking for the accel-
erated PowerVR version that works with the US release of this game. Anyways the game still runs
pretty fast and has some decent effects. However there is the CD check bug that needs to be FiX'ed.
So I got W32Dasm up and running and disassembled v_on.exe and set out to remove the CD check.
I started out by going up to the menu bar and selecting "Refs" and then "String data references"
from the drop down menu. One the string data refs box showed up I grabbed the slider bar and scrolled
down looking for interesting things like "Insert.. ", "Please insert..", or references to the CD volume
or even "%C:\" which is commonly used in CD checks. Well I found all three types of references in
Virtual On. From there I doubled clicked on them and followed the code to see what was going on.
Here is the code along with a brief description of what the code is doing:
* Referenced by a CALL at Address:
|:005C5CF5 <-- Where the call was made from.
|
:005C82BA 55 push ebp
:005C82BB 8BEC mov ebp, esp
:005C82BD 83EC04 sub esp, 00000004
:005C82C0 53 push ebx
:005C82C1 56 push esi
:005C82C2 57 push edi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C830D(U)
|
:005C82C3 E826FFFFFF call 005C81EE <-- Check for the CD
:005C82C8 A3605FAE01 mov dword ptr [01AE5F60], eax
:005C82CD 833D605FAE01FF cmp dword ptr [01AE5F60], FFFFFFFF <-- Check for the result
:005C82D4 0F840A000000 je 005C82E4 <-- This jump asks for the CD
:005C82DA B801000000 mov eax, 00000001 <-- Setup for passed CD check
:005C82DF E92E000000 jmp 005C8312 <-- Jump to the end of this routine
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C82D4(C)
|
:005C82E4 6A35 push 00000035
* Possible StringData Ref from Data Obj ->"Virtual ON for PC"
|
:005C82E6 A148F56B00 mov eax, dword ptr [006BF548]
:005C82EB 50 push eax
* Possible StringData Ref from Data Obj ->"Please insert VIRTUAL ON CD." <-- Ask for the CD
|
:005C82EC 6890876C00 push 006C8790
:005C82F1 6A00 push 00000000
* Reference To: USER32.MessageBoxA, Ord:0197h
|
:005C82F3 FF15E8D56503 Call dword ptr [0365D5E8]
:005C82F9 8945FC mov dword ptr [ebp-04], eax
:005C82FC 837DFC02 cmp dword ptr [ebp-04], 00000002 <-- 02 means you hit cancel
:005C8300 0F8507000000 jne 005C830D
:005C8306 33C0 xor eax, eax <-- Setup for a failed CD check
:005C8308 E905000000 jmp 005C8312 <-- Go to the return section
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C8300(C)
|
:005C830D E9B1FFFFFF jmp 005C82C3 <-- Go back up and retry
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005C82DF(U), :005C8308(U)
|
:005C8312 5F pop edi <-- This is the section that returns to the caller
:005C8313 5E pop esi <-- eax will already have the result in it when you
:005C8314 5B pop ebx <-- get here. eax=00 for a failed CD check
:005C8315 C9 leave <-- while eax=01 for a passed CD check
:005C8316 C3 ret
That's the section that asks for the CD when not found. So lets check the call to 5C82C3
which is the routine that actually checks for the CD in your CD-ROM drive:
* Referenced by a CALL at Address:
|:005C82C3
|
:005C81EE 55 push ebp
:005C81EF 8BEC mov ebp, esp
:005C81F1 83EC5C sub esp, 0000005C
:005C81F4 53 push ebx
:005C81F5 56 push esi
:005C81F6 57 push edi
* Reference To: KERNEL32.GetLogicalDrives, Ord:00E7h <-- Common text string in CD checks
|
:005C81F7 FF1518D46503 Call dword ptr [0365D418]
:005C81FD 8945F4 mov dword ptr [ebp-0C], eax
:005C8200 C745F800000000 mov [ebp-08], 00000000
:005C8207 E903000000 jmp 005C820F
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005C822C(U), :005C8294(U)
|
:005C820C FF45F8 inc [ebp-08]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C8207(U)
|
:005C820F 837DF820 cmp dword ptr [ebp-08], 00000020
:005C8213 0F8D80000000 jnl 005C8299
:005C8219 B801000000 mov eax, 00000001
:005C821E 8A4DF8 mov cl, byte ptr [ebp-08]
:005C8221 D3E0 shl eax, cl
:005C8223 8545F4 test dword ptr [ebp-0C], eax
:005C8226 0F8505000000 jne 005C8231
:005C822C E9DBFFFFFF jmp 005C820C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C8226(C)
|
:005C8231 8B45F8 mov eax, dword ptr [ebp-08]
:005C8234 83C041 add eax, 00000041
:005C8237 50 push eax
* Possible StringData Ref from Data Obj ->"%c:\" <-- Common refs string to check out
|
:005C8238 6888876C00 push 006C8788
:005C823D 8D45A4 lea eax, dword ptr [ebp-5C]
:005C8240 50 push eax
* Reference To: USER32.wsprintfA, Ord:026Ch
|
:005C8241 FF1540D56503 Call dword ptr [0365D540]
:005C8247 83C40C add esp, 0000000C
:005C824A 8D45A4 lea eax, dword ptr [ebp-5C]
:005C824D 50 push eax
* Reference To: KERNEL32.GetDriveTypeA, Ord:00CEh <-- Commonly used call in CD check routines
|
:005C824E FF151CD46503 Call dword ptr [0365D41C]
:005C8254 83F805 cmp eax, 00000005 <-- 05 is the CD-ROM drive value
:005C8257 0F8537000000 jne 005C8294
* Possible StringData Ref from Data Obj ->"V_ON\V_ON.EXE" <-- Checkin for the EXE with full path of CD
|
:005C825D 6878876C00 push 006C8778
:005C8262 8D45A4 lea eax, dword ptr [ebp-5C]
:005C8265 50 push eax
* Reference To: KERNEL32.lstrcatA, Ord:0266h
|
:005C8266 FF15D4D46503 Call dword ptr [0365D4D4]
:005C826C 6A00 push 00000000
:005C826E 8D45A4 lea eax, dword ptr [ebp-5C]
:005C8271 50 push eax
* Reference To: KERNEL32._lopen, Ord:0262h
|
:005C8272 FF1520D46503 Call dword ptr [0365D420]
:005C8278 8945FC mov dword ptr [ebp-04], eax
:005C827B 837DFCFF cmp dword ptr [ebp-04], FFFFFFFF
:005C827F 0F840F000000 je 005C8294
:005C8285 8B45FC mov eax, dword ptr [ebp-04]
:005C8288 50 push eax
* Reference To: KERNEL32._lclose, Ord:025Fh
|
:005C8289 FF1524D46503 Call dword ptr [0365D424]
:005C828F E905000000 jmp 005C8299
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005C8257(C), :005C827F(C)
|
:005C8294 E973FFFFFF jmp 005C820C
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005C8213(C), :005C828F(U)
|
:005C8299 837DF820 cmp dword ptr [ebp-08], 00000020
:005C829D 0F850A000000 jne 005C82AD
:005C82A3 B8FFFFFFFF mov eax, FFFFFFFF <-- Need to return with FFFFFFFF
:005C82A8 E908000000 jmp 005C82B5 <-- for a passed CD check
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C829D(C)
|
:005C82AD 8B45F8 mov eax, dword ptr [ebp-08] <-- Any other value is a failed check
:005C82B0 E900000000 jmp 005C82B5
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005C82A8(U), :005C82B0(U)
|
:005C82B5 5F pop edi
:005C82B6 5E pop esi
:005C82B7 5B pop ebx
:005C82B8 C9 leave
:005C82B9 C3 ret
Yet another example of what a CD check might look like. So we know call to the CD check was
made from 5C82C3 which is part of the "insert CD" routine. The insert Cd routine runs from 5C82BA to
5C8316 and is called from 5C5CF5. So now we need to check out the surounding code in that area:
:005C5CE1 837DD43D cmp dword ptr [ebp-2C], 0000003D
:005C5CE5 0F850A000000 jne 005C5CF5
:005C5CEB C705E0846C0001000000 mov dword ptr [006C84E0], 00000001
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C5CE5(C)
|
:005C5CF5 E8C0250000 call 005C82BA <-- Do the CD check
:005C5CFA 85C0 test eax, eax <-- Test the result
:005C5CFC 0F8507000000 jne 005C5D09 <-- Take this jump to continue with the game
:005C5D02 33C0 xor eax, eax <-- Set up for a quit to Win95
:005C5D04 E901060000 jmp 005C630A <-- then go do it
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C5CFC(C)
|
:005C5D09 E85FA8F7FF call 0054056D <-- Continue with the game
:005C5D0E 837D0C00 cmp dword ptr [ebp+0C], 00000000
:005C5D12 0F851B000000 jne 005C5D33
:005C5D18 8B4508 mov eax, dword ptr [ebp+08]
:005C5D1B 50 push eax
:005C5D1C E8E8FBFFFF call 005C5909
There, we now have all the information we require to crack this game. Just overwrite the call to
the CD check with mov eax, 00000001 and this will force the jne 005C5D09 at 5C5CFC to always be taken.
This in turns forces the game to always run if the CD is present or not.
There is PowerVR version from NEC Japan for Virtual On, however it doesn't work with the US release
of this game due to the added files required for the PowerVR version. In fact the CD check fails even with
an original Virtual On CD online! The PowerVR version's exe file is vonpvr.exe and it's the file that needs
to be editted. If you happen to own a PowerVR card and the special PowerVR version of Virtual On I have
added the required edits for it also. The edit you need to make is:
For the DirectX CD version edit v_on.exe
===============================================
Search for: E8 C0 25 00 00 at offset 1,855,733
Change to : B8 01 00 00 00
For the PowerVR CD version edit vonpvr.exe
=============================================
Search for: E8 6F 26 00 00 at offset 964,135
Change to : B8 01 00 00 00
For the PowerVR net update edit vonpvr.exe
=============================================
Search for: E8 6F 26 00 00 at offset 964,359
Change to : B8 01 00 00 00
Once again with a simple edit another Sega game, Virtual On, has been FiX'ed
Static Vengeance
NOTE: A simple search string to find the CD check would be: "E8 xx xx 00 00 0F 85 07 00 00 00 33 C0 E9"
Once found, change the E8 xx xx 00 00 to B8 01 00 00 00 and you have cracked Virtual On.