HelpNetwork Protocol

Posts 14 of 4 · Page 1 of 1
Network Protocol
Hello,
The past few days I have been looking over the forum and getting addicted to ROTMG and I've decided to work on a custom client. I've found quite a bit of resources, but the one thing I'm stuck on is the network protocol; I've found some resources but I cannot replicate the data given

Here's the protocol reverse:
Code:
(C) 2012 Anoos: 3

Reverse engineering the protocol the game Realm Of The Mad God. / Build ver. 123 (?) /

Server Address: ec2-176-34-240-11.eu-est-1.compute.amazonaws.com (176.34.240.11) / EuNorth /

The addresses of all servers (on May 8, 2012, ver. 123.0.0)
+ --------------- + --------------- + ----------------- ------------------------------------------ +
| Name | IP | hostname |
| --------------- + ----------------- + --------------- ------------------------------------------ +
| USWest | 50.18.113.133 | ec2-50-18-113-133.us-west-1.compute.amazonaws.com |
| USMidWest | 107.22.218.252 | ec2-107-22-218-252.compute-1.amazonaws.com |
| EUWest | 46.137.187.86 | ec2-46-137-187-86.eu-west-1.compute.amazonaws.com |
| USEast | 184.72.218.199 | ec2-184-72-218-199.compute-1.amazonaws.com |
| AsiaSouthEast | 46.137.247.5 | ec2-46-137-247-5.ap-southeast-1.compute.amazonaws.com |
| USSouth | 107.22.231.55 | ec2-107-22-231-55.compute-1.amazonaws.com |
| USSouthWest | 50.18.176.194 | ec2-50-18-176-194.us-west-1.compute.amazonaws.com |
| EUEast | 46.51.176.123 | ec2-46-51-176-123.eu-west-1.compute.amazonaws.com |
| EUNorth | 176.34.240.11 | ec2-176-34-240-11.eu-west-1.compute.amazonaws.com |
| EUSouthWest | 176.34.240.126 | ec2-176-34-240-126.eu-west-1.compute.amazonaws.com |
| EUWest2 | 46.137.143.87 | ec2-46-137-143-87.eu-west-1.compute.amazonaws.com |
| USEast3 | 50.19.47.160 | ec2-50-19-47-160.compute-1.amazonaws.com |
| USWest2 | 184.169.130.44 | ec2-184-169-130-44.us-west-1.compute.amazonaws.com |
| USMidWest2 | 174.129.56.145 | ec2-174-129-56-145.compute-1.amazonaws.com |
| USEast2 | 23.21.243.164 | ec2-23-21-243-164.compute-1.amazonaws.com |
| USNorthWest | 184.169.131.108 | ec2-184-169-131-108.us-west-1.compute.amazonaws.com |
| USSouth2 | 107.20.55.255 | ec2-107-20-55-255.compute-1.amazonaws.com |
| AsiaEast | 46.137.218.95 | ec2-46-137-218-95.ap-southeast-1.compute.amazonaws.com |
| USSouth3 | 204.236.195.161 | ec2-204-236-195-161.compute-1.amazonaws.com |
| EUSouth | 176.34.71.225 | ec2-176-34-71-225.eu-west-1.compute.amazonaws.com |
| EUNorth2 | 46.137.38.91 | ec2-46-137-38-91.eu-west-1.compute.amazonaws.com |
+ --------------- + --------------- + ----------------- ------------------------------------------ +

The client requests a file from the server crossdomain.xml (http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html)

Information on packages == ==
The format of the package:
[LENGTH] <ID> (DETAILS)
| 01020304 | 05 | 0xDATA |
awwa
Presentation:
int length # length includes 5 byte header (4 bytes in length, and one byte for the ID), hence the length of the data
*******************# == Length-5
ubyte id # ID package
Vector <byte> data # Data is encrypted RC4, uses two keys:
*******************# 311f80691451c71b09a13a2a6e -> Outgoing Data
*******************# 72c5583cafb6818995cbd74b80 <- Incoming stream

Package List ========= =======================
== Presented in order of how the developers ==
# Srv - server sends a packet
# Cli - client sends a packet
#?? - Purpose of the package is unknown


------- ------------ Format
ID NAME
type field
type2 field2
---------------------------
================================================

0 FAILURE # Srv, an error message
int errorID # ID errors
String errorDescription # description of the error

59 CREATE_SUCCESS # Srv, object creation was successful
int objectID # ID of the object
int charID # ID Team

49 CREATE # Cli, a game object
short objectType # ID object type

