![]() |
|
Sponsored by:![]() |
![]() ![]() ![]() ![]() ![]() ![]() |
Search | Newsletter | Conference | Tech Jobs |
O'Reilly's Emerging Technology Conference: May 13-16, 2002 | ![]() |
![]() | ||||||||||||||||||||||||||||||||||||||||||
![]() |
![]() |
Developing the Battle.net Emulator BNETD Wen: What have you learned interesting technically about Battle.net through developing BNETD? Crittenden: Fortunately for us, they have a pretty nice network protocol. It consists of a fixed-sized header that contains the command to execute and the length of the remaining data for that command. This makes it very easy to add new command support to the server; you just need to figure out what the command is trying to do (start game, list games, log in, etc.) and then code appropriately. The protocol itself isn't encrypted at all, just individual packets within them (like a modified SHA-1 hash on the password). Just looking at a packet dump of a login provides great insight into how the protocol works -- it's fairly obvious. Combs: The protocol wasn't designed to be portable from the beginning. The packet structures are all Intel-sized, packed, and little-endian. That's not exactly bad, but I really suspect they were just send()ing and recv()ing raw structures. They also use things which we call "tags." They are a lot like the Macintosh resource types in that they appear to be strings, but they are always four characters and aren't NUL terminated. I suspect they are just constants stored in an integer since some compilers support an initialization syntax like:
Which is, of course, non-portable in several ways, and it ends up making the string look backwards if [you read it] a character at a time on little-endian systems. For example, the StarCraft client identifies itself as "RATS" ("STAR" backwards). We also found several of the more mysterious values the client sends are just copies of values from Windows, specifically the 64-bit timestamps on files and the language/locale information. Overcoming the Technical DifficultiesWen: Describe the biggest technical challenges you have dealt with in developing BNETD. Combs: The first big task was adding persistent storage for accounts. I wanted to make the storage easy to parse and edit with tools or by hand. I settled on a flat-file key, value format like such: "key"="value." Many people have criticized this decision (they would prefer a binary format and/or a database), but I believe it has been more beneficial than not. 64-bit timestamp values are used in several places. I had never seen them before, and I had a lot of difficulty writing a conversion routine that obtained the correct values down to the second. After writing a linear regression routine and feeding in a whole bunch of sample points (yes, I did need more than two since rounding was involved), I figured out the offset and slope. Probably the most daunting task was figuring out any part of the protocol that involved encryption. Thankfully, the server works without supporting any of those packet types. But that meant going without passwords on the player accounts. Not having passwords was OK for LAN parties and systems behind firewalls, but some people wanted to allow logins from the Internet. Once we implemented account profiles, it became even more important so that players couldn't destroy each other's ratings. Thankfully, the hash size was the same as SHA1 and [we were] sent an example hashing function. The hashed password was sent in the plain to the server where it was stored for later logins. We figured out that the login hash used the session key and a random value (actually a timestamp), plus that hashed password, and then hashed it again. The server performs the same operation and compares the results. It's not the greatest scheme (knowledge of single-hashed password is the same value as knowing the password), but it was good enough for a game server. There was some further complication because the hash is performed in an endian-dependent way and it doesn't use the standard initialization or padding. I spoke about the packet format a bit above. Even though it was very tempting to just import and export raw structures, we tried to do this in a portable way [and] mostly succeeded. I created a set of types and functions called
[These] are stored as arrays of unsigned chars as they would be seen "on the wire." However, we rely on the compiler not adding padding between these elements in the packet structures. We use gcc extensions to keep gcc from doing this, but everyone uses gcc. I don't know of any compiler that adds padding to arrays of unsigned chars, so we are safe until we run into that. These types are used to build up structures which match the packets sent and received by the server. There is a union of all these packet types, and a character array which allows the network code to read and write them without conversion. Crittenden: Their ladder support took quite a bit of time as well. They use an extended Elo rating system. This computes a probability to win, and then assigns points based upon that probability and the outcome of the game. The number of possible points decreases as a player advances. There are some pretty complicated formulas for calculating these probabilities, and as the number of players in a game increases, so does the complexity of the calculations. Ross worked a way to figure out the various permutations for 2-5 players, and we quickly added support for that. While the packets are fairly straightforward, there were endian issues to deal with, and fetching the data out of the packet was a bit tricky. Ross devised a clever system of function calls to fetch 1, 2, 4 or 8 bytes of data from the "packet" at a time, which made programming much simpler. We built upon this base and made a bunch of "helper" functions to fetch string contacts, integers, whatever. Wen: What other technical challenges do you anticipate will come up for BNETD? Crittenden: It appears that Blizzard is actively patching their games to not work on non-Battle.net servers. This is really a shame, and I doubt there is much on the server side we can do to prevent this. Combs: One area of BNETD which has never been completed is our server-interconnection protocol. This was originally designed to hook servers together into a kind of cluster. This is much more difficult to write than a stand-alone server, since it will involve locking and cache coherency. Currently, it allows sharing of games and channels, but there are some bugs. I suspect Blizzard will be moving toward more encryption and more heavily involved servers. Currently, most of the logic is on the client side. Moving things to the server allows Blizzard more control over the environment. Taking Legal Precautions
Wen: Do you have legal advice for others taking part in open source projects that deal with reverse engineering? Combs: The current environment is not just the fault of special interests. We, the citizens of the U.S., have allowed it to get to this point. We should make an effort to stay informed and get involved. Anyone implementing a clone or work-alike should remember the DMCA. Try to think of every possible way that any interested party might claim you are bypassing copy or access controls. If there is any question, you should contact the EFF. When reverse engineering, stick with 'exposed' interfaces and communications. If you decide you need to de-compile code or inspect others' implementations, it's best to talk with a lawyer so that proper 'clean room' techniques can be used. Wen: What other important legal lessons can you share? Combs: The first is to clearly and prominently state your goals and intentions on the front page of your site. Too many people made assumptions about our group. Most of the assumptions could have been easily dispelled. Let me list a few here: We are not a new group; we have been around since 1998. We do not encourage or condone piracy. [Editor's note: Unlike Battle.net, the BNETD server software does not check whether a game client connected to it is a legal or pirated copy.] We don't write hacks and/or cracks for use on our servers or on Battle.net. We don't modify any client-side executables or libraries. Another lesson is to get legal advice sooner rather than later. I learned that the DMCA is more than a theoretical problem. While reading about Eric Corley, Dmitry Sklyarov, and others, I didn't realize that I might be in a similar situation someday. Crittenden: We probably should have talked to a lawyer years ago to get an opinion on whether what we were doing was legal or not. I'm not sure how much it would have helped in this case. But it might have gotten us into a conversation with Blizzard much earlier, and perhaps in a less confrontational way. Howard Wen is a freelance writer who has contributed frequently to O'Reilly Network, and written for Salon.com, Playboy.com and Wired, among others. Return to the ONLamp.com. ![]()
|
![]() |
Sponsored by: ![]() ![]() |
![]() |
|
![]() ![]() ![]() |
|
![]() |
|
![]() |
|
Copyright © 2000-2002 O'Reilly & Associates, Inc. All Rights Reserved. All trademarks and registered trademarks appearing on the O'Reilly Network are the property of their respective owners. For problems or assistance with this site, email help@oreillynet.com |
![]() |