0
\$\begingroup\$

im trying to create lightweight value obscurer, against possibility to blatantly change primitive values in memory editor. Such as cheat engine. Here's what i have to far.

/// <summary>
/// Obscure for type int.
/// </summary>
public class ObscuredInt{

    public ObscuredInt() {
        this.value = 0;
    }

    public ObscuredInt(int value) {
        this.value = value;
    }

    private int _a;
    private int _b;

    /// <summary>
    /// Current obscure value.
    /// </summary>
    public int value {
        get {
            return _a + _b;
        }
        set {
            _a = Random.Range(int.MinValue, int.MaxValue);
            _b = value - _a;
        }
    }
}

usage

ObscuredInt health = new ObscuredInt(5);
health.value = 10;

printInConsle(health.value);

This works by simply never storing actual value, but rather a combination of two integers, which sum represents the value. That way the value is actually never cached long time in the memory. So finding it in a primitive way using cheat engine is not possible.

My question

I've seen other examples of obscuring, which involve conversion to binary or string hashing or other quite heavy operations.

This example is of course much more lightweight, how is this example worse than more advanced hashing or conversions. What flaws do you see with this example? What can you suggest?

Thank you

\$\endgroup\$
  • 4
    \$\begingroup\$ Security through obscurity is not security at all. \$\endgroup\$ – Almo Jul 4 '16 at 12:45
  • 2
    \$\begingroup\$ Possible duplicate of Strategies to Defeat Memory Editors for Cheating - Desktop Games \$\endgroup\$ – Philipp Jul 4 '16 at 14:22
  • 2
    \$\begingroup\$ Why would you do that anyway? In a multiplayer game, any data worth manipulating should be server-sided. In a singleplayer game, the player is only cheating themselves. Why prevent them from playing your game the way they want? When they think it's more fun to play with infinite health, why not let them? \$\endgroup\$ – Philipp Jul 4 '16 at 14:23
  • 2
    \$\begingroup\$ @YoungDeveloper I'm just trying to help you avoid programming in something that is going to kill performance and cause difficult to find issues with cache and optimization. \$\endgroup\$ – user5665 Jul 4 '16 at 14:28
  • 1
    \$\begingroup\$ please see this link alanzucconi.com/2015/09/02/… \$\endgroup\$ – Seyed Morteza Kamali Jul 4 '16 at 15:23
3
\$\begingroup\$

The major flaw is that you are adding random values between int.MinValue and int.MaxValue leaving no more space for your real value. Okay, the default in C# is to not perform range checks, but this can be changed.

In order to keep the whole int value range open for your real values I would suggest to use an XOR operation instead.

public int value {
    get {
        return _a ^ _b;
    }
    set {
        _a = Random.Range(int.MinValue, int.MaxValue);
        _b = value ^ _a;
    }
}

Applying the same "mask" a second time with XOR restores the original value. The result of XOR is always in the int-range and never overflows. XOR is very fast and does not involve range checks.


Alternatively you could wrap your code in unchecked statements.

public int value {
    get {
        unchecked {
            return _a + _b;
        }
    }
    set {
        _a = Random.Range(int.MinValue, int.MaxValue);
        unchecked {
            _b = value - _a;
        }
    }
}

See: Checked and Unchecked (C# Reference).


Speed: The most expensive operation is the creation of the random number. If speed matters, consider making the random number static and create only one per session.


Safety: I think most cheat engines won't be smart enough to get around your trick. But of course, for human hackers that's another story.

\$\endgroup\$
  • \$\begingroup\$ Thank you for your response, i am not exactly sure what unchecked does in this matter but i will look into that. \$\endgroup\$ – YoungDeveloper Jul 4 '16 at 14:04
  • 1
    \$\begingroup\$ I added a link to the Checked and Unchecked (C# Reference) \$\endgroup\$ – Olivier Jacot-Descombes Jul 4 '16 at 14:17
  • \$\begingroup\$ Thanks, i will wait for possible other answers, if no more will pop up (and better :) ) i will accept yours as an answer. Thanks again, have a good day! \$\endgroup\$ – YoungDeveloper Jul 4 '16 at 14:18

Not the answer you're looking for? Browse other questions tagged or ask your own question.