Defeating Memory Editors with Moving Values

Many years ago, I inquired on the GameDev StackExchange site about how to stop players from using memory editors to cheat. While slightly controversial, I still maintain that this is a fun academic exercise.

Recently, I revisited this concept. After lots of experimentation with a simple game (press a key to fight, player and monster both decrease in health by a random amount), I arrived at a working solution based on my initial concept.

Memory editors work because programs store (integer) values in the same location in memory, for as long as the game runs. C# applications also exhibit this behaviour. Memory editors exploit this, by allowing the user to scan for a specific value, or a changed (eg. decreased value).

Some anti-cheat mechanisms work around this by masking the value (eg. storing it as twos-complement or inverted, or added/subtracted to a random value), or by never displaying the original value.

My solution involved actually moving the object to a new location. In .NET, this means re-creating the original object’s value, in a new object.

What if you read this value in your game loop, at 60FPS, and each read results in a write? That may lead to poor performance. Instead, the value only changes on each write operation.

Some code:

class MovingValue<T> {
  private Box<T> box;

  public MovingValue(T value)
  {
      this.box = new Box<T>(value);
  }

  public T CurrentValue
  {
      get { return this.box.Value; }
      set { this.box = new Box<T>(value); }
  }

  class Box<T>
  {
      public T Value { get; set; }

      public Box(T value) { this.Value = value; }
  }
}

I chose the names MovingValue to indicate that the value stored moves, and Box because it uses a concept similar to boxing/unboxing.

The value stored changes on each write operation, and you can always get the current value. To use it, you change this:

class Player {
  private int health = 30;

  public int Health { 
    get { return this.health; }
    set { this.health = value;
  }

  public void GetHurt(int damage) {
    health -= damage;
  }
}

To this:

class Player {
  private MovingValue<int> health = new MovingValue<int>(30);

  public int Health { 
    get { return this.health.Value; }
    set { this.health.Value = value;
  }

  public void GetHurt(int damage) {
    health -= damage;
  }
}

I tested this with the ArtMoney memory editor. The original health int address is easy to locate/freeze, while the MovingValue address can’t be pinned down, even with multiple rounds of scanning.

This design also doesn’t suffer from any type of concurrency issues or race-conditions (which it would if you moved the value with, say, a timer).

As a final caveat, I would be weary of:

  • Updating this value frequently (like every render/update tick), because it allocates a new object every single write.
  • Updating this value with a very large object, that has multiple fields/sub-fields (perhaps with collections). If you update frequently, this can compound problems.

About Ashiq Alibhai, PMP

Ashiq has been coding C# since 2005. A desktop, web, and RIA application developer, he's touched ASP.NET MVC, ActiveRecord, Silverlight, NUnit, and all kinds of exciting .NET technologies. He started C# City in order to accelerate his .NET learning.
This entry was posted in Core .NET and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *