views:

710

answers:

9

One of our next projects is supposed to be a MS Windows based game (written in C#, with a winform GUI and an integrated DirectX display-control) for a customer who wants to give away prizes to the best players. This project is meant to run for a couple of years, with championships, ladders, tournaments, player vs. player-action and so on.

One of the main concerns here is cheating, as a player would benefit dramatically if he was able to - for instance - let a custom made bot play the game for him (more in terms of strategy-decisions than in terms of playing many hours).

So my question is: what technical possibilites do we have to detect bot activity? We can of course track the number of hours played, analyze strategies to detect anomalies and so on, but as far as this question is concerned, I would be more interested in knowing details like

  • how to detect if another application makes periodical screenshots?
  • how to detect if another application scans our process memory?
  • what are good ways to determine whether user input (mouse movement, keyboard input) is human-generated and not automated?
  • is it possible to detect if another application requests informations about controls in our application (position of controls etc)?
  • what other ways exist in which a cheater could gather informations about the current game state, feed those to a bot and send the determined actions back to the client?

Your feedback is highly appreciated!

A: 

You should look into what goes into Punkbuster, Valve Anti-Cheat, and some other anti-cheat stuff for some pointers.

Edit: What I mean is, look into how they do it; how they detect that stuff.

TraumaPony
+4  A: 

Just an idea what if the 'cheater' runs your software in a virtual machine (like vmware) and makes screenshots of that window? I doubt you can defend against that.

You obviously can't defend against the 'analog gap', e.g. the cheater's system makes external screenshots with a high quality camera - I guess it's only a theoretical issue.

Maybe you should investigate chess sites. There is a lot of money in chess, they don't like bots either - maybe they have come up with a solution already.

Just about the VM thing - you could use Shader Model 2.0 for the game, which currently no VM can run in hardware.
OregonGhost
A: 

@TraumaPony: We have already checked out Punkbuster et al, but as far as we understand it, the main purpose of those tools is to detect known cheats, exploits etc. In our case that would not be applicable, as due to the limited userbase it would be more likely to encounter custom made cheats.

Edit: Thanks for the new response. I understood what you said, but Punkbuster for instance (and it's really the same with the other products in this area), mainly act as a kind of virus-scan, searching for dubious memory-fingerprints, processes, changes to APIs and the like (also see http://en.wikipedia.org/wiki/Punkbuster). This would apparently not work for custom-made cheats.

Grimtron
A: 

@kineas.myopenid.com: Exactly right, that's the reason why we're interested in ways to detect information-polling from the client itself. As the game is rather high paced we deem it unlikely to have a separate "bot-advice-output" which a user would follow (as would be possible in a chess game), but the bot would have to "play himself", with limited human-interaction.

Grimtron
+1  A: 

I don't know the technical details, but Intenet Chess Club's BlitzIn program seems to have integrated program switching detection. That's of course for detecting people running a chess engine on the side and not directly applicable to your case, but you may be able to extrapolate the apporach to something like if process X takes more than Z% CPU time the next Y cycles, it's probably a bot running.

That in addition to a "you must not run anything else while playing the game to be eligible for prizes" as part of the contest rules might work.

Also, a draconian "we might decide in any time for any reason that you have been using a bot and disqualify you" rule also helps with the heuristic approach above (used in prized ICC chess tournaments).

All these questions are easily solved by the rule 1 above:

* how to detect if another application makes periodical screenshots?
* how to detect if another application scans our process memory?
* what are good ways to determine whether user input (mouse movement, keyboard input) is human-generated and not automated?
* is it possible to detect if another application requests informations about controls in our application (position of controls etc)?

I think a good way to make harder the problem to the crackers is to have the only authoritative copies of the game state in your servers, only sending to and receiving updates from the clients, that way you can embed in the communication protocol itself client validation (that it hasn't been cracked and thus the detection rules are still in place). That, and actively monitoring for new weird behavior found might get you close to where you want to be.

Vinko Vrsalovic
And what about older computers running the software? Processor usage is a very vague and nebulous way to detect automation.
Jeff Hubbard
It would have to work not in absolute terms, but relative to the computer itself. In any case, more than the heuristic, the rest of the comment is what's most relevant, imo
Vinko Vrsalovic
+3  A: 

The best protection against automation is to not have tasks that require grinding.

That being said, the best way to detect automation is to actively engage the user and require periodic CAPTCHA-like tests (except without the image and so forth). I'd recommend utilizing a database of several thousand simple one-off questions that get posed to the user every so often.

However, based on your question, I'd say your best bet is to not implement the anti-automation features in C#. You stand very little chance of detecting well-written hacks/bots from within managed code, especially when all the hacker has to do is simply go into ring0 to avoid detection via any standard method. I'd recommend a Warden-like approach (download-able module that you can update whenever you feel like) combined with a Kernel-Mode Driver that hooks all of the windows API functions and watches them for "inappropriate" calls. Note, however, that you're going to run into a lot of false positives, so you need to not base your banning system on your automated data. Always have a human look over it before banning.

Jeff Hubbard
That's a good idea, especially if the tests can be seamlessly integrated into the gameplay
Vinko Vrsalovic
+1  A: 

I have no deeper understanding on how PunkBuster and such softwar works, but this is the way I'd go:

Iintercept calls to the API functions that handle the memory stuff like ReadProcessMemory, WriteProcessMemory and so on.

You'd detect if your process is involved in the call, log it, and trampoline the call back to the original function.

This should work for the screenshot taking too, but you might want to intercept the BitBlt function.

Here's a basic tutorial concerning the function interception: Intercepting System API Calls

arul
+6  A: 

I wrote d2botnet, a .net diablo 2 automation engine a while back, and something you can add to your list of things to watch out for are malformed /invalid/forged packets. I assume this game will communicate over TCP. Packet sniffing and forging are usually the first way games (online anyways) are automated. I know blizzard would detect malformed packets, somehting i tried to stay away from doing in d2botnet.

So make sure you detect invalid packets. Encrypt them. Hash them. do somethign to make sure they are valid. If you think about it, if someone can know exactly what every packet means that is sent back and forth they dont even need to run the client software, which then makes any process based detection a moot point. So you can also add in some sort of packet based challenge response that your cleint must know how to respond to.

mattlant
Importantly, you need to encrypt the first release. If you add encryption after the fact, it's already defeated as the attackers know what the data looks like and just have to figure out how you're transforming the packets. ...not that they couldn't reverse engineer the encryption with a debugger, but at least not having the data right there in the network stack will give you another measure of obfuscation.
dash-tom-bang
What about a disassembler and a debugger like ollydbg? This strikes me as security though obscurity.
Rook
+2  A: 

A common method of listening to keyboard and mouse input in an application is setting a windows hook using SetWindowsHookEx. Vendors usually try to protect their software during installation so that hacker won't automate and crack/find a serial for their application. Google the term: "Key Loggers"... Here's an article that describes the problem and methods to prevent it.

Yuval Peled