20 PLAYERSHOO T # Cli, shoot
int timestamp # Time shot
int bulletID # ID texture bullet
short containerType #???
Point startingPos # coordinates x, y the shooting
float angle # degree angle shot in the plane xOy

61 MOVE # Cli, player movement
int tickID # ID game timer tick (anti-spidhak?)
int time # Timestamp start of motion (anti-spidhak?)
Point newPosition # coordinates x, y destination
short recordsLength #???
Vector records #???

39 PLAYERTEXT # Cli, send a chat message
String message # UTF-8 string posts

7 TEXT # Srv, chat message
String name # name of the message sender (player or bot quest)
int objectID # ID of the object (?)
int numStars # The number of asterisks wound (by a class quests) player, who wrote the message
ubyte bubbleTime # time, how much it will hold a bubble message on the player (in seconds?)
String recipient # Name of the message recipient (for personal messages)
String text # Message
String cleanText # (formatted?) Text messages

21 SHOOT (_-u5, _-FL) # Srv, shot
ubyte bulletID # ID texture shot
int ownerID # ID "owner" of the shot
short containerType #???
Point startingPos # initial coordinates x, y shots
float angle # degree angle shot in the plane xOy
short damage # damage that will cause the bullet when hit

31 SHOOT # Srv, handling multiple shots at once
ubyte bulletID # ID texture shot
int ownerID # ID "owner" of the shot
short containerType #???
Point startingPos # initial coordinates x, y shots
float angle # degree angle shot in the plane xOy
short damage # damage that will cause the bullet when hit
# - Following is the list of shots, if there are bytes, then:
# Every next byte is the number of shots
# Next to him is a float angle that will be fired
Byte # If not, then the number of shots = 1, and angle = 0

38 DAMAGE # Srv, notification of the damage caused and the effects (blindness, weakness, slow, etc.)
int targetID # ID purposes
ubyte length # length of the list of effects
Vector effects # byte array, ID effects (blind, slow)
int damageAmount # How much damage inflicted
bool kill # Killed?
ubyte bulletID # ID bullet
int objectID # ID of the object (?)

5 UPDATE # Srv, renewal of the world (new chunks (tiles), objects (mobs players?) Drops (bags))
short length_tiles # list length tiles
Vector <_-MV> tiles # The block list for updates (you need to understand the structure of the object block)
short length_newObjs # length of the list newObjs
Vector <_-Oe> newObjs # list of objects to be updated (----- ^)
short drops_length # length of the list drops
Vector <int> drops # List of drops (id drops?)

14??

63 NOTIFICATI ON # Srv, notification
int objectID
String text # Text Alerts
int color # text color

57 NEW_TICK # Srv,?
int tickID
int tickTime # unix timestamp (?)
short length # Length of the following list
Vector <ObjectStatusData> statuses # List status (?)

65 INVSWAP # Cli, a permutation of items in the inventory
int time # timestamp permutation (for syncing?)
Point position # Location (coordinates x, y) permutation (for drops?)
Slot slotObject1 # source object slots (slots necessary to identify the data structure Slot)
Slot slotObject2 # The target slot (- ^)

58 USEITEM # Cli, use things (elixir, egg)
int time # timestamp of use (for timing?)
Slot slotObject # object slot
Point itemUsePos # The place where the object is used (for use pots at once out of the bag?)

77 SHOW_EFFECT # Srv, to show the effect of
ubyte effectType # type of effect (0-15)
int targetObjectID # ID purposes
Point pos1 #???
Point pos2 #???
int color # Color effect (?)

17 HELLO # Cli, login to the server package
String buildVersion # version Build # 123
Int gameID # ID game (?)
String guid # Login
String password # Password
String secret # secret
int keyTime #???
short keyLength # Key length (?)
Vector <byte> key # key
int? length # length of the array
An array of String utf8bytes # utf-8 bytes

# Login, password, and secret encrypted with the public key PEM.RSA
# The encrypted data is encoded Base64
# RSA public key is available and within the swf-file
# ----- BEGIN PUBLIC KEY ----- \ n


50 GOTO # Srv, pemereschenie object
int objectID # ID moving object
Point pos # kordinaty move

11 INVDROP # Cli, drop a thing of the slot
Slot slotObject # Data from the slot

75 INVRESULT # Srv, the result of actions with the inventory
int result # result code

4 RECONNECT # Srv, reconnect to the (different) server
String name
String host
int port
int gameID
int keyTime
short keyLength
Vector <byte> key

41 PING # Srv
int serial # serial number ping

27 PONG # Cli
int serial # serial number of the processing of PING, this package should be sent immediately after the PING

