Jump to content

  • Log In with Google      Sign In   
  • Create Account

Cheat prevention?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
37 replies to this topic

#1 3TATUK2   Members   -  Reputation: 730

Like
0Likes
Like

Posted 20 September 2013 - 06:45 AM

What are some techniques you might use to prevent hacking by things like CheatEngine/ArtMoney?



Sponsor:

#2 lwm   Members   -  Reputation: 1474

Like
5Likes
Like

Posted 20 September 2013 - 06:59 AM

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.


current project: Roa


#3 L. Spiro   Crossbones+   -  Reputation: 14271

Like
5Likes
Like

Posted 20 September 2013 - 07:36 AM

I’m hurt that you did not mention MHS, since it is far more popular than ArtMoney.  Second after Cheat Engine.
 
Unfortunately, I can’t help you until you explain a bit the behavior of the data you wish to protect.
 
How does it increase and decrease?  What is the range of it?
 
There are literally a million ways to make hacking harder (but never impossible).  Why not start by describing everything you can about the variable you wish to protect?
Especially how it is used in the game, because observing that is how all hackers decide on the route to attack a certain variable.  And MHS allows them so much much more after that.
In fact it would not hurt you to follow other tutorials to gain an understanding of how people view the behaviors of values in games and translate that into values to find.
 
Also, I am not related to any tutorials you will find, including the links I provided.
 
 
L. Spiro

Edited by L. Spiro, 20 September 2013 - 06:43 PM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#4 Hodgman   Moderators   -  Reputation: 31851

Like
9Likes
Like

Posted 20 September 2013 - 07:57 AM

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 unsure.png

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 tongue.png

 

^ 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 tongue.png).

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 wink.png


Edited by Hodgman, 20 September 2013 - 10:43 AM.


#5 ApochPiQ   Moderators   -  Reputation: 16401

Like
6Likes
Like

Posted 20 September 2013 - 10:30 AM

Detection is far more important than attempting prevention.

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.

#6 swiftcoder   Senior Moderators   -  Reputation: 10369

Like
5Likes
Like

Posted 20 September 2013 - 10:48 AM

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).


Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#7 SeraphLance   Members   -  Reputation: 1454

Like
0Likes
Like

Posted 20 September 2013 - 02:43 PM

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.



#8 ApochPiQ   Moderators   -  Reputation: 16401

Like
5Likes
Like

Posted 20 September 2013 - 03:50 PM

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.

#9 dejaime   Crossbones+   -  Reputation: 4119

Like
0Likes
Like

Posted 20 September 2013 - 04:05 PM

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.


Edited by dejaime, 20 September 2013 - 04:18 PM.


#10 SeraphLance   Members   -  Reputation: 1454

Like
0Likes
Like

Posted 20 September 2013 - 04:58 PM

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.



#11 L. Spiro   Crossbones+   -  Reputation: 14271

Like
4Likes
Like

Posted 20 September 2013 - 06:50 PM

As should be clear by now, there are a million things to hack in a million different ways.

By just guessing what his situation is we can give advice all day long and never provide what he needs.

 

3TATUK2, you should be reading all replies and thinking about what information you wish to share.  Is it offline or online?  What kind of data do you wish to protect?  Do you wish to prevent certain kinds of behavior?

 

Another over-generalized piece of advice I can give you: Never use globals/statics/singletons/etc.  Not only is it a sign that your code is bad, it is a hacker’s dream-come-true.  Anything that never changes addresses in the final .EXE (or changes predictably, such as global data inside DLL’s) makes a hacker’s job 10 times easier.

 

 

L. Spiro


It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#12 3TATUK2   Members   -  Reputation: 730

Like
0Likes
Like

Posted 20 September 2013 - 07:34 PM

One thing i'm specifically interested in is... say the address of the variable *does* change - but changes predictably... for example, only between one of two addresses... Is something like CheatEngine able to exploit this? I've tested with a friend of mine and he couldn't quite figure it out... If he locked both addresses, for example, then the game would crash



#13 L. Spiro   Crossbones+   -  Reputation: 14271

Like
4Likes
Like

Posted 20 September 2013 - 07:42 PM

It’s very easy to exploit.

 

The game itself has to know which value is the correct one.  That means it has a pointer to it or an index or some flag that indicates which one it is.

 

In MHS it is trivial to use the Expression Lock to use the same method the game uses to figure which is the correct address to lock.

 

 

L. Spiro


It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#14 cronocr   Members   -  Reputation: 755

Like
2Likes
Like

Posted 20 September 2013 - 08:15 PM

