Jump to content
Arix

The protocol explained

Recommended Posts

Yet another big post :) Here I take a go at explaining the entire jagex protocol the 718 client uses. I was not able to identify EVERY operation code as thorough as others. I may not post this all at once as this is quite a big task. So while this is not complete please check back for updates regularly.

Introduction

The protocol is, when it comes to structure one of the most simple forms of a protocol. When I talk about a packet what I mean is a block of bytes that is considered a complete package according to the protocol specifications. Do not confuse "packet" with the TCP/IP Model specification where a packet is the naming of a block of data on the "Internet Layer". According to the TCP/IP Model our TCP data blocks are called segments or datagrams.

Anyways... that was some tough reading. Back to the easier stuff. The protocol's structure consists of a header and a body but I will get into that later.

In the client a protocol operation is defined with an id and a length. The following code is an example of a protocol operation declaration:

public static OutgoingPacket PING_PACKET = new OutgoingPacket(21, 0);


The constructor of OutgoingPacket requires two parameters; id and length. The id is the operation code. A unique id given to every operation.

In this example the packet is the PING operation that the client sends to the server. As you can see the required length of the packet is 0. This means that the actual content the packet contains is nothing. This packet is designed to test wether the server answers or not and does not carry any other function (like transferring information or executing commands (note these commands are not client commands like ::acommand)).

So what is the structure of a packet? The header contains the operation code (the unique packet id) encrypted with an ISAAC cypher (synchronous algorithm) and the body contains any data either fixed or variable length (depending which opcode) written in the protocol specified by jagex's OutputStream. These streams are used for every I/O operation done by the client. The streams differ from the regular java streams because of the numerous special types jagex has created (or implemented) in the protocol.

So here we have the basic setup of the protocol. Now we can divide the traffic into 2 sides.

  • Data going from the client to the server
  • Data going from the server to the client



So let's begin packet identification...

You will see that the packet length is sometimes -1 or -2. This means:

  • Length = -1 → The buffer will have a capacity of 260 bytes
  • Length = -2 → The buffer will have a capacity of 10 000 bytes



Packets: Client → Server

[TABLE="class: grid, width: 90%, align: center"]
[TR]
[TH]ID[/TH]
[TH]Length[/TH]
[TH]Body Structure
[/TH]
[TH]Description[/TH]
[/TR]
[TR]
[TD="align: center"]0
[/TD]
[TD="align: center"]-1
[/TD]
[TD="align: center"]Byte, String, Short, Byte, Long(*)
[/TD]
[TD]Quick Chat in a Private Message. The first byte is always 0 for an unsignificant reason. The longs are variable. There can be several longs. The longs are the ints from the clientscript (I guess the selected option in the quick chat). The 4th type indicates the length of the longs. It is calculated by subtracting the index of the buffer before the longs were written from the index of the buffer after the longs are written and the byte is then inserted into the buffer.
[/TD]
[/TR]
[TR]
[TD="align: center"]1
[/TD]
[TD="align: center"]-2
[/TD]
[TD="align: center"]Short
[/TD]
[TD]hold on guys i'm taking a break.
[/TD]
[/TR]
[/TABLE]

Share this post


Link to post
Share on other sites
[quote name='Arix']
You will see that the packet length is sometimes -1 or -2. This means:
[LIST]
[*]Length = -1 → The buffer will have a capacity of 260 bytes
[*]Length = -2 → The buffer will have a capacity of 10 000 bytes
[/LIST][/QUOTE]

Length -1 indicates byte packetheader which has a maximum length of 255 (unsigned byte).
Length -2 indicates short packetheader which has a maximum length of 65535 (unsigned short).

Share this post


Link to post
Share on other sites

Length -1 indicates byte packetheader which has a maximum length of 255 (unsigned byte).


Length -2 indicates short packetheader which has a maximum length of 65535 (unsigned short).


http://prntscr.com/56arsd ;I coming from the method that creates buffers with a given packet declaration

And I have JUnit tested it and the internal array of the buffer has a size of the numbers I specified. It seems safe to assume what -1 and -2 is when I look at that.

Perhaps you are right, I don't know. A packet that has -1 size does have only 1 byte header (would explain the 0)

Share this post


Link to post
Share on other sites

http://prntscr.com/56arsd ;I coming from the method that creates buffers with a given packet declaration



And I have JUnit tested it and the internal array of the buffer has a size of the numbers I specified. It seems safe to assume what -1 and -2 is when I look at that.

Perhaps you are right, I don't know. A packet that has -1 size does have only 1 byte header (would explain the 0)



I assume they did that because no packet exceeds 10000 bytes in length.

Share this post


Link to post
Share on other sites

I assume they did that because no packet exceeds 10000 bytes in length.


Are you sure that it also signifies wether a header is one ubyte or an ushort? If so I'll add it in there ;o

Share this post


