Solved

Game score unhackable?

Posted on 2004-09-29
23
490 Views
Last Modified: 2010-04-05
Hi There,
I am developing a game that will display your running score at all times. What approach should be taken to ensure that a trainer cannot be developed for messing with the score?
0
Comment
Question by:maxb
  • 9
  • 7
  • 5
  • +2
23 Comments
 
LVL 4

Expert Comment

by:Evarest
ID: 12185851
Nothing cannot be hacked, you know. If a cleaver enough hacker will set himself on your app, it'll be hacked/cracked in no time.

However, using some encryption, you might be able to scare off a lot of potential hackers. Just download the excellent DCPCrypt from

http://www.cityinthesky.co.uk/delphi.html

Please do download and review the included Demo's as they'll explain how to use the components.

Don't be discouraged if you can't get it right right away. It are very powerful components, and once you get the hang of it, you'll use them all the time...

Kind regards,
Evarest
0
 

Author Comment

by:maxb
ID: 12186159
What does DPCrypt allow me to do? I think i am looking more for like best practices as in "never keep the actual score in memory, decrypt it, change it, and encrypt it back up" or something...
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12188546
You don't need encryption to prevent people from messing up the score. All you need to do is calculate a hash over the score. A SHA or MD5 hash would be more than enough. Then you can just store the score any way you like, but you also store the hash. If someone messes around with the scores, your game would notice this immediately since the hash would be invalid.
If someone wants to cheat, they would also need to know how to calculate that hash. And that's often a bit more difficult than cracking some encryption scheme. (Especially if you calculate a hash over only a part of the things you store in the scoreboard.

This piece of code will calculate a very simple hash over a string value. It should be enough for simple purposes:

function PJWHash( const Value: shortstring ): Integer;
var
  I, G: Integer;
  Len: Integer;
begin
  Len := Length( Value );
  // Initialize the hash value.
  Result := 0;
  // Now add every character to the hash, in a very randomized way.
  for I := 1 to Len do begin
    Result := ( Result shl 4 ) + Ord( Value[ I ] );
    G := Result and $F0000000;
    if ( G <> 0 ) then Result := Result xor ( G shr 24 ) xor G;
  end;
end;

This hash function works best if the strings you're using are at least 7 characters. You could use it like this:
PJWHash( 'Piece of salt' + Score.PlayerName + IntToStr(Score.Total) );

The "Piece of salt" in front of it is just some fixed text that is used to make the string a bit longer, and the result less predictable. And this hash function is pretty fast.

Can people still mess with the score? Sure, but now they also have to deal with the hash. And it will take them brute force to guess the right hash value for an altered score.

If you want to make things even a bit more difficult, you don't just calculate a hash over each score in your system, you also calculate a hash over all the hashes and make sure that doesn't change either. So if this is the scorelist:
Name           Score
kretzschmar    1003474
Madshi         599986
inthe              514794
geobul              381648
Ferruccio68        366296
Slick812            364557
rllibby            344898
mnasman            340396
Epsylon            324729
DragonSlayer        300794
rwilson            293576
simonet            222423
Workshop_Alex  215226
Lischke            205638
Lee_Nover          192042

Then you first calculate a hash for each line:
Name           Score       Hash
kretzschmar    1003474     1A2B3C4D
Madshi         599986      5A6B7C8D
etc...

And then a sum of all hashes:
Lischke            205638      9F8E7C6D
Lee_Nover          192042      1F2E3F4E
                           --------
                           FE34CD88

