Signed Multiplayer Binaries


TrevorBradley

Active Member
Joined
Nov 6, 2007
Messages
732
Hey there. I need some collective developer brain to help me solve a problem that I can't wrap my brain around. I'm hoping it's already been thought of and a solution is waiting for me..

I've been working on my Multiplayer "hide and seek" game Galactic Artifact, things are going pretty well, but I've left the source closed for now. I have no problems releasing the source for a single player game. People can modify my game all they wish, make the Galaxy a pink elephant, whatever they wish. But for multiplayer, having the source available would make it exceptionally easy to cheat, as the victory condition is transmitted at game start. I could move much more of the game logic over to the server (and plan to if there isn't an easy solution), but it dramatically increases the amount of work I need to do, load on the server, and lag for the players as each and every action is checked by the server for legitimacy.

I've already encrypted by client-server traffic so that the client doesn't snoop and figure out more than he's allowed to.

Someone in the beta testing forum suggested signed binaries, but I just can't wrap my head around how you could ensure the client wasn't lying about their signature. If the code checked the CRC of the file it were run from, you could just modify that bit of code to look at the original binary. Heck at the moment someone with my code could create a telnet client that would win immediately.

I know no solution if it were out there would be perfect (legit games suffer from this problem and use invasive DRM to solve it without success), but has anyone thought of a solution to this problem before?

If there isn't a solution (as I suspect), I'll start looking into putting the burden of legitimate gameplay on the server.

Thanks in advance.
 
whatever you do against this, I imagine someone can always just build a client that's hacked, but reads from an original client.

There's really nothing you can do. Most big multiplayer games have to move everything they can to the server to avoid this.
 
well. I would solve this problem by ignoring it. Honestly. Look at wikipedia - it was all achieved by putting trust into random individuals from whole world. And it worked.

There's no fun when cheating. Games are meant to be fun, so only a small minority of people will cheat. And it won't be fun for them, so they will stop doing that.

There is a very little 'fun' to be lost for victims, because they will recognize sooner or later that someone was cheating, and will stop playing with them, it's that simple.

for everything there's a workaround. Even if the source code is closed. Just look at DRM fiasco. To the contrary PGP works quite well, thanks to the transparency. But in your case there's no solution. Even if you run a checksum during runtime, in the memory of the executable being run, and send it to server to verify... this transmission can be easily hijacked.

So just forget it.
 
Yeah, the problem is that you cannot trust whatever you give the client, signed or unsigned. Steam is a perfect example of this - it even checks your graphics drivers for legitimacy but the only thing that puts the hackers off is the fact that they don't get an immediate ban, so they have no way of knowing whether or not their hacks were detected without signing up for dozens of accounts and being careful about what hacks they try on what accounts etc. You still get Steam hacks, though.

If anything you send the client is untrusted, then you don't trust the client to do anything vital to the game. Even the "entirely server side with clients being dumb terminals" games suffer hacks - things like automated programs that send keypresses to the official client to collect gold in MMORPG's etc.

Basically, if you plan to make it very secure, you're going to have a REALLY tough time. If you plan to make it "secure enough", you'll have to be tolerant and fix any big hack you do get. If you don't plan to make it secure at all, you may lose players. It's all a trade-off.

OpenTTD, for instance, is an open-source, popular, networkable game where a hacker could easily make life hell and ruin 10-hour-long games for a dozen people. See what they use to do their client-side authentication - I think you'll find that the server does everything for every player and the client just sends packets that say "I'd like to do this". It's up to the server to work out what's valid and not. And that's quite a simple game with no "secret information" that the player mustn't find out about the other players (e.g. in the game you describe, you'd need to make sure that X never gets sent any information that reveals Y's location until they can legitimately see them in the game).

You still get people who run hacked clients every now and again but they are so in the minority, it's barely worth putting in the fixes.

Mathematically speaking, it's currently considered impossible to ensure the integrity of a piece of software which the other party has free reign upon. It might be extremely difficult to "hack" but you can never really trust the entity on the other end. This is the problem that's hit all forms of DRM (which is effectively what you are implementing here) - DVD, Blu-Ray, iTunes, TrustedComputing, HDMI, etc. If you can't be sure that people cannot view and insert random bytes into the memory of your program, then you can't be sure that the client is actually the one you gave them.

Think about it - we all know that SSL/SSH are "secure" and practically-speaking unbreakable (for a certain time / CPU tradeoff - normally 20+ years on a supercomputer will reduce anything to mush). However, if I give you a browser which I insist you have to use to connect to my SSL website, you can do anything - even make a copy of the browser that pretends to be the same but has extra features, automates some procedures etc. It won't be easy but it would be possible to "emulate" my browser perfectly but yet work completely differently. Even if you get smart and start encrypting, checksumming, etc. there are always ways around it if you can't control the content on my computer (and hence, this is why the TrustedComputing initiative want to check every part of your computer from the BIOS to the CPU to the disk to the software in order to ensure that the computer won't let you play - even that is hackable if you can emulate the TrustedComputing chips - tricky (and I don't *think* it's been done yet) but not impossible.

All SSL/SSH ensure are that the transit is secure (i.e. random people on the net can't sniff your bank details), not the endpoint. That's the best you can get.
 
cosurgi said:
well. I would solve this problem by ignoring it. Honestly. Look at wikipedia - it was all achieved by putting trust into random individuals from whole world. And it worked.

There's no fun when cheating. Games are meant to be fun, so only a small minority of people will cheat. And it won't be fun for them, so they will stop doing that.

There is a very little 'fun' to be lost for victims, because they will recognize sooner or later that someone was cheating, and will stop playing with them, it's that simple.

for everything there's a workaround. Even if the source code is closed. Just look at DRM fiasco. To the contrary PGP works quite well, thanks to the transparency. But in your case there's no solution. Even if you run a checksum during runtime, in the memory of the executable being run, and send it to server to verify... this transmission can be easily hijacked.

So just forget it.
Well, there's only one server at the moment, so that means I have to at least deal with the issue. :) It's too much fun for jerks to ruin everyone's fun when there's nowhere else for anyone else to go.

I'll be looking at moving all of these checks to the server, asking nicely that they not modify the client if connecting to the server, and then kicking/banning people for doing weird things.

A thought... I *could* put in a keycode into the game code (i.e.0x01234567) , then release the source code with a different keycode (0x00000000), and release binaries with the keycode compiled in. The keycode would form the basis of the client-server encryption. The source can then be released, but you can't recompile and connect to my server. But you can create your own server, connect to it, etc.

That *won't* stop people from hacking the game, but it will slow them down with a minimum of effort. The source code could then be open source, but people who downloaded and compiled (and potentially modified) the game would not able to connect to *my* server.

If people felt that was restrictive, they would be free to run their own servers with their own (potentially NULL) keycodes.

Open Source. Closed Binary.

It's just a thought, potentially a dumb/naive one, but it's better than anything I came up with last night.
 
Last edited by a moderator:
That could work, as long as it's not easy to find it within the binary using a hex dump tool.
Or to do some kind of debugging trick and find the code that way. Either way, it's sounds easy to do and fairly inconvenient to break.

You should also remember that if any one malicious user does get the key and re-compiles a hacked binary that passes authentication, anybody playing with that key could be playing on a hacked client.

Like I said, keep as much on the server as possible.
 
Trevor Bradley said:
A thought... I *could* put in a keycode into the game code (i.e.0x01234567) , then release the source code with a different keycode (0x00000000), and release binaries with the keycode compiled in.

Heh, it will be rather easy to find out what value was put in there. Just look at the binary in the right place :)
 
Last edited by a moderator:
lulzfish said:
That could work, as long as it's not easy to find it within the binary using a hex dump tool.
Or to do some kind of debugging trick and find the code that way. Either way, it's sounds easy to do and fairly inconvenient to break.

You should also remember that if any one malicious user does get the key and re-compiles a hacked binary that passes authentication, anybody playing with that key could be playing on a hacked client.

Like I said, keep as much on the server as possible.
Yup, I'm still planning to move as much to the server as is feasible (Artifact location, alien information), but not permission to perform an action that requires fast reaction time (Ship movement). Best to check for hacks server side after though rather that waiting for server acknowledgment if an action is permissible. Let the client cheat for at least a few seconds before they're kicked. :)
 
Last edited by a moderator:
Trevor Bradley said:
Yup, I'm still planning to move as much to the server as is feasible (Artifact location, alien information), but not permission to perform an action that requires fast reaction time (Ship movement). Best to check for hacks server side after though rather that waiting for server acknowledgment if an action is permissible. Let the client cheat for at least a few seconds before they're kicked. :)

