What are some techniques you might use to prevent hacking by things like CheatEngine/ArtMoney?
Cheat prevention?
A very simple technique is xor-ing the data in memory with a constant.
class A {
private int money;
public void setMoney(int value) {
this.money = value ^ 42;
}
public int getMoney() {
return this.money ^ 42;
}
}
But to be honest, I wouldn't bother. If someone wants to cheat, they will find a way.
These days I'm focussing on cheat detection rather than prevention (which is just detection and response in real-time), as hackers/crackers are too clever
e.g. recording a user-input replay, which can be played back later in time (on a different client) to see if the same final results are generated from the replay, as were reported by the original game.
If someone cheats by increasing their health value, then later when the replay is tested (which only contains real user inputs), this cheat wont be applied, and the results from the replay will differ from the original results, e.g. they will die in the replay when they didn't die in the original match. They can then be banned
^ That particular scheme doesn't help against input-based cheating, like aim-bots that inject fake mouse inputs, though... Just ones that mess with the game-state, which is what the hacking tools you mentioned are usually for.
It also doesn't help against cheaters who abuse hidden knowledge, like "wall hacks" or "map hacks", that let people know where their enemies are hiding. They're a lot harder to detect (and also harder to prevent ).
For some games, the best course of action would be to keep these facts of life in mind when designing the game, or designing the server architecture
Prevention is impossible in any situation where the attacker (cheater) controls the hardware and software they are trying to break. As long as those elements are under attacker control, they can and will find a way to circumvent any security attempts you make.
The perverse thing about it is that the more "tricky" your prevention gets, the more fun these guys have in breaking it, which means past a certain point you're actually hurting yourself by trying to engineer complicated protection schemes.
I don't personally cheat in games very often, but I can tell you from firsthand experience that 99% of the security attempts made in software are ridiculously easy to defeat, and the remainder are moderately easy if you have tools and some patience.
The first question that comes to mind is whether this is a single player or multiplayer game?
For single player games, cheat prevention really isn't worth it. Those who want to work around your preventions will do so, and ultimately, they are only ruining their own experience of the game.
For multiplayer games, presuming you have a centralized server architecture, robust cheat prevention is possible insofar as you are able to perform calculations on the server (or check the results of client calculations on the server).
I got into this conversation with a friend, and he suggested modifying the compiler to use fewer registers, preserving "important stuff" in those newly unallocated registers. It's a very heavy-handed way to go about it, will lead to serious repercussions in performance, and still isn't fool-proof, but it's damned hard to get around because it requires a lot of inside knowledge to know what gnarly asm to inject.
In the end, trying to fight cheaters without leveraging a server isn't a war you can win.
I got into this conversation with a friend, and he suggested modifying the compiler to use fewer registers, preserving "important stuff" in those newly unallocated registers. It's a very heavy-handed way to go about it, will lead to serious repercussions in performance, and still isn't fool-proof, but it's damned hard to get around because it requires a lot of inside knowledge to know what gnarly asm to inject.
Wat?
Using "fewer registers" doesn't make any sense. First of all, that means more stuff will be spilled to stack memory, where it's actually easier to find and modify. Secondly, it's going to be transiently limited to the runtime of a single function at most, so those values still have to go back to stack or free-store memory at some point. Finally, on platforms like x86-32, there's already so few registers available that this is just... not smart to try.
And for all that, it wouldn't stop a determined reverser for more than about 5 seconds, and then they'd laugh at how silly your "protection" is and trivially crack it anyways.
I am one of those who would ship a game with built-in cheats, unless the game is competitive and multiplayer simultaneously.
So, I absolutely hate the fact that Sanctum 2 has a built-in cheat detection feature, but neglected the most basic feature of all times: pausing the game. In other words, make your cheat detection, but do not leave basic stuff aside so you can do it.
If you want your game to be cheat-proof, you'll have nightmares.
Usually, you'll want a Client application of your game to manage only two things: Rendering and Input. This would pass everything else to a server, that does all the heavy stuff.
If you want to create simple memory scan shields, you can store the values on 2 or 3 different places, maybe compound storing, where you have to multiply two values to get your HP, for example, and the second changes randomly every X frames, adjusting the other one to keep the result. Like in the little snippet here.
typedef struct compound_value {
float *value;
int *multiplier;
} cvalue;
bool create_compount_value (cvalue* cv, float p_value) {
//Set Multiplier
try{
cv.multiplier = Allocate(INT_VAR);
}
catch (allocate_exc exc){
return false; //Or throw the exception
}
cv.multiplier[0] = random_number(1, 5000);
//Set value
try{
cv.value = Allocate(FLOAT_VAR);
}
catch (allocate_exc exc){
return false; //Or throw the exception
}
cv.value[0] = p_value/( (float) cv.multiplier[0]);
return true; //Success
}
void update_compound_value (cvalue* cv, float p_value) {
cv.value[0] = p_value/( (float) cv.multiplier[0]);
}
void randomize_compound_value (cvalue* cv) {
cv.value[0] = cv.value[0] * (float) cv.multiplier[0];
cv.multiplier[0] = random_number(1, 5000);
cv.value[0] = cv.value[0] / ( (float) cv.multiplier[0]);
}
float get_compound_value (cvalue* cv) {
return ( cv.value[0] * (float) cv.multiplier[0] );
}
As an example.
The Cheat Engine gurus would still be able to hack a game with this code. They would even consider it a challenge, having even more fun while doing so!
All cheat detection will have a cost on development time of your games, not a little, usually. On top of that, will always have a performance cost, one that gets bigger with better detection methods. Cheat prevention on local games (by that, I mean not client-server games), well, I'd say one can't do it easily, unless you are really good.
Also, note that this is just an idea, please use it only if you have an implemented memory pool and other performance allies.
There's probably dozens of better ways to do it.
Wat?
Using "fewer registers" doesn't make any sense. First of all, that means more stuff will be spilled to stack memory, where it's actually easier to find and modify. Secondly, it's going to be transiently limited to the runtime of a single function at most, so those values still have to go back to stack or free-store memory at some point. Finally, on platforms like x86-32, there's already so few registers available that this is just... not smart to try.
And for all that, it wouldn't stop a determined reverser for more than about 5 seconds, and then they'd laugh at how silly your "protection" is and trivially crack it anyways.
Yep. I'm no expert, and I don't mean to be. I just thought the notion was amusing at best. In the end, trying to protect a locally-controlled (to the user) game is foolhardy and not worth pursuing.