All that juicy Omnified assembly code is now available for viewing as I write it!

In the Shadows No Longer

Ever since I began this strange and wild journey of hacking games and making them Omnified on and off my stream, all my code and reverse engineering work was contained in a private, hidden-from-the-world workspace. Not too long ago I began the slow process of publishing my Bad Echo technology code to the new Bad Echo source code repository, yet the Omnified hacking framework and game-specific hacks remained unpublished.

Until now. After doing a complete re-tooling in regards to what I use to author the hacks, as well as creating a completely new design and approach to how the Omnified and hacking code is organized and structured, all Omnified-related hacks will be worked on in a repository that will be published to source control following each stream (or other event causing a significant update).

Find the latest Omnified hacking sources here.

Everything is set up for all the coding to take place within the Visual Studio Code editor; though, given that there’s no special build process or anything else that forms a hard requirement to that editor, it isn’t a requirement to use the code at all.

The Need for a Change in the Structuring of Hacks

Other than being one of our reverse engineering tools, Cheat Engine serves as our injection provider; it acts as the vehicle that gets our handcrafted assembly code injected into the target binary that is loaded in memory. Cheat Engine does, in my opinion, a fantastic job at this, yielding no complaints from me. The experiences offered in regards to working with a larger body of work, editing the code with the Cheat Engine editor, and simply dealing with its file format, however, are ones I’ve frequently found to be problematic.

The Cheat Engine editor is fine for tiny projects or bits of test code. It is not suitable for maintaining large, serious amounts of code, unless you don’t mind tearing your hair out (you’ll be doing plenty of that anyway). No code completion, shaky save states, and other fun things are in store for you if you try. This problem isn’t that hard to get around: I simply would load the Cheat Table file (.CT) in an external editor like Notepad++.

But that doesn’t help us get around the main problem preventing easy maintainability of an ever growing codebase: the nature of the file format used by Cheat Engine. It’s not my intention to criticize this aspect of the software; it’s most likely suitable for 99% of the kind of use the application gets. Not for how we use it, however!

A .CT file (which is the primary file type employed by Cheat Engine) is a strange mix of XML, assembly code, and sometimes LUA. The file format does not encourage the creation and use of common code and functionality; indeed each .CT file is incredibly specific to whatever software is being targeted (you really can’t get more specific than binary-specific memory offsets). A bunch of unrelated .CT files by themselves are really poor candidates for being useful denizens in a published source control setting, a setting which is supposed to be a very well thought out and crafted one (I try at least).

But the single biggest pain is one that coincides with our attempt to use an external, superior editor to edit the code within a .CT file:

Any changes made to the code within a .CT file are not seen by Cheat Engine until the application instance is completely closed and loaded up again.

That means unhooking the hooks you have in the targeted binary, closing Cheat Engine, and then reopening the whole thing up again. Quitting out of Cheat Engine has been necessary since I’ve found reloading the table within the same Cheat Engine instance to be highly problematic.

So you need to close it. Did you have a bunch of live reverse engineering data you wanted to keep up on your screen so you could continue with your testing and probing? Tough my friend! You’re already writing assembly by hand, you should relish the pain! Well, I had enough of that.

During one of the initial Omnification streams for The Witcher 3, I whipped out a solution I’m so happy about — so happy, I’m comfortable with publishing the hacks to source control!

A New Approach to the Design and Structure of Hacks

After a bit of thinking and some grunt work, I’ve managed to design a new approach to structuring an Omnified hacking workspace that I find much more palatable for source control and useful in general. Note that this article isn’t intended to be a deep technical dive into how it works, and also be aware that I am still fleshing out the new approach as we speak (so of course, the final product and vision isn’t yet up in that repository!).