(Too bad EE doesn't use a fixed-size font.)
All you have to do is calculate the hashes and the total hash and any hacker will have a hard time trying to crack it.
0
 

Author Comment

by:maxb
ID: 12191250
Workshop_Alex,
That sounds good. Can you help me understand the actual implementation? Obviously the score needs to be altered and displayed during the course of the game. Can you walk me through the exact steps on doing that?
 I'm looking for something like:
1. hash score
2. check if current score hash equals old hash
3. increment score and rehash

??
Thanks!
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12191580
Well, I assume you store the score in some way, e.g. a record. Something like:

type
  TScore = record
    Name: string;
    TotalScore: Integer;
    // Add this:
    ScoreHash: Integer;
  end;
  TScoreList = array[0..9] od TScore;
var
  ScoreList: TScoreList;

So, whenever you change thename or score of a record, recalculate the hash like this:

  ScoreList[0].Name := 'Workshop Alex';
  ScoreList[0].TotalScore := 96460;
  ScoreList[0].ScoreHash := PJWHash( 'Piece of salt' + ScoreList[0].Name + IntToStr(ScoreList[0].TotalScore) );

Or when you need to check it, use:
  if (ScoreList[0].ScoreHash = PJWHash( 'Piece of salt' + ScoreList[0].Name + IntToStr(ScoreList[0].TotalScore) )) then begin
    // Score is okay.
  end else begin
    // Some hacker messed around with it all.
  end;

And to calculate the total hash:

var
  I:Integer;
  Temp: string;
  TotalHash: Integer;
begin
  Temp:= '';
  for I := Low(ScoreList) to High(ScoreList) do Temp := Temp + '/' + IntToStr(ScoreList[I].ScoreHash;
  TotalHash := PJWHash( Temp ); // No need for this one to be salted.

Or if you just want to check if the whole list is unaltered, then change the last line into:
  if (TotalHash = PJWHash( Temp ) ) then begin
    // Score is okay.
  end else begin
    // Some hacker messed around with it all.
  end;

All you have to do is store both the scorelist and the total hash in some way. But that's up to you. There are too many ways to do such a thing. But a good way would be to use a class for the TScore and a second class for the TScoreList. That way, you could automatically recalculate the hash values if needed.
In general, you would only have to check the hashes when you read the list from file, or calculate the hashes when you write it to a file.

The chance of someone cracking this system is pretty low, since they have to guess two proper hash values. They could do this if they know the hash algorithm that you've used and also know the grain of salt (the extra string constant) that you used to pollute the hash a bit. Otherwise, they need to use brute force to guess the two proper hash values. Since both have about 4 billion possible values, they have 4 billion * 4 billion different possibilities. That's quite a lot... :-)
0
 

Author Comment

by:maxb
ID: 12191654
Well, the score is basically just one number stored in an Integer variable.

You're saying that its fine to check the hash just when its read from a file, however, that doesnt prevent people from changing the value in memory as the app is running... I'm trying to prevent people from using trainers- something that changes the actual system memory values. Still confused
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12193925
Well, if you want to prevent people from changing the value of the high score while your game is running, you would have to create get/set methods to assign the score to the scorefield. The get will have to check the score and the set would adjust both the score as the hash. This is best done if the score is part of a class.
However, it isn't that easy to hack values that are stored in-memory. Besides, if some hacker manages to do this, then no protection scheme would be save for this hacker.

But, a trainer must be loaded in the process space of your application and you could perhaps come up with a way to detect that a user is loading such a trainer in your application.
0
 
LVL 7

Expert Comment

by:DavidBirch2dotCom
ID: 12203250
Hi this is a nice site to read all about creatingn unhackable stuff in delphi, its not specificaly about this form of encrytion but I am certain it will give you some ideas

http://www.inner-smile.com/nocrack.phtml

Have a look at this thread also

http://www.experts-exchange.com/Programming/Programming_Languages/Q_21071015.html#11660670

David
0
 
LVL 13

Accepted Solution

by:
BlackTigerX earned 50 total points
ID: 12214688
another thing to keep in mind is to:
have the score in MORE THAN ONE PLACE!... and so, if at some point the scores are different, you know they are messing up with your application...

(in addition to) you could also keep the score in something like:

if the score it 58210 (supposing the highest score is 99999)

a=5
b=8
c=2
d=1
e=0

x=58210

add encryption to all those variables and any cracker will get crazy trying to figure it out!!
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12219885
I just don't get it... Why did you accept BlackTigerX his answer?
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12223434
I'll let him answer that, but just a comment on this:

if (ScoreList[0].ScoreHash = PJWHash( 'Piece of salt' + ScoreList[0].Name + IntToStr(ScoreList[0].TotalScore) )) then ...

and that PJWHash XOR "encryption", is just completly discouraged, XOR encryption is one of the oldest and wickest methods for encrypting
in this example of "protection" you show, a hacker would just have to encrypt whatever he wanted the score to be and is done (since you are providing the simple little function)

you can read about cracking XOR encryption here:
http://www.delphi3000.com/articles/article_2199.asp?SK=

there are many methods around for good encryption methods, "home made" encryption methods are COMPLETLY DISCOURAGED by anyone that knows about encryption-decryption techniques, standard methods are preferred (MD5, etc)
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12224959
BlackTigerX, this is not encrypting we're talking about, but hashing. Two completely different techniques. And the hash method selected by me in this case just is an example. For more security, use a more complicated hash!
You are confusing encryption with hashing. A hash is just like a digital signature, making it harder to tamper with the signed data. All you do is read the value, calculate the hash and compare what you've calculated with what you've stored. If it's the same, it's not tampered with.

And for both encryption and hashing, if the hacker knows the algorithm, then it's not protected. All the user then needs is the key to encrypt and decrypt the data, if there is a key in the first place. The two of you should definitely learn the difference between hashing and encryption. A HASH CANNOT BE DECRYPTED! Thus, hashing is just as good as a solution as encryption.

If you use a hash instead of encryption, you will keep the hacker off-guard for quite a while. He sees where the score is stored but if he alters it, the program crashes. With encryption, once he knows how to decrypt it, he just encrypts his preferred score. Besides, no matter what you try, the encryption routine or hash routine is always provided to the hacker. It's there, in your code, stored as binary code. He can easily call those routines to use for his own needs.

What you suggested:
> if the score it 58210 (supposing the highest score is 99999)
> a=5
> b=8
> c=2
> d=1
> e=0
> x=58210
is even weaker than encryption or hashing since the average hacker will just use a disassembler to study the sourcecode. Looking for the place where the score is updated and from there he just looks how it is stored. If a hacker already has this much access to the application, no protection scheme is safe. Because no matter what you do, at one point the score has to be updated. All the hacker has to do is debug the whole thing. The weak spot is the one routine that is used to update the score anyway. No matter how you encrypt the data, no matter in how many variables you store the score, no matter how much hashing you do, at one point there's one single function that will assign a value to the score. All the hacker has to do is find this point and pass his own values instead.
If you encrypt it, all he has to do is discover where you encrypt the value.
If you split it, all he has to do is find where you split it.
If you hash it, all he has to do is find the call to the hash routine.

No, this is just the big problem with security. If the hacker has access to the binary code, then he can crack it. It might take a day or two but it will happen.

Now, the reason why I'm so suprised that he accepted your answer, BlackTigerX, is because all you suggest is to split up the score over multiple locations. And that's just a very weak protection. A hacker would easily discover this by keeping an eye on all memory writes. First you write to a, then to b, then to c, then to d... All he has to do is check what you've written. And if you encrypt it before splitting it, he just has to alter the score right before you start encrypting it... Piece of cake, actually.
The same is true for the hashing solution, though. But as I said, no solution is foolproof.
0
 

Author Comment

by:maxb
ID: 12228801
Hi Alex, I'm very sorry but I didnt even realize that it wasn't you who posted the splitting suggestion. I sincerely apologize, I realize I actually should have split the points because BTX actually did provide another idea that I have not thought of.

Since all encryption can be broken, how are all these online casinos still in business? I don't get why there isnt a trainer or something out by now.... any ideas?
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12230444
I'm not worried about not getting the points, maxb. It's just that I thought it was weird that you accepted some other answer.

And why are online casinos still in business? Simple. Too many people are just losing money with their games, so that makes up some of the losses. The additional advertisements on their sites add more revenue. The price money is also limited to some maximum amount in many cases. Furthermore, they might not just keep track of the score but also the time it took the player to reach that score. If you can score about 500 points per minute then it's suspicious if someone scores 10.000 points within a minute. And of course, these are online games. They could send an in-between score to the server quite regular.
Also, since these are online games, it is a bit difficult for hackers to hack the system. Their actions are tracked by the server, thus by analysing the server logs you can check if there was some foul play going on.

It is still possible to hack online casino's, though. But it just requires quite a few good resources and keeping track of the network traffic. But guess what? An online casino can make it harder by changing the protocol slightly every week. Like with the hash I suggested, by changing the seed every two weeks in your application and then sending an updated game version to the users, they don't give hackers much time to crack the current system. Especially if it's a Flash/MacroMedia application that's reloaded every time the player visits the site.
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12230505
I am afraid you don't know much about code protection Workshop Alex, I recommend you read from guys that know more about it, they will recommend you to keep different variables with same values but hashed different and so that is what I suggested

and hashing or encrypting using XOR method is not good anyway

however I do agree that there is no such thing as security, if a good hacker wants to tamper it, he will no matter what you do
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12230554
actually the casinos is another whole story, they use laws of probabilities (randomness), and EVERY turn has the same (1 in a billionth or whatever) probability of winning the big price

that randomness can be adjusted

can it be hacked? sure... but you would actually have to hack into their servers first and whatever database they use, not only the screen (Flash or whatever) that you see... as you can see, the complexity of that is very high
0
 

Author Comment

by:maxb
ID: 12230735
So the casino software actually does no calculations? You're saying that you need to hack their servers... why? if the software is on your PC (why not just hack your PC's memory?). Any idea how its actually setup?
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12233417
if it was only in your computer it would be way too easy...

