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! :) |