This new way of organizing Omnified hacking code managed to achieve the following:

  • We now are able to use a single editor in crafting all code, namely VS Code.
  • All assembly language code has been separated entirely from .CT files and are now stored in .asm files.
  • All LUA language code has been separated entirely from .CT files (save for a simple function call to the Omnified framework that makes all this possible) and are now stored in .lua files.
  • All .CT files are identical to each other in each targeted game, save for the discovered and defined data structures specific to that game that are stored in the .CT file. These are used purely for reverse engineering efforts and not Omnified code injection.
  • A template .CT file now exists (or will, when I get to pushing some changes to source control…) that allows for us to easily begin hacking a new game. All you need to do is copy and paste it into a target game directory in the workspace, rename the .CT file (technically optional, but probably a good idea) and you’re good to go. Absolutely no changes need to be made to it prior to us starting the Omnification.
  • Code can now be edited and saved in an external editor, with the changes going into effect without having to reload Cheat Engine (big win!).
  • Part of the Omnified framework now includes code that makes it easy to import common assembly code into active target code similar to how #include-ing C header files work.
  • Omnified framework game-neutral code is now cleanly separated from all game-specific code, and is set up so that all game targets are referencing the same framework files in a common directory.

As one might be able to glean from all the furious typing I’m doing here: I’m quite excited about these changes! This will make life so much better while working on Omnifying a particular game. In regards to a technical overview going over how I’m able to do this stuff (none of this stuff is able to happen out of the box), I may write some articles on the topic in the future.

Omnified Hacks Source Directory Structure

At the outset, the directory structure for the Omnified hacking workspace is not a terribly complicated one. It looks like the following:

  • /framework/: This contains all game-neutral, Omnified framework code.
    • Omnified.lua: Omnified framework system code, responsible for providing all code importing and loading functionality, including the loading and injection of framework assembly code and game-targeted assembly code, as well as the removal of all injected hooks during cleanup. Other functionality is provided as well, such as status effect timers, etc.
    • Omnified.hooks.asm: Core Omnified framework assembly code. This is where all the code for the game-neutral Omnified systems can be found, such as the Apocalypse system, the Predator system, etc. — the star of the show.
    • Omnified.unhooks.asm: Code required in order to cleanly uninject all code injected from the Omnified.hooks.asm file. A separate file is required given that this data must be fed separately from the hooking code to Cheat Engine through a function call that facilitates the cleanup. It would be nice to have it all in one file, so I’ll give some consideration to a prudent way to creating some method for parsing separate hooking/unhook sections (still learning LUA, btw).
    • OmnifiedDisplay.lua: Omnified framework display code, responsible for exporting hacked data for display on screen during stream — viewable now in the form of my the primitive Statistics and Apocalypse Log windows, but will also play a vital role in serializing data to be processed by my Vision application that’s currently in development. This file still needs to be “commonalized” (made game-neutral)! Bear with me!
  • /targets/: This contains all Omnified targets. Each Omnified game will have its own subdirectory.
    • /witcher3/: This would be the directory for The Witcher 3 acting as the Omnified target, and serves as our example for this article.
      • Omnified_w3.ct: The .CT file for Omnified Witcher 3, and what we double click on (and then check the check box in) in order to make the loaded Witcher 3 process Omnified. This contains all boilerplate code that loads framework and target hack files.
      • hooks.asm: Game specific hooks for the target.
      • unhooks.asm: Game specific hook cleanup code for the target.

And that’s what it looks like! A solid starting point.

Where Are the Previous Omnified Games?

All games Omnified from here on out will appear in source control as my active hacking workspace is exactly what is being put into the repository. I have no plans on putting any of the games I previously Omnified up on source, as that would be a whole lot of work for very little return.

Never fear, I’ve published all the Omnified source code for Omnified games that I’ve been beaten since this website was created on the Tombstones section of my hackpad. Source code for all Omnified games that were beaten before this website was made can be found in the #tombstones channel on my Discord server.

So, the source is out there! It’s just very low priority me — the main value gained from Omnifying previous games came in the form of experience gained and lessons learned that helped make what we have today possible.

Alright. Hope you enjoyed that little bit of news — I enjoyed the typing! Very therapeutic. See you on the stream.