Hmm, maybe you should move the cheaters to a different game entirely without them realizing it. Make the game really hard so they wonder why the cheats aren't even helping them.
 
Last edited by a moderator:
lulzfish said:
Don't give the cheaters any notification that you're onto them other than their sudden inability to win the game :D
yeah, that might work. If you somehow discover cheating, don't ban. Don't send any message. Just make the game impossibly difficult :)

for example, in the usual game, you can add a 1% chance that the winning artifact changes its place. For cheaters - make it 99% :)
 
Last edited by a moderator:
You may want to read through this thread that Eniko started, originally on licensing, though it turned into an anti-cheating/botting discussion. I think that the general rule is that you have to treat the game client as if it is the player itself; in other words, only tell the client what the player is allowed to know.

Although i will admit to being intrigued by your closed binary keycode combined with encrypted data streams, i can't believe it will hold up against crackers for very long. Also, this can only be done if all the code used to create that binary is your own or under a very permissive license; statically linking LGPL libraries wouldn't be allowed. (By the way, your current statically-linked binary with no released source is, i think, technically illegal; i doubt the libraries' creators would be too upset, but, you might want to shift back to complete dynamic linking soon or open source it and hope cheating during beta testing is minimal).

You should also note, if you haven't already, that if all the real gameplay work is done on the server, single player will be impossible unless server code is included with the client. Fortunately, though, having this included will make it that much easier to allow for unofficial servers, including servers used for ad-hoc local play. I know you've said you aren't making that a goal for now, but i'm sure some people would appreciate it.

I know reworking your entire server and client will be painful, but hopefully it'll lead to a better game in the future.
 
Last edited by a moderator:
The binary keycode is a wonderful idea in my opinion. However...

Instead of it being compiled as constant. Have it generated with a fairly complex algorithm at runtime that would be an absolute BITCH to try and decompile and understand. That way you can't get any go-happy hex editors finding your key code. Then in your opensource version remove this algorithm altogether and like you said give them a value of 0x000000 or something. Then, instead of just not letting unofficial copies not connect to your server and possibly hamper harmless mods, signify to other players that said person is using an unsigned binary. Depending on whether you have some kind of match making system people could use this to create games/rooms with options such as "signed binary's only" or they could allow people with unsigned binary's and just be cautious.

A big added plus to the programmatically determined keycode is that not only do you gain more protection but if someone does discover your algorithm its as simple as making a new one with increased complexity and issuing an update (possibly an automatic one if you implement that kind of feature).

I've actually had this idea many times before :p

Truth is you will never get perfect protection BUT you can make it an EXTREME pain in the ass to try and crack that most people will give up before they succede. That's the goal.
 
Using something like a pseudorandom number generator with a hardcoded seed would certainly be better than just the code. It would make hackers work a bit harder.

Again, I don't know much about debuggers, but I think it would still be possible to detect the code once it's been generated, like when you're passing it to an encryption function or something.

It still has the same problem that once somebody knows the key, they can use the source code to make a version that has it hardcoded and looks signed anyway. It's just a matter of how much time you have until it's broken.
 
Soulkiller said:
The binary keycode is a wonderful idea in my opinion. However...

Instead of it being compiled as constant. Have it generated with a fairly complex algorithm at runtime that would be an absolute BITCH to try and decompile and understand. That way you can't get any go-happy hex editors finding your key code. Then in your opensource version remove this algorithm altogether and like you said give them a value of 0x000000 or something. Then, instead of just not letting unofficial copies not connect to your server and possibly hamper harmless mods, signify to other players that said person is using an unsigned binary. Depending on whether you have some kind of match making system people could use this to create games/rooms with options such as "signed binary's only" or they could allow people with unsigned binary's and just be cautious.

A big added plus to the programmatically determined keycode is that not only do you gain more protection but if someone does discover your algorithm its as simple as making a new one with increased complexity and issuing an update (possibly an automatic one if you implement that kind of feature).

I've actually had this idea many times before :p

Truth is you will never get perfect protection BUT you can make it an EXTREME pain in the ass to try and crack that most people will give up before they succede. That's the goal.
Actually I was leaning towards this earlier today. Take my Crypto.cc file's "encryptMessage" and "decryptMessage" and have them return their input values. Then have my own method bodies here that are compiled into the server and into the clients.

As for those statically linked binaries, I've got to pull them soon. I had no idea of the requirements of static linking, but rather was trying to resolve a bunch of problems the Linux users were having with the dynamically compiled binaries (the Windows version is dynamically compiled but includes libs in the distribution, which aren't properly documented in the release.)

