Server emulation, not something you hear about on a daily basis, but it is an essential part of some gaming communities. In the context of gaming, server emulators are in essence a reimplementation of an existing or previously existing game server by a third party. Server emulators are created and run with the intent of having a server that is not dependent upon a publishing company to maintain it. This means that when a company stops supporting a particular game server the game can still be enjoyed by players on the emulated server. Over the last year I have been involved with a project trying to create a server emulator for one of these unsupported games.
At a high level there are three problems to be solved in building a server emulator:
- Redirecting traffic from the original to the new server.
- Understanding the communication protocol.
- Understanding payloads.
Redirecting traffic is the easiest of the problems. On a console it is simply a matter of patching urls and IP addresses in the game binary and distributing the new binary to players. As this particular project was for a console, modifying and redistributing the game binary was not possible. What is possible on some consoles is run-time memory editing with cheat devices. This is only practical for small changes, such as changing an https call to http or changing a single domain. An easier and often more practical method is to create a custom Domain Name System that maps the game's requested domains away from their legitimate locations to a 3rd party controlled server. The players who want to use this alternative server would then only need to point their DNS to the custom one.
The real work starts with trying to reverse-engineer the communication between the game client and the game server. Ideally the original server would still be online when this work begins, allowing one to see responses that are known to be valid. Alternatively, capturing packets from the server and examining them once this stage is reached is another option. Having neither a legitimate server nor packet captures makes the work of reversing a very challenging task. The more data you have about valid responses the easier this is when trying to figure out the protocol in use, assuming it is not a well-known and standardized protocol.
In examining an unknown protocol the first thing to do is to see if data is changing in a predictable manner. Do most packets share some commonalities; perhaps they are all a specific size or contain a certain structure? The more data to compare against, the easier these patterns are to see. If there is seemingly no commonality, then encryption or some form of obfuscation may be in use. If you know certain pieces of data are being sent in the packet, it would be wise to determine how your input is changing the packet. If a minor change results in a drastically different packet, encryption is most likely in use and the encryption algorithm and key will need to be discovered or patched out.
Once any encryption or obfuscation has been removed, if any, one can start looking for protocol meta information. Often protocols will include some meta information about the data actually being sent. Payload size, command and state flags, checksums, and other things of similar nature. More often than not these will be the first bytes of the packet.
Once the protocol has been understood, one can start to comprehend the payloads being sent. For a game server this is normally going to be related to the game: player statistics, lobby information and the like. As with the protocol, being able to make small changes and examining how it effects the end result is immensely helpful - for example, changing a single byte and seeing how it is reflected in the resultant packet. Making big changes can also be useful in determining what data is in certain blocks of the payload. At this stage it is useful to know tricks to cause errors, knowing what does and does not cause errors. For this project it was determined that for most responses the value 0x00000000 should be the first 4 bytes of the payload anything else would be treated as an error. It would result in an error display, however, if the client was expecting that particular command flag. Abusing this fact once could send multiple command flags with the error response and determine which one would result in the error. This allowed us to determine what command flags were to be set for the response to a particular client request. Building a server emulator is largely about figuring out what information the client wants, after all, so this was the first step to that knowledge.
Without access to the usual debugging environment that can be used with control games, the task of figuring out responses is a tedious one; frustrating and sometimes difficult, but it is possible. In the absence of both a live server and packet logs from the live server it may be fruitful to examine the online mode of other games by the same publisher. If the publisher thought the online mode was good enough for one game, there is little reason why they wouldn't use a similar protocol for another game.