if you were the one programming it, would you relay only in the client side program? I wouldn't, is just like any other web application, you can NEVER trust the data coming from the client side, you always validate it

Macromedia files (all versions) have been cracked really easy

I don't know how is actually setup
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12243982
@BlackTigerX, let's just say that opinions differ on this. I still wonder how you could crack a one-way hash anyways. All you end up with is 4 bytes of data securing whatever amount of data there is. Even if a XOR method is used, it's still a one-way method. Trying to calculate the correct score back from the hash is just impossible, no matter what kind of method you use. Now, if the hacker happens to know the hash method and seed used to hash the score then he has mostly cracked it already. But again, this is true for whatever hashing method you use. No matter if you use XOR or e.g. the more complex SHA hash. OR a DES or Triple-DES. MD5 would do fine too.
Of course, for encrypting a XOR hash won't do, but again... I'm NOT encrypting here. And a XOR hash is weaker than a SHA hash since the final result set is a lot smaller.
Furthermore, there is a hashing algorithm that is very popular which is based on the XOR principle... Ever heard of BLOWFISH? Go check it.

One other reason why I chose this simple XOR algorithm is just because it's simple. Simple, fast and already very effective. And if you read my first post, I already said this was just one of the simplest hashing methods. The only weakness of my XOR method is that the result is a 32-bit value. Most other hashes start with a 64-bit result set and could even be as big as 512 or 1024 bytes. (And bigger.)
---------------------------------------------
About those online casino's, they could be using a simple webservice system. The client application would be connecting to the server through the webserver, calling methods on the server that will do most of the calculations and the random drawing of cards or whatever. In Delphi, this is called SOAP, although webservices have grown a bit beyond this. So if they have a poker game, the client asks for 5 cards to be drawn. The server then sets up a new game, draws 5 cards and remembers that this player just started a game with the cards chosen randomly for the player. The client shows them to the player, the player can start bidding and/or discarding cards and ask new ones from the server. The client tells the server which cards have been discared and the server remembers this and draws more random cards for the player. Determining if the player has won and if so, how much, is also done on the server.
The biggest drawback is of course that a player needs to be connected to the Internet and you should be aware that a player could just quit the game while it's still playing. (E.g. because he has very bad cards, but also because of a power failure that ends in a connection loss.) Thus, the server will just have to remember where the player was the last time so the player can continue the game at a later time, or assume the player just forfeited the game. Player loses, thus loses his cash too. However, players should be warned about this before they start playing! (If during a game the connection is broken, the player might get 48 hours to reconnect or else he loses the game and bet.)
For multiplayer casino games this would be even more difficult, though. Just imagine someone is about to win and his connection is broken off for whatever reason. That would cost him a lot of money but the other players just continue to play. Thus, with multiplayer games it becomes even more complex.