Let me say for the record that while I have screwed up here (a) it was not my intention to release a closed source static binary in violation of the GPL and that I've done so out of naivety, and (B) it's my intention now to open source the project as soon as possible and © this wasn't supposed to be a "release" per say but rather an "in house/community testing project" that got popular beyond my control to the point where the game has already been repackaged for redistribution in German. :|

The question is how rapidly do I need to address this problem considering there's no intent of malice... can it wait a week until my next release or should I drop everything and fix it now?
 
Last edited by a moderator:
Trevor Bradley said:
The question is how rapidly do I need to address this problem considering there's no intent of malice... can it wait a week until my next release or should I drop everything and fix it now?
Don't hurry. It's ok. To be exact: it is ok until someone comes complaining which is very unlikely, thanks to your positive attitude.
 
Last edited by a moderator:
Soulkiller said:
.... generated with a fairly complex algorithm at runtime that would be an absolute BITCH to try and decompile and understand.
I had an idea overnight how to mitigate the problem with people peeking into disassembler/debugger and spotting the number right after it is generated, then sending it everytime when asked to.

Make the number to be different each time.

This could take several inputs: a server sends a random number, the client processes it through the algorithm and sends back the answer. The number becomes a function of server's query. Now the only solution for a cheater is to disassemble the binary and copy/paste the function's assembler code into asm{} block in cpp in place of this function. it will be just a little bit more difficult, than just spotting the answer.

