Cracking protection exercise
BlitzMax Forums/BlitzMax Programming/Cracking protection exercise
| ||
| 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. |
| ||
| 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. |
| ||
| 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. :) |
| ||
| 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. |
| ||
| (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. |
| ||
| 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. |
| ||
| 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! :) |
| ||
| This is inspiring.. thanks! |
| ||
| You are most welcomed! :) |