Link to post
Share on other sites

Are you sure that it also signifies wether a header is one ubyte or an ushort? If so I'll add it in there ;o



Well ye that's just how the client sends data.
If packet length is -1 the client will write an extra byte after the opcode byte indicating the packet length (which can maximum be 255),
if the length is -2 the client will write an extra short after the opcode byte which gives room for a maximum of 65535 bytes (although your buffer is limited to 10 000 as you pointed out).
They do this for packets with changing size (for instance when writing a string you can send "lol" which is 3 bytes or "roar" which is 4 bytes).

Share this post


Link to post
Share on other sites
[quote name='Arix']Yet another big post :) Here I take a go at explaining the entire jagex protocol the 718 client uses. I was not able to identify EVERY operation code as thorough as others. I may not post this all at once as this is quite a big task. So while this is not complete please check back for updates regularly.

[SIZE=4][B]Introduction[/B][/SIZE]

The protocol is, when it comes to structure one of the most simple forms of a protocol. When I talk about a packet what I mean is a block of bytes that is considered a complete package according to the protocol specifications. Do not confuse "packet" with the TCP/IP Model specification where a packet is the naming of a block of data on the "Internet Layer". According to the TCP/IP Model our TCP data blocks are called segments or datagrams.

Anyways... that was some tough reading. Back to the easier stuff. The protocol's structure consists of a header and a body but I will get into that later.

In the client a protocol operation is defined with an id and a length. The following code is an example of a protocol operation declaration:
[code]
public static OutgoingPacket PING_PACKET = new OutgoingPacket(21, 0);
[/code]
The constructor of OutgoingPacket requires two parameters; id and length. The id is the operation code. A unique id given to every operation.

In this example the packet is the PING operation that the client sends to the server. As you can see the required length of the packet is 0. This means that the actual content the packet contains is nothing. This packet is designed to test wether the server answers or not and does not carry any other function (like transferring information or executing commands (note these commands are not client commands like ::acommand)).

So what is the structure of a packet? The header contains the operation code (the unique packet id) encrypted with an ISAAC cypher (synchronous algorithm) and the body contains any data either fixed or variable length (depending which opcode) written in the protocol specified by jagex's OutputStream. These streams are used for every I/O operation done by the client. The streams differ from the regular java streams because of the numerous special types jagex has created (or implemented) in the protocol.

So here we have the basic setup of the protocol. Now we can divide the traffic into 2 sides.
[LIST]
[*]Data going from the client to the server
[*]Data going from the server to the client
[/LIST]

So let's begin packet identification...

You will see that the packet length is sometimes -1 or -2. This means:
[LIST]
[*]Length = -1 → The buffer will have a capacity of 260 bytes
[*]Length = -2 → The buffer will have a capacity of 10 000 bytes
[/LIST]

[SIZE=4][B]Packets: Client → Server[/B][/SIZE]

[TABLE="class: grid, width: 90%, align: center"]
[TR]
[TH]ID[/TH]
[TH]Length[/TH]
[TH]Body Structure
[/TH]
[TH]Description[/TH]
[/TR]
[TR]
[TD="align: center"]0
[/TD]
[TD="align: center"]-1
[/TD]
[TD="align: center"]Byte, String, Short, Byte, Long(*)
[/TD]
[TD]Quick Chat in a Private Message. The first byte is always 0 for an unsignificant reason. The longs are variable. There can be several longs. The longs are the ints from the clientscript (I guess the selected option in the quick chat). The 4th type indicates the length of the longs. It is calculated by subtracting the index of the buffer before the longs were written from the index of the buffer after the longs are written and the byte is then inserted into the buffer.
[/TD]
[/TR]
[TR]
[TD="align: center"]1
[/TD]
[TD="align: center"]-2
[/TD]
[TD="align: center"]Short
[/TD]
[TD]hold on guys i'm taking a break.
[/TD]
[/TR]
[/TABLE][/QUOTE]

interesting to read and really well explained, would you fancy doing something like this on how reflection/injection works ? ^_^

Share this post


Link to post
Share on other sites
[quote name='officiallulzs3c']interesting to read and really well explained, would you fancy doing something like this on how reflection/injection works ? ^_^[/QUOTE]
Haha sure but I don't know if there's that much to explain. I can show the possibilities and some explanations but that's it...

Share this post


Link to post
Share on other sites
[quote name='Arix']Haha sure but I don't know if there's that much to explain. I can show the possibilities and some explanations but that's it...[/QUOTE]

there's a fair bit to explain, how you initialize reflection, how you would implement scripts, how reflection actually works, how injection actually works, etc

Share this post


Link to post
Share on other sites

Very nice explanation. You should of this it clear that this is the GameProtocol for OpCodes. (maybe make another thread on the loginprotocol and explain Jaggrab? and login types?) Overall very nice thread, good job.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×