With online casino's, the only client-side calculations are the ones that don't affect the game. With poker, for example, the client application could display what kind of card the player has (2 pairs, full house, royal flush, whatever.) And the client application might tell the player which odds he has on getting a better card if he discards some cards. Also keep in mind that with a game like Blackjack, you should "shuffle the cards" before the first game starts and them remember the whole deck until it's emptied. With blackjack, the cards are only shuffled after they've all been drawn. Thus, the client application could even keep track of all cards that have already been drawn and thus help the player even more in predicting which cards are in the deck.

Keep in mind that online casino's have to invest heavily in a secure server park. Not only do they have to serve hundreds of players at the same time, they also have to do lots of calculations and store the data of every game.
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12245314
the only part that we disagree is that you say that having the value split across multiple places (different variables in different places) is weaker than having a simple "if"
"What you suggested:
> if the score it 58210 (supposing the highest score is 99999)
> a=5
> b=8
> c=2
> d=1
> e=0
> x=58210
is even weaker than encryption or hashing since the average hacker will just use a disassembler to study the sourcecode"

maybe you didn't read my initial post, I also said:
"add encryption to all those variables and any cracker will get crazy trying to figure it out!!" (meaning hashing each separate variable, even using different methods for each)

and when I used the "encryption" word, I was meaning "one way encryption", also known as hashing, I put MD5 as an example of this, so that was just a misunderstanding

anyway, the question is closed

best regards
BlackTigerX
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12254582
BlackTigerX, you just keep mixing up the words encryption and hashing. If you don't even know the difference between these two terms, then you're only confusing matters. And if you suggested to hash the score then your answer is not so different from mine. And if you only hash those values then you can't ever get the original score back so you have to score the original score in one place and the hash in some other place.
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12267296
well, The questioner understood what I meant and he knows is a good idea, if you are confused about the terms I used, I'm sorry for you
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12272176
No, the questioner already said he made a mistake because he didn't realise that the answer you gave wasn't from me. As he says:

> Hi Alex, I'm very sorry but I didnt even realize that it wasn't you who posted the splitting
> suggestion. I sincerely apologize, I realize I actually should have split the points because
> BTX actually did provide another idea that I have not thought of.

Apologies accepted and for only 50 points I'm not going to start a lot of trouble. Basically, he would have split the points if he realised that your answer didn't come from me.

The only good suggestion you apparantly made was splitting the score in multiple fields...
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now