Interesting topic, how does this work with games developed in Mono/.NET? Are these as simple to cheat?


 

 


#15 L. Spiro   Crossbones+   -  Reputation: 14271

Like
5Likes
Like

Posted 20 September 2013 - 08:29 PM

I haven’t tried those, but interpreted languages such as Java are extremely difficult to hack.  The health value (or any value) moves around in RAM and the only way to keep track of it is to follow a crap-load of pointers through the Java run-time, and offsets will be different for every version of Java, meaning you can’t distribute anything you make.

 

Ultimately, cheat protection boils down to reducing how much spread a given cheat has, not the actual prevention of the cheat itself, because that is impossible.  Cheats will invariably be made for any major game, but if they only work for a handful of people then it isn’t a major deal.

 

 

For any interpreted language, you can often find a value only once, change it, and then you have to find it again.  Making a stand-alone cheat is usually not practical.

 

 

L. Spiro


It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#16 dejaime   Crossbones+   -  Reputation: 4119

Like
4Likes
Like

Posted 20 September 2013 - 08:30 PM

One thing i'm specifically interested in is... say the address of the variable *does* change - but changes predictably... for example, only between one of two addresses... Is something like CheatEngine able to exploit this? I've tested with a friend of mine and he couldn't quite figure it out... If he locked both addresses, for example, then the game would crash

Cheat Engine and several other memory scanners allows you to track down where a variable is being stored. So, once you find this, what'll probably be a function, you'll have the variable under control. By this, I mean you can even keep track of variables that change address even if they always change to a newly allocated block.

 

Download Cheat Engine, try to go over their beginners Tutorial (under the Help menu). You'll understand a lot better how these work when you've successfully finished it.

 

Interesting topic, how does this work with games developed in Mono/.NET? Are these as simple to cheat?

I do not know Mono, but if it is an interpreted technology it is harder to hack with memory scanners. Still, some may be susceptible to direct file editing, making it easier to create hacked/cracked versions of the application.


Edited by dejaime, 30 September 2013 - 07:13 AM.


#17 Khatharr   Crossbones+   -  Reputation: 3040

Like
0Likes
Like

Posted 20 September 2013 - 08:59 PM

 

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.

 

 

If I saw that happening (and it would be a little hard to notice, though it wouldn't slow down a disassembler for one second) I'd rejoice because it would mean that it would be easier for me to write assembly hacks. Registers reserved for hacking! Yay!


void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

#18 lwm   Members   -  Reputation: 1474

Like
6Likes
Like

Posted 21 September 2013 - 02:05 AM


I do not know Mono, but if it is an interpreted technology it is harder to hack with memory scanners.

 

Just to clarify: While the JVM may interpret the byte code for some time before translating it to machine code, the CLR (and I believe Mono as well) will never interpret anything.

Like L. Spiro said, what makes memory scanning in managed languages somewhat harder (or rather, more tedious) is the ability of the VM to move around objects in memory at will. This will most commonly happen when the garbage collector compacts the heap after a successful collection.


current project: Roa


#19 wintertime   Members   -  Reputation: 1878

Like
3Likes
Like

Posted 21 September 2013 - 04:38 AM

I guess you could make it more funny for the cheater in a compiled language too, if you move the value around to some other place in ram every time you write to it and when you dont change it move it sometimes too. Possibly mangle the pointer to the value before saving it also.

I read once about someone combining the value with a unrelated function pointer (that gets recovered and used every few frames) in 2 different ways and then writing the results at 2 places in memory that need to be combined to recover it. Then if only one value changed it crashes. I'm not sure if that would really be effective for long.



#20 L. Spiro   Crossbones+   -  Reputation: 14271

Like
2Likes
Like

Posted 21 September 2013 - 05:36 AM

The thing that makes interpreted languages hard to hack is their complexity, not just the fact that they move things around.

 

Any compiled language can emulate that level of complexity, but if it were that simple tons of games would be doing it.

In fact, that level of complexity requires generating a whole new language and optimizing it enough to be of use during run-time.  The only reason Java and C# can get away with being “unhackable” (not to be taken literally) is because they had huge teams and millions in investments backing them.

 

This is obviously not plausible for any game team, and especially not for a single person.

 

If it was that simple, nothing would be hackable, as all game teams would jump onto the bandwagon.

 

Reiterating the point, if you try to emulate this with a compiled language by moving around variables, it will require more time and money than any hacker is worth, and it will cost you in performance as your game constantly looks up the value each time it is accessed.

 

 

L. Spiro


Edited by L. Spiro, 21 September 2013 - 07:12 AM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS