Jump to content

How do you make difficult hacking a variable by changing the value via memory?

I tried doing this:

template <class Type>class SafeVar{public:	SafeVar(Type value)	{		mValue = value;		mCheck = value;	}	void Set(const Type& type)	{		if (mValue != mCheck)			std::cout << "Hijacked value!\n";		else		{			mValue = type;			mCheck = type;		}	}	Type Get()	{		if (mValue != mCheck)		{			std::cout << "Hijacked value!\n";			return NULL;		}		else			return mValue;	}private:	Type mValue;	Type mCheck;};

I knew since the first line that this wasn't going to work, but at least it got me somewhere:

post-49433-0-38348700-1432735457_thumb.p

Although I wouldn't call this a win, since all you have to do is change both of the values, and since I can't know which one was edited I can't really reset it, so... what do I do now?

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/
Share on other sites

Link to post
Share on other sites

In C# you can  use a read only collection, wont let you change it unless you create a new read only collection and reassign it.

https://msdn.microsoft.com/en-us/library/ms132474%28v=vs.110%29.aspx

public static readonly IList<string> Questions;Questions = new ReadOnlyCollection<string>(new List<String>(GetQuestionsList())); 
Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5069647
Share on other sites

Link to post
Share on other sites

 

In C# you can  use a read only collection, wont let you change it unless you create a new read only collection and reassign it.

https://msdn.microsoft.com/en-us/library/ms132474%28v=vs.110%29.aspx

public static readonly IList<string> Questions;Questions = new ReadOnlyCollection<string>(new List<String>(GetQuestionsList())); 

