Free Information Xchange '98 presents:
Balls of Steel - CD crack by Static Vengeance
Requirements:
hex editor and full install
Balls of Steel is decent pinball game, having five tables and a slightly adult flavor to it.
There is of course one bug that needs to be FiX'ed and that's why I'm writing this tutorial. I am
speaking of the CD check that comes up during the game. Like most games, I do a full install and
when I want to play them I want to play them now. I get sick of having to dig through all of my CD's
just to play one quick game while the latest file is being downloaded off the net. So I set out to
take care of this bug. I got W32Dasm (RUSoft) up and running and disassembled the main excutable file
by the name of bos.exe. Once W32Dasm had done it's work I simply went up to the menu bar selected
"Refs" and then selected "String data references" from the drop down menu. From there I grabbed the
slidder bar on the Refs box and scrolled down a bit to see what I could find. The first thing that
cought my eye was "CD required". Double clicking this put me right in the middle of the CD check
routine. From there I skimmed through the code to see what it was doing and in a minute or two I had
the solution to the bug I mentioned. Here is what I found:
* Referenced by a CALL at Address:
|:0043738F <-- Where the CD check was called from
|
:00437124 55 push ebp
:00437125 8BEC mov ebp, esp
:00437127 81C4A8FEFFFF add esp, FFFFFEA8
:0043712D 53 push ebx
:0043712E 56 push esi
:0043712F 57 push edi
:00437130 33C0 xor eax, eax
:00437132 8985A8FEFFFF mov dword ptr [ebp+FFFFFEA8], eax
:00437138 8945FC mov dword ptr [ebp-04], eax
:0043713B 8945F8 mov dword ptr [ebp-08], eax
:0043713E 33C0 xor eax, eax
:00437140 55 push ebp
:00437141 684F724300 push 0043724F
:00437146 64FF30 push dword ptr fs:[eax]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004370DF(C)
|
:00437149 648920 mov dword ptr fs:[eax], esp
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00437219(C)
|
:0043714C BB01000000 mov ebx, 00000001 <-- Initialize number of tries
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004371FA(C)
|
:00437151 8D85A8FEFFFF lea eax, dword ptr [ebp+FFFFFEA8]
:00437157 8D5341 lea edx, dword ptr [ebx+41]
:0043715A 4A dec edx
:0043715B E80CC3FCFF call 0040346C
:00437160 8B95A8FEFFFF mov edx, dword ptr [ebp+FFFFFEA8]
:00437166 8D45FC lea eax, dword ptr [ebp-04]
:00437169 B968724300 mov ecx, 00437268
:0043716E E8A9C3FCFF call 0040351C
:00437173 8B45FC mov eax, dword ptr [ebp-04]
:00437176 E819C5FCFF call 00403694
:0043717B 50 push eax
* Reference To: kernel32.GetDriveTypeA, Ord:0000h <-- Text string that can be searched
| <-- for "GetDriveType"
:0043717C E867D8FCFF Call 004049E8
:00437181 83F805 cmp eax, 00000005 <-- 05 is the value for a CD drive
:00437184 7570 jne 004371F6 <-- Take this jump for no CD Drive
:00437186 8D45F8 lea eax, dword ptr [ebp-08]
* Possible StringData Ref from Code Obj ->"BOS.IDF" <-- File to look for
|
:00437189 B974724300 mov ecx, 00437274
:0043718E 8B55FC mov edx, dword ptr [ebp-04]
:00437191 E886C3FCFF call 0040351C
:00437196 8B45F8 mov eax, dword ptr [ebp-08]
:00437199 E846EBFCFF call 00405CE4 <-- kernel32.FindFirstFileA & other calls
:0043719E 84C0 test al, al
:004371A0 7454 je 004371F6
:004371A2 8B55F8 mov edx, dword ptr [ebp-08]
:004371A5 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
:004371AB E8C5CEFCFF call 00404075
:004371B0 C6053790430000 mov byte ptr [00439037], 00
:004371B7 BA01000000 mov edx, 00000001
:004371BC 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
:004371C2 E835D2FCFF call 004043FC
:004371C7 E810B5FCFF call 004026DC
:004371CC 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
:004371D2 E87DCFFCFF call 00404154 <-- kernel32.GetFileSize call
:004371D7 E800B5FCFF call 004026DC
:004371DC 8BF0 mov esi, eax
:004371DE 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
:004371E4 E82FCFFCFF call 00404118
:004371E9 E8EEB4FCFF call 004026DC
:004371EE 81FE0400D717 cmp esi, 17D70004
:004371F4 7433 je 00437229
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00437184(C), :004371A0(C)
|
:004371F6 43 inc ebx <-- Increase the number of times we tried
:004371F7 83FB1B cmp ebx, 0000001B <-- Try up to 27 times to read file
:004371FA 0F8551FFFFFF jne 00437151 <-- Loop back up and try again!
:00437200 6A31 push 00000031
* Possible StringData Ref from Code Obj ->"CD required" <-- String that lead me here
|
:00437202 B97C724300 mov ecx, 0043727C
* Possible StringData Ref from Code Obj ->"Please insert the Balls of Steel " <-- Another string that points
->"CD and click OK to continue." <-- to the CD check routine
|
:00437207 BA88724300 mov edx, 00437288
:0043720C A124964300 mov eax, dword ptr [00439624]
:00437211 E8AAC7FEFF call 004239C0
:00437216 83F802 cmp eax, 00000002 <-- You hit cancel from dialog box
:00437219 0F852DFFFFFF jne 0043714C <-- Start over at init number of tries
:0043721F A124964300 mov eax, dword ptr [00439624]
:00437224 E803C7FEFF call 0042392C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004371F4(C)
|
:00437229 33C0 xor eax, eax
:0043722B 5A pop edx
:0043722C 59 pop ecx
:0043722D 59 pop ecx
:0043722E 648910 mov dword ptr fs:[eax], edx
* Possible StringData Ref from Code Obj ->"_^["
|
:00437231 6856724300 push 00437256
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00437254(U)
|
:00437236 8D85A8FEFFFF lea eax, dword ptr [ebp+FFFFFEA8]
:0043723C E81BC1FCFF call 0040335C
:00437241 8D45F8 lea eax, dword ptr [ebp-08]
:00437244 BA02000000 mov edx, 00000002
:00437249 E82EC1FCFF call 0040337C
:0043724E C3 ret <-- Finally return to the caller
This is a self contained CD check routine in so far as it doesn't return any special value in eax or
store a pass/fail value somewhere in memory. That only leaves us to disable the CD check from the calling
routine. So let's check back around 43738F and see how the above CD check code is called:
:0043737A 8B06 mov eax, dword ptr [esi]
:0043737C 80B8BC01000000 cmp byte ptr [eax+000001BC], 00
:00437383 74EE je 00437373
:00437385 E802FCFFFF call 00436F8C
:0043738A E88DFCFFFF call 0043701C
:0043738F E890FDFFFF call 00437124 <-- Single call to the CD check
:00437394 E88BFBFFFF call 00436F24
:00437399 B9F0B84300 mov ecx, 0043B8F0
:0043739E BAA8E44200 mov edx, 0042E4A8
:004373A3 8B03 mov eax, dword ptr [ebx]
:004373A5 E882C4FEFF call 0042382C
Simple enough, just disable the call at 43738F with five NOP's and you have a cracked pinball game
to play! Version 1.0 is from the CD and is the version I used for the above disassembly. Version 1.1 is
from a patch that I downloaded off the net. BTW: Before upgrading your version 1.0 to version 1.1 make sure
you have NOT made any edits to bos.exe. The upgrade (patcher) program will check that you have an unmodified
version before it will install the upgrade. You may have to uninstall and then reinstall the game before the
upgrade will successfully install. Also: Make the edits listed below ONLY at the location stated, as I found
the byte string in two places, only edit listed will function correctly. Make the edits to bos.exe by version
number:
Edit bos.exe v1.0 at offset 223,119
===================================
Search for: E8 90 FD FF FF
Change to : 90 90 90 90 90
Edit bos.exe v1.1 at offset 232,917
===================================
Search for: E8 CA FD FF FF
Change to : 90 90 90 90 90
Balls of Steel has just been added to the list of FiX'ed games!
Static Vengeance