Anti-hacking idea

Published January 17, 2006
Advertisement
I've been thinking to a solution to prevent hackers from releasing a pirated version of the game giving unfair advantages. Surely all the critical data and calculations will be done on the server side, but protecting the client from "cheap hacks" (like aimbots) is necessary too. This is for an online game, client/server based.

So here is the idea: each time a client wants to connect to the server, it has to download & replace the client EXE from it, pretty much like a patch.. but every time it connects. The trick is, the downloaded EXE is different each time and incompatible with its previous version, including the network protocol, function adresses, etc..

When the server detects an incoming connection, it picks up one EXE from a pool (which can be arbitrarily as large as you want) and sends it to the client. All the EXEs use a different network protocol and once the download is complete, the server is set to only understand the specific protocol corresponding to the client. If there's still no reconnection after 10 seconds, for example, the process has to restart from the beginning.

Some drawbacks i can see:
- additional bandwidth (if the EXE is 1 MB, that's 1 MB of bandwidth consumed each time a client connects).
- the server has to understand all the possible protocols at the same time
- the number of client EXEs has to be pretty large
- each time the client EXE is patched/improved (by the developpers), many versions have to be recompiled.
- not 56K friendly. ADSL is not problem because downloading 1 MB is only a couple seconds.. but 56K modem users will have to be patient.

The advantages:
- if a hacker modifies his local EXE, the server will send him a new one when he connects. If the hacker ignores the newly downloaded EXE and tries to connect to the server with his hacked version, the protocols will be incompatible and the connection refused.
- if the hacker downloads a new EXE, wants to hack it and connect to the server with this hacked version, he has to do it in less than 10 seconds.
- a hacked version cannot be redistributed because it would be invalidated as soon as average-Joe connects to the server.

The flaws..?
- could the hacker modify the EXE in less than 10 seconds ?
- still does not fix the content-modification problem (like modifying textures/models or external DLLs).

Thoughts..?
Previous Entry Station screenshots 2
Next Entry Server emulation
0 likes 24 comments

Comments

_winterdyne_
You can't guarantee that the downloaded exe is the one that will be run to connect - if someone already knows your encryption protocols (all of them) cycling the protocol won't help. You need a method of authenticating the client software and assets.

You can try an asset (including DLL) hashing system, where a hash of a random asset is checked periodically - if the hash fails there's an asset hack on the client, flag it dirty on the login box, and a new asset must be acquired before the client will authenticate. Hash checks can be done on the login box, so shouldn't slow down the game too much. You could even periodically (if you get clientside time) generate hashes from in-memory assets and get those checked - would make run-time swapping of assets more difficult.

If you package potentially exploitable code into its own DLLs and keep 'em encrypted (decrypt to memory, then load the DLL from there) you make disassembly very difficult.

You could also package required game-server negotiation information in 'up-to-date' DLLs, such as D-H primes and generators. Might make a smaller download than the whole exe, and eases the burden of modifying protocols all the time - the clients simply won't be able to negotiate an encryption key.

Just a couple of ideas I've been working on myself.
January 17, 2006 04:38 AM
Monkeyget
Isn't it possible to change the executable code when it is being executed? (code injection,...) The game logic won't change much from an executable to another so it's just a matter of finding what to change. I ain't no hacker so i might be wrong.
January 17, 2006 04:48 AM
_winterdyne_
Yes, but it's difficult - most OS's freak out if a process writes into the memory of another, so the client-to-be-hacked has to be launched inside the code-injector's memory. This cuts down the number of possible cheaters massively.

Hashing assets *whilst in memory* and periodically changing them (even if you just change the version number) causes a real headache. Code-injecting to a (loaded) DLL, will end up with that DLL having a different hash, or worse yet overwriting a different asset, which will fail if checked. Close-packing memory management of assets makes code injection into loaded DLLs very difficult.







January 17, 2006 04:56 AM
jollyjeffers
One thing that I've seen talked about regarding the new Windows Vista (note: obviously not a problem if this isn't a target platform) - security concerns. A lot of current copy protection stuff bends the rules regarding mild forms of "hacking" type programming. Because it's A Good Thing™ most people don't mind - it's when people do the same stuff for bad reasons that we freak out.

The obervation being, that any sort of "clever" anti-cheat/anti-piracy thing could end up being classified, restricted or killed by the OS [oh]

Jack
January 17, 2006 05:47 AM
NickGeorgia
Would modifying textures slightly every once in a while do the trick? Or perhaps lay a trap and make it obvious someone is hacking then deal with accordingly?
January 17, 2006 06:00 AM
Drilian
Also, don't forget that a malicious server (I assume players are running their own servers) could build their pool out of virus-laden copies of the exe for fun and profit. That'd be very, very bad.

