Vampire The Masquerade: Bloodlines

The solution

The solution is easy if we allow ourselves to do something very bad that software engineers should never do: make an assumption. If we assume that we will never run on a system with only 15Mb of free memory - which isn't that horrific of an assumption if you were expecting to be able to play a Source engine game on that system - then we can simply change the code to ignore the check on GlobalMemoryStatus()'s data and skip over the error message unconditionally.

The test is performed here:

:200FA494 7D12                    jge 200FA4A8

All we have to do is change the jge (jump if greater-than or equal) to jmp (jump unconditionally). The disassembler is kind enough to tell us that this code is at offset FA494 in the DLL so we can open it up in a hex editor and jump to that address. Lo and behold there is the code 7D 12. I happen to know the hex equivalent of jmp is EB, so we can change the code to EB 12 and save the file. Voilà the DLL is patched.

How to patch your file

If you don't want to hack around yourself, use the patch I provide to fix engine.dll for you. If you want to get stuck in, read on.

XVI32 is a good, free hex editor for Windows. WinHex is a very good, not free hex editor for Windows. Either program will allow you to open the DLL and jump to offset FA494 where you should see 7D 12 under the cursor. The correct offset is indeed FA494 and not 200FA494 as displayed by the disassembler.

Please note that this analysis was done with the version of engine.dll that ships with the official patch to the game. If your file is not 1986620 bytes in size it is not the right version!

Detailed instructions for XVI32

Search Google for XVI32 to get the latest version. Take a copy of your engine.dll file the follow these steps.

  1. Open engine.dll inside XVI32.

  2. Press Control-G to "go to" a specified offset. The Go to address window pops up.

  3. Ensure that Go to is set to hexadecimal and that Go mode is set to Absolute. Enter FA494 in the box and hit OK.

  4. The cursor should now be over 7D in the lefthand (hex) view with 12 immediately to the right. Type EB.

  5. Save the file.

Notes for users of the unpatched (v1.0) game

The v1.0 DLL has the phrase that pays at FA384. Everything else is the same.

Exercise for the reader

Change the code to call and interpret the results of GlobalMemoryStatusEx() instead.


Jump to a section

intro | part 1: Isolating the problem | part 2: Disassembly | part 3: GlobalMemoryStatus() | part 4: The solution | part 5: Patches | part 6: Low res textures