37 MAPINFO # Srv, the card information
int width # Map width (at the nexus 255)
int height # length card (at the nexus 255)
String name # name card (Nexus)
uint fp #???
int background # code background cards (2 - blue by default)
bool allowplayertp # Allow teleport players to each other (eg smoking in the castle Oryx)


34 LOAD # Cli, download cara
int charID # ID chara

3 PIC # Srv, loading images (bitmaps)
int height
int width
Vector <byte> byteArray # Data file picture size: (height * width) * 4

28 SETCONDITI ON # Cli, installation conditions (?)
byte conditionEffect # ID effect
float conditionDuration # The duration of the effect (second?)

23 TELEPORT # Cli, a request to teleport to the object
int objectID

45 USEPORTAL # Cli, use the portal (or the hatch in the dungeon)
int objectID

47 DEATH # Srv, notification of death
int accountID
int charID
String killedBy

68 BUY # Cli, a request for purchase (from a shop in Nexus)
int objectID

10 BUYRESULT # Srv, the result of purchase
int result # result code
String resultString # Message (an error or a successful purchase)

62 AOE # Srv, AOE (Area of ​​Effect) damage as a bomb jellyfish.
Point position # Position of the center
float radius # Radius effect
ushort damage # Damage Done
ushort origType # Damage type (?) probably bombs, ladders, etc. Khilki

19 GROUNDDAMA GE # Cli, drawing earth damage (blocks)
int time
Point position

18 PLAYERHIT # Cli, getting into the player
byte bulletID
int objectID

24 ENEMYHIT # Cli, hit the enemy
int time
byte bulletID
int targetID
bool kill

26 AOEACK # Cli
int time
Point position

64 SHOOTACK # Cli
int time

6 OTHERHIT # Cli
int time
byte bulletID
int objectID
int targetID

16 SQUAREHIT # Cli
int time
byte bulletID
int targetID

51 GOTOACK # Cli
int time

55 EDITACCOUN TLIST # Cli
int accountListID
bool add
int objectID

66 ACCOUNTLIS T # Srv
int id
short listLength
Vector <int> accountIDs

74 QUESTOBJID # Srv
int objectID

40 CHOOSENAME # Cli, name change
String name

67 NAMERESULT # Srv, the result of the name change
bool success
String errorText

76 CREATEGUIL D # Cli, creating a guild (clan)
String name # Name Clan

69 CREATEGUIL DRESULT # Srv, the result of making the guild (clan)
bool success
String errorText

8 GUILDREMOVE # Cli, removal of the guild (clan)
String name

22 GUILDINVIT E # Cli, invite to the guild
String name # name of the invited player

53 ALLYSHOOT # Srv, shots allies (other players)
ubyte bulletID
int ownerID
short containerType
float angle

48 REQUESTTRA DE # Cli, a request to trade a player
String name

36 TRADEREQUE STED # Srv, alert the player that want to trade with him
String name

9 TRADESTART # Srv, start trading
short myItemsLength # length of the list of things that I'm willing to trade
Vector <Slot> myItems # The list of things
String yourName # Name (whose?)
short yourItemsLength # length of the list of things
Vector <Slot> yourItems # The list of things

12 CHANGETRAD E # Cli, change trade, boolean list of selected slots
short offerLength # length of the list of marks
Vector <bool> offer # List marks true - a slot is selected, false - not selected

44 TRADECHANG ED # Srv, the player changed his proposal
short offerLength # length of the list of marks slots
Vector <bool> offer # List marks slots

15 ACCEPTTRAD E # Cli, to take trade
short myOfferLength
Vector <Slot> myOffer
short yourOfferLength
Vector <Slot> yourOffer

25 CANCELTRAD E # Cli, cancel trade
# The data is not passed

42 TRADEDONE # Srv, trade completed
int code # result code
String desription # Description

1 TRADEACCEPTED # Srv, trade adopted
short myOfferLength
Vector <Slot> myOffer
short yourOfferLength
Vector <Slot> yourOffer

46 CLIENTSTAT # Srv, stats Client Team
String name # Name stat
int value # value

30 CHECKCREDI TS # Cli, Captions, like pressing a button on the main menu Credits
# The data is not passed

33 ESCAPE # Cli, teleport to the Nexus
# The data is not passed

56 FILE # Srv, download the file from the server (?)
String name
int filesize
# The following array of 8-byte UTF-size filesize

35 INVITEDTOG UILD # Srv, warning that the player client was invited to the guild (clan)
int objectID # ID Guild
int charID # ID players invited to the guild