Or a non-malicious server that just happens to have a virus on it. Either way, bad stuff.
January 17, 2006 09:18 AM
PERECil
There are many things to do:

A. When loading files, put a read/write lock on them, so nobodies can access them while the game is running. Upon start, check every file (CRC Hash). If the hash is wrong, redownload the file from internet.

B. This doesn't prevent a hack from the main executable. To protect the main executable, upon connection, download a small code (dll? exe?) which will run from memory. This dll will check the main executable and maybe the memory for hacking tools. When the dll has checked everything, send a message to the server (with a generated code valid only one time, and another key based on the computer's devices installed), which enable the server to process the client login (which will also send the devices installed).

Note that the executable file will be "locked" by the filesystem, so any attempt to modify it on the fly would fail. Any hacked exe which wouldn't download the check dll wouldn't be able to login in.

C. This doesn't prevent a hack from memory (changing in assembly a jump in the downloaded code). But you can kill the gameplay of a possible hacker by redownloading the check code once a while. Being in memory, it forces the hacker to go step by step through the code to change the code in assembly mode. And who really wants to do this every 5 minutes?
January 17, 2006 10:11 AM
Drilian
Actually, after thinking about it more, it's worse than that. It wouldn't even have to be a virus-laden copy of the EXE, it could just be any arbitrary bad thing. Remote haXX3ss? Yep. Format c:? Sure.

I think that accepting and running arbitrary code from another machine is a bad idea waiting to be abused. Whether it's a DLL or an EXE or whatever, it's a massive, highly-critical security flaw. It's what's gotten Microsoft into a ton of trouble recently (re: WMFs).

In Summary: It's a potentially good idea from an anti-cheating perspective, but in terms of system security, it should be avoided at all cost.
January 17, 2006 11:04 AM
Metorical
Drilian: If you're connecting to someone's server using software released by them then you're putting yourself at their mercy anyway. I don't think a mechanism to distribute new executables/patches would make it any more dangerous than it already is however people accept these risks everyday when they download software from the internet.

Ultimately though any software ran on a remote machine is at mercy to the remote user. They can do anything to your software if they really want to so you can only limit the extent to which they cheat. Things like speedhacks should have never got in to mmorpgs but they happen all the time but hacks where a client can modify server data... even worse!

Of course it is definately worth it making it as hard as possible for them. One of authentication of an executable just wont work as they can bypass that check but an interesting way is to use the hash throughout the client. Rather than returning a true/false value on validation make a function that returns a complicated value then use this value throughout the code as part of the client mechanics? Someone wrote a good article about this very thing yet I can't remember what it is.

How about.

1. client gets server system time.
2. generates key based on time and client code.
3. server encrypts a patch based on what the client code should be and the time it recorded.
4. patch is sent down to client.
5. client can only decrypt patch if the client in memory hashes the same.
6. the patch contains a key used for transactions between the client-server.
7. regenerate the key at random intervals.
8. if a hash fails then you know they've changed the client in memory (e.g. through injection).

January 17, 2006 02:06 PM
Drilian
I was assuming that the servers were run by other players, not Ysaneya's company itself.
January 17, 2006 02:30 PM
Rebooted
Would it be possible to achieve this using scripts that run inside a virtual machine? This would remove security concerns, maybe you could still have enough control for the changing protocols, etc.

The script could be downloaded right into memory and run.
January 17, 2006 03:51 PM
Raduprv
Don't even bother, people will always find ways to cheat using aim bots.
Having different sets of protocols is extremely counter productive, hard to implement, bug prone, etc.
Besides, I wouldn't play a game that sends me a new client each time I connect. Even with my DSL, it still takes abotu 20 seconds to download 1 MB (assuming the game server can send it at full speed, which is not the case when you have like 10 log ins/second.).
January 17, 2006 04:53 PM
Jotaf
Quote:
Of course it is definately worth it making it as hard as possible for them. One of authentication of an executable just wont work as they can bypass that check but an interesting way is to use the hash throughout the client. Rather than returning a true/false value on validation make a function that returns a complicated value then use this value throughout the code as part of the client mechanics? Someone wrote a good article about this very thing yet I can't remember what it is.


Better yet! Send the hash code itself :)

1. Server requests hash from bytes X to Y
2. Client performs hash and sends value back
3. Server checks it against its Reference Client Code