I'm using C++, and no .NET framework, I can't do that  :(

 

Also, I tried this:

template <class Type>class SafeVar{public:	SafeVar(Type value)	{		mValue = value;		mCheck = value + 100;	}	void Set(const Type& type)	{		if (mValue != mCheck - 100)			std::cout << "Hijacked value!\n";		else		{			mValue = type;			mCheck = type;		}	}	Type Get()	{		if (mValue != mCheck - 100)		{			std::cout << "Hijacked value!\n";			std::cout << "Reset to " + std::to_string((mCheck - 100)) + "From " + std::to_string(mValue) + "\n";			mValue = mCheck - 100;			return mValue;		}		else			return mValue;	}private:	Type mValue;	Type mCheck;};

And by adding a number I can now check it and reset it, but the problem is that now I'm limited to numeric variables.

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5069691
Share on other sites

Link to post
Share on other sites

hmm, how about this. function-level static variable?, it is initialized only the first time through. So the inital value parameter is useless after the first run of the function. Therefore, all you need to do is ensure that the first call of the function is the one that initializes it.

int GetConstValue(int initialValue = 0){  static int theValue = initialValue;  return theValue;}
Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5069740
Share on other sites

Link to post
Share on other sites

 

hmm, how about this. function-level static variable?, it is initialized only the first time through. So the inital value parameter is useless after the first run of the function. Therefore, all you need to do is ensure that the first call of the function is the one that initializes it.

int GetConstValue(int initialValue = 0){  static int theValue = initialValue;  return theValue;}

You can still edit the value at any time if you know its location.

1474412270.2748842

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5069803
Share on other sites

Link to post
Share on other sites

 

hmm, how about this. function-level static variable?, it is initialized only the first time through. So the inital value parameter is useless after the first run of the function. Therefore, all you need to do is ensure that the first call of the function is the one that initializes it.

int GetConstValue(int initialValue = 0){  static int theValue = initialValue;  return theValue;}

That doesn't work, you can change the static var.

A static const may work, but then I wouldn't be able to change it.

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5069813
Share on other sites

Link to post
Share on other sites

Your complete programm code and variable values are open to the "attacker". So the only option you really is to obfuscate it to hell.

 

It helps a lot to understand how programs like Cheat Engine work.

 

First somebody searches for a value (e.g. your money in the game). Then he changes that value in game by buying something and searches again. This is done until you only left with one memory location what fits that value every time.

This is the first point where you can obfuscate. For example having 100€$ in game may be saved as variable = money + 30035 xor 1337

 

Of course there are many other ways like timers that check periodically or sanity checks that activate when the value changes outside of a reasonable value like 1000000000.

 

But it all end up being obfuscate in one way or another.

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5069935
Share on other sites

Link to post
Share on other sites

Maybe try using a random number generator to select a random number generator object from a list of RNG's each with a unique seed to obfuscate the variable after every update. Then to de-obfuscate you simply store the previously generated number. 

 

I don't know if that made any sense if I have time tonight I will make some pseudo code if a more clear explanation is need.

CPU: Intel i7 - 5820k @ 4.5GHz, Cooler: Corsair H80i, Motherboard: MSI X99S Gaming 7, RAM: Corsair Vengeance LPX 32GB DDR4 2666MHz CL16,

GPU: ASUS GTX 980 Strix, Case: Corsair 900D, PSU: Corsair AX860i 860W, Keyboard: Logitech G19, Mouse: Corsair M95, Storage: Intel 730 Series 480GB SSD, WD 1.5TB Black

Display: BenQ XL2730Z 2560x1440 144Hz

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5073576
Share on other sites

Link to post
Share on other sites

You could have 3 of the same variable, then any incorrect values get corrected depending on what the majority of the values read as e.g:

score[0]=1score[1]=1score[2]=1if ((score[0]==score[1]) and (score[2]!=score[0])) //Check for modification, if one of the values is incorrect{score[2]=score[0] //Correct it}if ((score[0]==score[2]) and (score[1]!=score[0])) //Check for modification, if one of the values is incorrect{score[1]=score[0] //Correct it}if ((score[1]==score[2]) and (score[0]!=score[1])) //Check for modification, if one of the values is incorrect{score[0]=score[1] //Correct it}
The only issue is that you need to set all 3 of them whenever you want to change one of them and so it will cause slightly more lag.

"My game vs my brains, who gets more fatal errors?" ~ Camper125Lv, GMC Jam #15

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5075858
Share on other sites

Link to post
Share on other sites

You could have 3 of the same variable, then any incorrect values get corrected depending on what the majority of the values read as e.g:

score[0]=1score[1]=1score[2]=1if ((score[0]==score[1]) and (score[2]!=score[0])) //Check for modification, if one of the values is incorrect{score[2]=score[0] //Correct it}if ((score[0]==score[2]) and (score[1]!=score[0])) //Check for modification, if one of the values is incorrect{score[1]=score[0] //Correct it}if ((score[1]==score[2]) and (score[0]!=score[1])) //Check for modification, if one of the values is incorrect{score[0]=score[1] //Correct it}
The only issue is that you need to set all 3 of them whenever you want to change one of them and so it will cause slightly more lag.

 

This is a good idea, but you can "freeze" a value with cheat engine, altho that means the cheater would have to freeze all the found values for it to work, which will probably crash the program, you could just alternatively make the program exit when a change is found with this method, then it would be safe, except not very efficient.

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5087108
Share on other sites

Link to post
Share on other sites

This is a good idea, but you can "freeze" a value with cheat engine, altho that means the cheater would have to freeze all the found values for it to work, which will probably crash the program, you could just alternatively make the program exit when a change is found with this method, then it would be safe, except not very efficient.

What about encrypting 2 (using something simple like Pi or something) of the values and then decrypting them when checking them?

"My game vs my brains, who gets more fatal errors?" ~ Camper125Lv, GMC Jam #15

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5087292
Share on other sites

Link to post
Share on other sites

 

In C# you can  use a read only collection, wont let you change it unless you create a new read only collection and reassign it.

https://msdn.microsoft.com/en-us/library/ms132474%28v=vs.110%29.aspx

public static readonly IList<string> Questions;Questions = new ReadOnlyCollection<string>(new List<String>(GetQuestionsList())); 

 

Does that actually ensure that an outside program can't modify your program's memory? I would have assumed it would only ensure the CLR can't modify your memory.

 

I'd assume you'd need a server to do checksums to verify that you aren't cheating.

 

Theoretically, you could try and get your operating system to prevent modification to a page... then again, someone could just hack the operating system and get around that.

 

 

What about encrypting 2 (using something simple like Pi or something) of the values and then decrypting them when checking them?

If a machine can decrypt it, the key for it is on the machine. Anyone on the machine could find the key and decrypt it.

 

 

 

You could have 3 of the same variable, then any incorrect values get corrected depending on what the majority of the values read as e.g:

score[0]=1

score[1]=1

score[2]=1

if ((score[0]==score[1]) and (score[2]!=score[0])) //Check for modification, if one of the values is incorrect

{

score[2]=score[0] //Correct it

}

if ((score[0]==score[2]) and (score[1]!=score[0])) //Check for modification, if one of the values is incorrect

{

score[1]=score[0] //Correct it

}

if ((score[1]==score[2]) and (score[0]!=score[1])) //Check for modification, if one of the values is incorrect

{

score[0]=score[1] //Correct it

}

The only issue is that you need to set all 3 of them whenever you want to change one of them and so it will cause slightly more lag.

 

 

Why couldn't someone just modify all 3 values at once?

 

 

might be bit overkill but what about something like MAC or HMAC ?

you mean like doing a checksum with something like SHA-256? The attacker could probably modify the hash value as well as the original, if it's stored on the same machine. Probably would slow an attacker though.
Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5088330
Share on other sites

Link to post
Share on other sites

 

you mean like doing a checksum with something like SHA-256? The attacker could probably modify the hash value as well as the original, if it's stored on the same machine. Probably would slow an attacker though.

 

 

Yup you make a checksum of the data + something secret, and check the data later on if that + the secret matches the checksum

 

27zycg5.jpg

 

and yea they can still modify it if they really want to, but not through a simple process like just editing a value, they need to know how the code works in order to calculate the checksum for the new value.

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5090493
Share on other sites

Link to post
Share on other sites

and yea they can still modify it if they really want to, but not through a simple process like just editing a value, they need to know how the code works in order to calculate the checksum for the new value.

I suspect this kind of thing has been tried with anti piracy software and already been beaten. Look how fast they got denuvo

 

That's what I'm aiming for, it's impossible to make it completely safe, but if you make it hard enough most of the people will give up.

I think serverside checks are the way to go for anti cheat. You'd only want anti cheat to prevent multiplayer cheating, so there's not much of a problem with forcing always online for multiplayer.

 

It'd be a lot harder to break an anticheat if you have to figure out what input the server is looking for. You can always send a fake checksum to the server, but you'd have to figure out what it'd have to be blind.

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5093467
Share on other sites

Link to post
Share on other sites

Just simply, don't save the raw value in the variable.

For example
instead of
int score = 100;
score += 10;
score -= 10;

You can do something like this:
int Encode(int val)

{
  return ((val * 75) + 20) ^ 0xffffffff
}
int Decode(int val)
{
  return ((val ^ 0xffffffff) - 20) / 75
}

int score = Encode(100);
score = Encode(Decode(score) + 10);
score = Encode(Decode(score) - 10);



this is a very simple example of this. You could make it a lot more complicated. But they idea stays the same.
If you try scanning for your score, you won't be able to find it, since the actual value is not stored on the heap.
The only way to hack it, is to know the little formula.

If you want to can stick this in some template class.

EDIT:

I made a little template class with some overloaded operators.
I also improved the encoding and decoding so there is no information loss, and I also made a version for 64 bit values.

Code: http://scrnsht.me/u/1d/raw

 

Link to comment
https://linustechtips.com/topic/374805-anti-cheat/#findComment-5099920
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×