Secret messages
When I reviewed my code for the aberoth protocol messages, I noticed something interesting:
The command and message ids start at 0 and go up to 255 with almost each id having a meaning. I say 'almost' since there are 3 ids which can not be found in the client's code. So what's the deal with them? Are there more messages that have been removed from the aberoth clients? What do ids 0x0a, 0x0f and 0x11 do?
Let's assume that all of these ids have a meaning. In that case, the first thing to find out is wether they are messages or commands. However, finding that out is extremely difficult, if not impossible due to the behaviour of the server. If we send the ids as messages, there is no appearent effect. Maybe the server ignores messages with faulty ids, maybe they actually did something which is just not visible. Here is how to send the data to the server:
The second option is that the ids are commands. In this case, they have to be part of either the ONE_FRAME_WITH_INO, ONE_FRAME_NO_INFO or the USER_INPUT message. Since USER_INPUT is the only thing we can control, let's test that first.
But first, we have to get familiar with the way the server deals with weird messages: If the server encounters a message with an id that does not correspond to a message, the whole packet is ignored, with no (visible) side effects. However it's an entirely different story if the server receives a message with a valid id but invalid message contents, there are several things that can happen: First, if the packet is long enough that is contains a complete message, any additional data sent is ignored. However, if the server does not receive enough data to form a complete message, it just ragequits and immediately disconnects the misbehaving client. This phenomenon is really handy for finding out the length of the unknown commands.
First tests yield promising results: The server is absolutely ok with receiving 0x0a and 0x0f as part of the USER_INPUT message:
However, this is because the server appearenty ignores invalid bytes inside the USER_INPUT message. But there is still id 0x11, which the server actually rejected. Let's investigate that further. Under the assumption that 0x11 is in fact a valid command, we first need to determine the length of that command. To do that, we simply change the length by one byte every time and see wether the server disconnects us:
Intersting. Appearently, the server did receive the command successfully at length 3 onwards. Let's see what happens when we send something other then 0s:
And with that, the commands structure is already complete: first the constant 0x11, then two bytes specifying a length field, then some data of the given length. What is the purpose of this command? Well, I don't know yet. Maybe it was used at some point in time to send in-game commands? Maybe it is used to send logging or debugging information? In practice, I couldn't create any visible effects with this command.
Finally, since the command does obviously not have an official name, I propose to call it DATA_INPUT for the time being, since it ties in nicely with the (also unofficially named) KEYBOARD_INPUT and MOUSE_INPUT commands.
So can anyone figure out what this command is actually used for? Maybe it is even related to the two other unknown ids 0x0a and 0xff...
| Id | Name | Type |
| 0x00 | DRAW_FILLED_RECT_AT_Y_PLUS_ONE | Command |
| 0x01 | DRAW_FILLED_RECT_AT_BLOCK_XY | Command |
| 0x02 | DRAW_FILLED_RECT_AT_DY | Command |
| 0x03 | DRAW_FILLED_RECT_AT_X_PLUS_ONE | Command |
| 0x04 | DRAW_FILLED_RECT_AT_DX | Command |
| 0x05 | DRAW_FILLED_RECT_AT_XY | Command |
| 0x06 | SET_COLOR | Command |
| 0x07 | CACHE_CURRENT_COLOR | Command |
| 0x08 | SET_ON_SCREEN_TEXT | Command |
| 0x09 | MOVE_ON_SCREEN_TEXT | Command |
| 0x0a | ??? | ??? |
| 0x0b | PING_ID_BANDWIDTH_CHECK | Command (?) |
| 0x0c | ONE_FRAME_WITH_INFO | Message |
| 0x0d | FRAME_RECEIVED | Message |
| 0x0e | USER_INPUT (unofficial name) | Message |
| 0x0f | ??? | ??? |
| 0x10 | KEYBOARD_INPUT (unofficial name) | Command |
| 0x11 | ??? | ??? |
| 0x12 | DRAW_PIXEL | Command |
| 0x13 | MOUSE_INPUT (unofficial name) | Command |
| 0x14 | CREATE_WINDOW | Message |
| 0x15 | COPY_AREA | Command |
| 0x16 | CLIENT_STATUS | Message |
| 0x17 | ONE_FRAME_NO_INFO | Message |
| 0x18 | SUB_WINDOW | Command |
| 0x19 | SET_FILLED_RECT_SIZE | Command |
| 0x1a | USE_GLOBAL_RESOURCE | Command |
| 0x1b | DRAW_FILLED_RECT_AT_Y_PLUS_ONE_REPEAT | Command |
| 0x1c | SET_COLOR_BASED_ON_CACHE | Command |
| 0x1d | SET_COLOR_WITH_ALPHA | Command |
| 0x1e - 0xff | LOAD_COLOR (unofficial name) | Command |
The command and message ids start at 0 and go up to 255 with almost each id having a meaning. I say 'almost' since there are 3 ids which can not be found in the client's code. So what's the deal with them? Are there more messages that have been removed from the aberoth clients? What do ids 0x0a, 0x0f and 0x11 do?
Let's assume that all of these ids have a meaning. In that case, the first thing to find out is wether they are messages or commands. However, finding that out is extremely difficult, if not impossible due to the behaviour of the server. If we send the ids as messages, there is no appearent effect. Maybe the server ignores messages with faulty ids, maybe they actually did something which is just not visible. Here is how to send the data to the server:
#import incendium.client
#c=incendium.client.Client()
data1=b"\xff\x00\x01\x0a" #id 0x0a
data2=b"\xff\x00\x01\x0f" #id 0x0f
data3=b"\xff\x00\x01\xaa" #id 0xaa
c.conn_server.send(data1)
c.conn_server.send(data2)
c.conn_server.send(data3)
The second option is that the ids are commands. In this case, they have to be part of either the ONE_FRAME_WITH_INO, ONE_FRAME_NO_INFO or the USER_INPUT message. Since USER_INPUT is the only thing we can control, let's test that first.
But first, we have to get familiar with the way the server deals with weird messages: If the server encounters a message with an id that does not correspond to a message, the whole packet is ignored, with no (visible) side effects. However it's an entirely different story if the server receives a message with a valid id but invalid message contents, there are several things that can happen: First, if the packet is long enough that is contains a complete message, any additional data sent is ignored. However, if the server does not receive enough data to form a complete message, it just ragequits and immediately disconnects the misbehaving client. This phenomenon is really handy for finding out the length of the unknown commands.
First tests yield promising results: The server is absolutely ok with receiving 0x0a and 0x0f as part of the USER_INPUT message:
data1=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x0a" #id 0x0a
data2=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x0f" #id 0x0f
data3=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x00" #id 0x00
data4=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11" #id 0x11
c.conn_server.send(data1) #works!
c.conn_server.send(data2) #works!
c.conn_server.send(data3) #also works?
c.conn_server.send(data4) #does not work
However, this is because the server appearenty ignores invalid bytes inside the USER_INPUT message. But there is still id 0x11, which the server actually rejected. Let's investigate that further. Under the assumption that 0x11 is in fact a valid command, we first need to determine the length of that command. To do that, we simply change the length by one byte every time and see wether the server disconnects us:
data1=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11" #length 1
data2=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11\x00" #length 2
data3=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11\x00\x00" #length 3
data4=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11\x00\x00\x00" #length 4
c.conn_server.send(data1) #does not work
c.conn_server.send(data2) #does not work
c.conn_server.send(data3) #works!
c.conn_server.send(data4) #works!
data1=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11\x00\x00"
data2=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11\x00\x01"
data3=b"\xff\x00\x06\x0e\x01\x00\x00\x01\x11\x00\x01\x00"
c.conn_server.send(data1) #works!
c.conn_server.send(data2) #does not work
c.conn_server.send(data3) #works!
Now, this couldn't be more obvious: the two first bytes of the commands data are a 16-bit value that specifies the length of a data field!And with that, the commands structure is already complete: first the constant 0x11, then two bytes specifying a length field, then some data of the given length. What is the purpose of this command? Well, I don't know yet. Maybe it was used at some point in time to send in-game commands? Maybe it is used to send logging or debugging information? In practice, I couldn't create any visible effects with this command.
Finally, since the command does obviously not have an official name, I propose to call it DATA_INPUT for the time being, since it ties in nicely with the (also unofficially named) KEYBOARD_INPUT and MOUSE_INPUT commands.
So can anyone figure out what this command is actually used for? Maybe it is even related to the two other unknown ids 0x0a and 0xff...
Comments
Post a Comment