Help with forging packets
My goal is to connect to the server using a tcp socket and creating the packets from my own program rather than using the clients packets like a proxy would, and I'm having trouble getting the HELLO packet to work.
I've gotten 2 responses from the server so far.
Seeing as I'm getting a proper response with the wrong build version("server.update_client" in plaintext after decryption), I can tell I've got the encrypting and decrypting down, and I can also tell my method used to write a string to the stream is working.
I'm not sure exactly what the problem is, but I think that it's an error in the rest of the information after the build version.
This is the order and data types I'm sending the packet data in. I copied these down from the decompiled client to make sure I had all the data types correct and in the right order.
For every string i'm writing a short containing the string length and then the string converted to bytes using this method
Similarly I'm writing ints, shorts, and bytes using these methods
These methods match those from K Relay and I'm fairly certain they are correct.
The data I'm using for the packet looks like this
My hunch is that I need to send a LOAD packet after the HELLO, but I figured the server would reply after a successful HELLO packet. I've read from this(Would post a link here but it won't let me) thread that you do need to send a series of packets to establish a connection(HELLO, LOAD, and MAPINFO). Will the server send a MAPINFO packet after a successful HELLO packet? If so I assume I need to respond with LOAD and choose my character if I get that back, correct?
If someone could explain the "chain of packets for logging in" in more detail I'll probably see where I'm going wrong. I thought it would be something along the lines of Client sends HELLO->Server responds with MAPINFO->Client responds with LOAD-> Client is now in game
Hopefully someone can see where I'm going wrong because I'm completely lost at the moment, and the info regarding this stuff is extremely limited.
I've gotten 2 responses from the server so far.
- I get back a response of length 31 with a packed ID of 0(FAILURE packet), error id of 0, and a description of "server.update_client" This only happens when I use the wrong build version(for example if I used "X12.0.0" instead of "X16.0.0")
- If I used the proper build version, the only thing I get back from the server is 0xff in the first byte of the header and everything following that is just 0x00. I'm assuming this means the server has refused my connection.
Seeing as I'm getting a proper response with the wrong build version("server.update_client" in plaintext after decryption), I can tell I've got the encrypting and decrypting down, and I can also tell my method used to write a string to the stream is working.
I'm not sure exactly what the problem is, but I think that it's an error in the rest of the information after the build version.
This is the order and data types I'm sending the packet data in. I copied these down from the decompiled client to make sure I had all the data types correct and in the right order.
Code:
//writeUTF and whatnot is how it's written in the client, I used this comment block to setup my packet and send the info in the same format the client is sending it. //Bascially where you see writeUTF that means I'm writing a string, writeInt means int, and so on. buildVersion_ writeUTF gameId_ writeInt guid_ writeUTF random1 writeInt password_ writeUTF random2 writeInt secret_ writeUTF keyTime_ writeInt key_ writeShort // length of key as short(2 bytes) key_ writeBytes // bytes of key mapJSON_ writeInt // length of mapJson as int(4 bytes) mapJSON_ writeUTFBytes // bytes of mapJson entrytag_ writeUTF gameNet writeUTF gameNetUserId writeUTF playPlatform writeUTF platformToken writeUTF userToken writeUTF
Code:
//Code is in C#
public void WriteUtf(string value)
{
byte[] data = Encoding.UTF8.GetBytes(value);
WriteShort((short)data.Length);
base.Write(data);
}
Code:
// base is a BinaryWriter
public void WriteInt(int value)
{
base.Write(IPAddress.NetworkToHostOrder(value));
}
public void WriteShort(short value)
{
base.Write(IPAddress.NetworkToHostOrder(value));
}
public void WriteByte(byte value)
{
base.Write(value); // write
}
The data I'm using for the packet looks like this
Code:
HelloPacket hello = new HelloPacket();
hello.BuildVersion = "X16.0.0";
hello.GameId = -2;
hello.GUID = email; // encrypted using rsa
hello.Password = pass;// encrypted using rsa
var r = new Random();
hello.Random1 = r.Next(0, 1000000000);
hello.Random2 = r.Next(0, 1000000000);
hello.Secret = "";
hello.KeyTime = -1;
hello.Key = new byte[0];
hello.MapJSON = new byte[0];
hello.EntryTag = "";
hello.GameNet = "rotmg";
hello.GameNetUserId = "";
hello.PlayPlatform = "rotmg";
hello.PlatformToken = "";
hello.UserToken = "";
//For Key I write the length as a short and then the bytes contained in the byte array after.
//For MapJSON i'm doing the same but rather than a short the length is an int(as that's how the client does it)
//Since both are empty byte arrays, they both will just write their length of 0 and then nothing else.
//From what I've been able to see from other public code it's sufficient to just give an empty byte array for these two attributes for connecting to the nexus.
My hunch is that I need to send a LOAD packet after the HELLO, but I figured the server would reply after a successful HELLO packet. I've read from this(Would post a link here but it won't let me) thread that you do need to send a series of packets to establish a connection(HELLO, LOAD, and MAPINFO). Will the server send a MAPINFO packet after a successful HELLO packet? If so I assume I need to respond with LOAD and choose my character if I get that back, correct?
If someone could explain the "chain of packets for logging in" in more detail I'll probably see where I'm going wrong. I thought it would be something along the lines of Client sends HELLO->Server responds with MAPINFO->Client responds with LOAD-> Client is now in game
Hopefully someone can see where I'm going wrong because I'm completely lost at the moment, and the info regarding this stuff is extremely limited.
