Cracking protection exercise

BlitzMax Forums/BlitzMax Programming/Cracking protection exercise

deps(Posted 2010) [#1]
Hi. Just to exercise my brain a bit I took a stab at creating some kind of memory cracking protection. If someone really wants to crack something they will do so eventually, but I enjoyed thinking about it.

Here's some code. I don't have much experience of memory cracking, or hacking, and wonder if someone could take a look at this, maybe even compile it and give it a go, and see if it's actually useful?

Please note that I wrote the code in just one sitting, and there's probably lots of room for improvement.

SuperStrict


Type TLockedValue

	Field name:String
	Field m_int:Int
	Field m_float:Float
	Field m_double:Double

	Method TransferTo( other:TLockedValue )
		other.name = name
		other.m_int = m_int
		other.m_float = m_float
		other.m_double = m_double
	EndMethod

EndType


Type TSafe

	Field list:TList
	Field timer:Int

	Method New()
		list = CreateList()
		timer = MilliSecs()
	EndMethod
	
	Method Add( lv:TLockedValue )
		' Create a copy of it and add it to the list
		Local nlv:TLockedValue = New TLockedValue
		lv.TransferTo( nlv )
		list.addlast( nlv )
	EndMethod
	
	Method Get:TLockedValue( name:String )
		For Local lv:TLockedValue = EachIn list
			If lv.name = name
				Return lv
			EndIf
		Next
		
		' Not found
		Return Null
	EndMethod
	
	Method Change( lv:TLockedValue )
		' Find the original
		Local o:TLockedValue = Get(lv.name)
		If o
			list.Remove( o )
		EndIf  
		
		' No matter if it existed or not, it doesn't do that now. Add it
		Add( lv )
	EndMethod
	
	Method Update()
		If MilliSecs() > timer+100
			timer = MilliSecs()
			' Create a new list at a new memory location
			Local nl:TList = CreateList()
			' Loop through the current list
			For Local lv:TLockedValue = EachIn list
				' Create a new locked value, and transfer the old values to it
				Local nlv:TLockedValue = New TLockedValue
				lv.TransferTo( nlv )
				nl.addlast( nlv )
			Next
			' List is now the new list, the old one will be garbage collected
			list = nl
		EndIf
	EndMethod

EndType




Graphics 640,480,0

Local mysafe:TSafe = New TSafe

Local m:TLockedValue = New TLockedValue
m.m_int = 100
m.name = "money"
mysafe.Add( m )
m = Null ' Destroy local copy

While Not KeyHit( KEY_ESCAPE )

	If KeyHit( KEY_1 )
		Local lv:TLockedValue = mysafe.Get("money")
		lv.m_int :+ 1
		mysafe.Change( lv )
	EndIf

	If KeyHit( KEY_2 )
		Local lv:TLockedValue = mysafe.Get("money")
		If lv.m_int > 0
			lv.m_int :- 1
			mysafe.Change( lv )
		EndIf
	EndIf

	mysafe.Update()

	DrawText "Press ESC to quit", 0,0
	DrawText "Press 1 to add money and 2 to remove", 0,12
	DrawText "Try to hack the memory and alter the amount! :)", 0,24

	DrawText "Current balance: "+mysafe.Get("money").m_int+"€", 200,240

	Flip
	Cls
Wend


If someone finds this code useful, they're welcome to use it in any way they see fit.


plash(Posted 2010) [#2]
First off, this is really unrealistic, and you'll be wasting a lot of time and memory doing this.
I don't know of a game that has every value identified with a string, and likely it would be overkill in many situations.

"Preventions" like this will never stop anyone who wants to play with the program's memory anyways, especially at an update rate of 1 second.


deps(Posted 2010) [#3]

First off, this is really unrealistic, and you'll be wasting a lot of time and memory doing this.

It was made just for the fun of it. Got the idea and then hacked this together as a proof of concept. Or failure. Haven't tried to "hack" the memory location of the "money", but I'm not so experienced in it either. :)
I don't see it as a waste of time, as I wrote it just for fun. Memory? Might be, but that's not an issue these days if you ask me.
What do you mean by unrealistic?

I don't know of a game that has every value identified with a string, and likely it would be overkill in many situations.

String, integer, whatever. I wrote this in like 5 minutes. A string may not be efficient, true, but that's not the point.

"Preventions" like this will never stop anyone who wants to play with the program's memory anyways, especially at an update rate of 1 second.


As I wrote, anyone determined enough might eventually crack this, but I would like to see how. And it's not once per second, it's 10 times per second. (100 milliseconds between each update, 100*10 = 1000 == one second)

I'm not really putting this out there to prove anything. I did it for the fun, and if someone thinks that's it can be cracked, please show how. :)


plash(Posted 2010) [#4]
And it's not once per second, it's 10 times per second. (100 milliseconds between each update, 100*10 = 1000 == one second)
I swore I saw timer+1000 :p

I'm not really putting this out there to prove anything. I did it for the fun, and if someone thinks that's it can be cracked, please show how. :)
I certainly don't know how to do something like this (at least in the 'uuber hacker' kind of way).

What do you mean by unrealistic?
I mean unrealistic in that it would be silly to do this in an actual program (and with a bunch of locked variables, you'll be running the GC a lot more). There are probably far better ways to avoid memory modification - Punkbuster, GameGuard, etc.
But now that I see you didn't make it for that exact purpose, it doesn't really matter.


deps(Posted 2010) [#5]
(and with a bunch of locked variables, you'll be running the GC a lot more)

Yes that's a big drawback. The GC will get very busy indeed. :)

The only problem I can see with this is that the OS might reuse memory for some of the variables, making it easier to crack. This could be avoided by pooling old variables (and check them to see if they're altered, giving the game a chance to respond with a nasty message or similar).

Either way, it won't be pretty. :)
Still, if someone can compile that code and show how to crack it it would be great. For the fun of it.


plash(Posted 2010) [#6]
It could be done fairly easily if you grab the pointer to the list field in the TSafe object.
Then you'd just traverse the list every time to set/get a value.

Really, no different from what TSafe is doing itself. In fact, you could just as easily grab the pointers for the methods in TSafe and call them, or constantly keep the timer value to the current time.


deps(Posted 2010) [#7]

It could be done fairly easily if you grab the pointer to the list field in the TSafe object.
Then you'd just traverse the list every time to set/get a value.


Good point!
Maybe a bunch of dummy variables set to the same value could prevent this?
And if the dummy variables are changed, the game is notified about it.

But it's starting to feel like one is beating a dead horse! :)


beanage(Posted 2010) [#8]
This is inspiring.. thanks!


deps(Posted 2010) [#9]
You are most welcomed! :)