To go further - this function, among other stuff, could do following:

take the query from the server and xor it over the file on disk that was just executed (the binary executable). That would be fopen(argv[0]); and reading it - you know, argv[0] is the name of the executable being executed.

This way if you paste the assembly code for this function, the answer will still be wrong, since binary file will be different. So then, the cheater would have to modify this asm code, to open a different file, replacing argv[0] with the name of the original file...

And so on... funny stuff.

or people could take a totally diffent approach, like "adom sage" was written. Replace the libraries with their own ones. The libraries would do the same stuff as the original ones did, but also some extra stuff, that they shouldn't do.

this race of arms can go on forever. Depending on how much people want to participate in it, heh.
 
Last edited by a moderator:
Most likely none of the lib-devs are going to sue you. Even the FSF is usually quite relaxed when it comes to GPL-violations and tries to negotiate and get the sources released before suing anybody. If you plan to release a free and open version later on, nobody will care.
The ideas in this thread sound good to me. As others have pointed out there is no definitive answer to this problem, you can either be open or (more) secure. Some losers will try to cheat if the game becomes popular enough, you can just try to make it harder.
 
OK, here's my plan at the moment.

Release C of my game will be coming out this week. It will remain closed source, but all binaries will be dynamic and the GPL license clearly displayed for included SDL libraries.

In a subsequent release, hopefully Release D, I will be releasing the game source as follows:

There will be a single class, Crypto.cc, which will be released with the source but neutered. This class is entirely of my creation, is mathematical in nature and contains no SDL or GPL derived code.

The rest of the game source will be released as compiled in to the game.

The game will include (potentially) static binaries. These binaries will be compiled against my version of Crypto.

People who download the game will have the source, be able to compile the game, create their own servers and connect to them, but will not be able to play multiplayer on my server without the binary provided using the unneutered Crypto.

I'll also be running a beta server which can be connected to using the neutered Crypto, but will make no guarantees that nobody is cheating.

I'll also be cleaning up my code so that Crypto isn't needed, but I'll never be sure, so it's another layer of protection. It's quite possible at some later date I'll understand many of the ways the game could be hacked and publish my Crypto code.

Now, I think this is within the spirit of the GPL... I just want to ensure it's within the letter of the GPL as well. Will I legally be able to distribute a static binary that includes a non GPL derived and non GPL'ed code? If not, what about dynamic binaries?
 
Trevor Bradley said:
Will I legally be able to distribute a static binary that includes a non GPL derived and non GPL'ed code? If not, what about dynamic binaries?
As long as the binary is all your own code and only links to SDL and its LGPL'd friends, you should be in the clear legally.

I hope your Crypto experiment works out; it's an interesting idea. I only wish i knew enough CS to poke at it myself; i'm dying to figure out what could be wrong with this approach!

Anyways, keep up the good work.
 
Last edited by a moderator:
Back
Top