But like all methods that have been suggested, it's not fullproof. The hacked client could perform the hash on a backup copy of the original instead and send that value. Oh well :/ Tough problem.
January 17, 2006 08:25 PM
Raduprv
Yes, that is the most trivial method, and it can be reversed engineered as you've mentioned.
Unless you do the security thing at a hardware level (TCPA) it is relatively easy for a skilled, motivated person to overcome it. Of course, the chance for someone to hax0r it drastically increase with the popularity of the game.
January 17, 2006 08:54 PM
Crayfish
Seems to me that the best method is to download a small security DLL each time the player connects. The game runs the security code inside the DLL which sniffs around for known hacks and transmits back a verification message to the server which includes a code that was transmitted inside the dll.

The dll can be updated whenever new cheats are discovered so that it can detect the signature of those cheats on the user's system.

I think this is similar to how Punkbuster works.
January 18, 2006 07:28 AM
Jotaf
The big problem here is that, no matter how clever your code is, a well-placed jump in the modified client will prevent it from running.
January 18, 2006 11:36 AM
mldaalder
But the server expects a call saying that the client is verified.
January 18, 2006 11:47 AM
Raduprv
Which can be done with a call to a custom function that returns to the server whatever data the server expects.
As I was saying, true security can be done only in hardware (under a nazi paradigm such as the TCPA).
January 18, 2006 04:14 PM
Jotaf
Yes, thanks Raduprv, forgot that part :)

I was toying with the idea that a 3rd program/dll could start with the port/connection to the server and from there figure out what program is using it, so the hash can't be done on anything else than the same code that is connecting to the server. This avenue could be worth exploring.

Talking about hardware - make one of those CDs that are really REALLY hard to crack (like some recent games, the names elude me right now), and make the client only run from there, so if you tamper with it, you won't be able to "put it back" in the CD and run it :P You'd have to bypass all the copy protections to run it from outside the CD.
January 18, 2006 05:59 PM
Raduprv
The thing is, while a resonably difficult to crack protection can be implemented, it is really not worth it because:
1. Take s alot of tiem to implement.
2. Can annoy legitimate users.
3. In the end it can be broken anyway.

So ust better make addditonal checks on the server and/or make the game play of sucha nature that aiming bots can't do shit (such as equiping ships with auto tracking system), etc.
January 18, 2006 06:13 PM
Crayfish
Quote:Which can be done with a call to a custom function that returns to the server whatever data the server expects.


Except that in the method I proposed the verification code that the server is expecting is transmitted inside the dll. Where it is located inside the dll and how it is encrypted can change each time you release a new version of the dll.

This is really the same as Ysaneya's original proposal, except that instead of downloading the entire game executable on each connection, you just download the security library. You can't jump past the call to the library because the server is waiting for the verification it sends, and you can't falsify the verification, because only the dll knows what the server is expecting.

The security check probably initially be just a simple CRC check on the game resources. When the first cheats are released, the security check can scan for the presence of those cheats in memory. One sidestep would be to load the cracks after the game has run its initial security check, so it might be necessary to call the security dll at random times while the game is running.
January 19, 2006 04:31 AM
_winterdyne_
Going back to the asset hash I suggested - bear in mind that we treat our DLLs as an asset - it's loaded in explicitly from file not a 'lib-linked' DLL.

If every asset in the game has an even chance of being selected and tested by the hasher at the server's selection, to get that aimbot (hacked UI DLL) working, the hacker has to effectively maintain a number of hash tables of every asset in the game, OR to crack the main executable (in addition to the UI DLL) to ignore either all hash checks (in which case the server disconnects) or to hardcode the hash for the target DLL into the main executable, along with checks for the selection of that DLL. Asset memory usage is also a possible hashable (server-predictable) value. Checking this value at random times makes the construction of a 'fake' table for it very difficult, and would provide warning signs that a modified asset is being used.

It's never going to be entirely hack-proof, but it can be made so that it's difficult for the average script-kiddie or cheat-downloader to have their way.

January 19, 2006 01:55 PM
BDePesa
The people good at "hacking" games (see www.game-deception.com) would have more or less very little trouble getting around most of these implementations.

Code injection is very frequently (nearly always) used in the game-hacking world, and the stuff they can do with it is simply amazing. PunkBuster, one of the largest anti-cheat programs is a prime example of this. Even PB is easily bypassed.

My suggestion is to do enough to block out most of the more incompetent people, the higher-ups with more knowledge would be able to bypass anything you have the first time within a few weeks, and after that, within hours.

Anyone who wants more info can contact me through PM, I know lots about this :).
January 20, 2006 01:03 PM
gtbass
I have a friend who made a cheat for Final Fantasy Online. It is a separate application that scans the memory of the game, searching for his character's name as a string.

Once he finds that, he knows that he's found the beginning of the entity pool in memory. He can read the position data of the entities directly from the game's memory, so he doesn't even have to bother with packet sniffing.

To circumvent this cheat, you'd at least need to encrypt any recognizable strings stored in memory.
January 22, 2006 02:18 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement