Tuesday, May 22, 2007

Reversing Drawball

I've spent some time lately trying to reverse-engineer the protocol for drawball.com. Granted, the client is in Flash, so in theory I could just decompile it and reverse it that way, but what fun is that?

Here's what I've found so far:

(All communication is in the form of null-terminated strings. The server listens on port 8007.)


Upon connecting, the client sends what seems to be an arbitrary 7-byte alpha (mixed upper and lower) string. One string can be reused a few times before a new one is required. I assume it's based on time somehow. For the time being, I've just been using Wireshark to retrieve the key generated and sent by the client. I need to spend more time on this one. I really need to figure out how this is generated, because it's a huge pain to open up the actual client and get a new key every time.
EDIT: Duh, got it. "View Source," idiot: <param name="FlashVars" value="l=myvalue">

The server responds with a 14-character string consisting of all uppercase letters.

The client responds with a 7-character string of printable ASCII characters. If the incorrect string is sent, the server disconnects. I figured out that the string is generated by taking each character of the first string sent by the client and subtracting the numeric value (0-25) of every other character in the server response. That's not a very clear explanation...will post the Perl function that performs this operation once I clean it up a bit.

EDIT: Here it is.

sub decode {
my @seed = split //, shift;
my @chal = split //, shift;
my $response;

while(@seed) {
# get the numeric (0-25) value of the next character of @chal
my $num = ord(shift @chal) - 65;
# throw away the next character of @chal
shift @chal;
# subtract $num from the next character of @seed, add to response
$response .= chr(ord(shift @seed) - $num);
return $response;


The client asks the server how much ink it has left by sending a lowercase "i". The server responds with the letter "i", and what appears to be a 4-byte integer. The first byte is always 01; I think it's just there to avoid having any nulls in the response, since communications are in the form of null-terminated strings.


To draw, the client sends a packet containing the following data:
  • ASCII "a" (0x61)
  • 0x1 (seems to be constant, not sure what it's for)
  • 0x1 (same)
  • a 1-byte sequence number, must start with 1 and increment with each transmission
  • 0x2 (constant, not sure)
  • color - 4-byte integer, don't know how it's being represented. black is 0x01010101, white is 0x09191908
  • a sequence of (x,y) coordinates where each coordinate is 3 bytes. the minimum number of coordinate pairs is 2, and the minimum line length is 2 pixels. this will draw a line between each coordinate.
I've successfully managed to automate drawing onto the ball, but I'm not going to be able to do anything really useful until I can figure out how the initial seed is generated.

Update: I may have been banned...I can load and navigate the site normally, and I seem to have a normal amount of ink, but any attempt to draw results in an immediate disconnection.

1 comment:

Anonymous said...

Oh, man! You really did it so far... I decompiled the flash itself and got all algorythms. The system which crypts and decrypts the packages is managed with "i2s" and "s2i" functions. And of course the cmd "i" is for asking about how much ink you have. But there's something bad: I think not the flash file but the server does the whole ink thing. And I got banned, too, but I'm a lucky guy - have got dynamic IP :P

So if you want to talk, ICQ: 430-167-969