52 JOINGUILD # Cli, to accept the invitation to the guild
String guildName # Name Guild

60 CHANGEGUIL DRANK # Cli, change the rank player in the guild (guild for admins)
String name # Player Name
int guildRank # New Rank

13 PLAYSOUND # Srv, play a sound
int ownerID
ubyte soundID
I also checked it with sources of other custom clients that have been released and they have the same information, however when packet sniffing to verify the network information, the data seems incorrect

For example:
Packet sniffed:
cli->srv
Code:
00 00 00 0D 10 71 11 89 1D 08 50 E8 DA
Using the information above:
00 00 00 0D = 13 (there is 13 bytes in the above packet, but only 8 in the data)
10 = 16 (Square Hit)
71 11 89 1D 08 50 E8 DA decrypted = B3 06 5C 90 6F 55 F6 32
given the information the structure for square hits should contain an integer, a byte, and an integer, however there is only 8 bytes of data available

Another example:
cli->srv
Code:
00 00 00 23 07 5B AD 0E 0D BC C8 41 72 99 EA 77 7B FF B7 07 D1 B5 56 CC C4 3F F0 7E 5E 97 B8 FA 95 4A FC
Len: 35 (correct, but length of entire packet, not data)
ID: 7 (TEXT)

so first off TEXT commands are only srv->cli, however this was recorded cli->srv, but let's ignore that for now

DATA (decrypted):
Code:
99 BA DB 80 DB CD 5F 9A 99 67 58 D9 2C 5C 0B 70 D9 2A 41 F3 5E C6 1B BF 41 59 5D AF 4B 79
so for that there's no NUL terminator for the strings and there's no series of characters that makes any sense

so then I thought maybe the ID is included in the encryption, so adding to that starts off with a 106 as the ID which doesn't exist

I'm not exactly sure what is wrong, I was looking through the source of this: http://www.mpgh.net/forum/655-realm-...er-please.html
and from what I can tell it works the same way the protocol would suggest:
Code:
[File: ./rotmg java proxy/rotmgclient/src/client/base/GameConnection.java]
[Lines: 173-183]
private void writePacket(RWable rw) throws IOException {
		if (!dontPrint.contains(rw.getId()))
			System.out.println(rw);
		ByteArrayDataOutput bado = new ByteArrayDataOutput(100000);
		rw.writeToOutput(bado);
		byte[] encr = cipher_fromServer.rc4(bado.getArray());
		out.writeInt(encr.length + 5);
		out.writeByte(rw.getId());
		out.write(encr);
		out.flush();
	}
basically it gets the packet data, encrypts the data with rc4 and outputs to a new array (hmm 100,000 bytes seems a bit big ^^), writes the length of the encrypted data, writes the ID of the packet, and then writes the encrypted data, then flushes the stream, however sniffing packet data from the client (currently hexed modselector from here for simplicity) doesn't have information that matches with the protocol
After looking through the packets, the length and IDs are all valid (where length is the length of the packet, not the encrypted data), however the DATA information doesn't match with the protocol

I'm kinda stuck on this and can't continue until this is resolved, any help would be appreciated

TL;DR:
Sniffer data doesn't match up with the reversed protocol information
1. That information you have there is out-dated. You have to decompile or disassemble the client and get the up-to-date packet structures.
2. The readUTF methods of AS3 (what the game is using), reads pascal strings, not null terminated C strings. That means the first 2 bytes of the string data tells you the size of the string.
3. Don't be sure that 1 game packet = 1 physical packet, more than 1 packet can be sent at once for example. The only thing you can be sure is the size information of each game packet.
4. Your RC4 implementation is most likely wrong. Be sure you recalculate and store its state and indices after each packet. It you are writing a client you need 2 RC4 states, if you are writing a proxy you need 4 of these.
The method I am using is
Buffer all incoming packets into one buffer, basically a byte array or string
Each new packet received gets append to the end of the buffer
Buffer = Packet1+packet2+packet3

Then I take a Peek at the packet length and packet id,
The First 4 bytes in the buffer are alway the packet length
The 5 Byte in the buffer is alway the packet id

Next I check the buffer length is larger or equal to the packet length

Now I just slice and remove the packet from the buffer
And pass the slice to the read packet function

Where the first five bytes are read and removed from the slice, next I do the rc4 encryption and repeat
Ok great, thanks to both of you for the help, I found the updated packet protocol information and will release a thread about it shortly (i'll include the link here when I finish for anyone else who's having this problem, until then, check _-0GB)
Posts 14 of 4 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?