Decode web layout frame

I am trying to decode a websocket frame, but I am failing when it comes to decoding an extended payload. Here is what I have done so far:

char *in = data; char *buffer; unsigned int i; unsigned char mask[4]; unsigned int packet_length = 0; int rc; /* Expect a finished text frame. */ assert(in[0] == '\x81'); packet_length = ((unsigned char) in[1]) & 0x7f; mask[0] = in[2]; mask[1] = in[3]; mask[2] = in[4]; mask[3] = in[5]; if (packet_length <= 125) { **// This decoding works** /* Unmask the payload. */ for (i = 0; i < packet_length; i++) in[6 + i] ^= mask[i % 4]; rc = asprintf(&buffer, "%.*s", packet_length, in + 6); } else if (packet_length == 126) { **//This decosing does NOT work** /* Unmask the payload. */ for (i = 0; i < packet_length; i++) in[8 + i] ^= mask[i % 4]; rc = asprintf(&buffer, "%.*s", packet_length, in + 8); } 

What am I doing wrong? How to encode an extended payload?

+6
source share
2 answers

If packet_length is 126, the next 2 bytes give the length of the data to read.
If packet_length is 127, the next 8 bytes give the length of the data to read.
The mask is contained in the next 4 bytes (after length).
This message must be decrypted.

The data framing section of the specification has a useful illustration of this.

If you reorder your code to something like

  • Read package_length
  • Check for packet_length the value 126 or 127. If necessary, list the value length_length in the value 2/4 bytes.
  • Read the mask (4 bytes after the packet length, including any additional 2 or 8 bytes read for the step above).
  • Decrypt the message (everything after the mask).

then everything should work.

+5
source

The sticking point is at a payload of> 125 bytes.

The format is pretty simple, let's say you send ten a in JavaScript:

 ws.send("a".repeat(10)) 

Then the server will receive:

 bytes[16]=818a8258a610e339c771e339c771e339 
  • byte 0: 0x81 is just an indicator that the received message
  • byte 1: 0x8a is the length, subtracting 80 from it, 0x0A == 10
  • byte 2, 3, 4, 5: 4th byte key for decrypting the payload
  • rest: payload

But now let's say you send 126 a in JavaScript:

 ws.send("a".repeat(126)) 

Then the server will receive:

 bytes[134]=81fe007ee415f1e5857490848574908485749084857490848574908485749084857490848574908485749084857490848574908485749084857490848574908485749084857490848574908485749084857490848574908485749084857490848574908485749084857490848574908485749084857490848574908485749084857490848574 

If the payload length is> 125, then byte 1 will be 0xfe, the format will be changed to:

  • byte 0: 0x81 is just an indicator that the received message
  • byte 1: will be 0xfe
  • byte 2, 3: payload length as uint16 number
  • byte 4, 5, 6, 7: 4th byte key for decrypting the payload
  • rest: payload

Sample code in C #:

 List<byte[]> decodeWebsocketFrame(Byte[] bytes) { List<Byte[]> ret = new List<Byte[]>(); int offset = 0; while (offset + 6 < bytes.Length) { // format: 0==ascii/binary 1=length-0x80, byte 2,3,4,5=key, 6+len=message, repeat with offset for next... int len = bytes[offset + 1] - 0x80; if (len <= 125) { //String data = Encoding.UTF8.GetString(bytes); //Debug.Log("len=" + len + "bytes[" + bytes.Length + "]=" + ByteArrayToString(bytes) + " data[" + data.Length + "]=" + data); Debug.Log("len=" + len + " offset=" + offset); Byte[] key = new Byte[] { bytes[offset + 2], bytes[offset + 3], bytes[offset + 4], bytes[offset + 5] }; Byte[] decoded = new Byte[len]; for (int i = 0; i < len; i++) { int realPos = offset + 6 + i; decoded[i] = (Byte)(bytes[realPos] ^ key[i % 4]); } offset += 6 + len; ret.Add(decoded); } else { int a = bytes[offset + 2]; int b = bytes[offset + 3]; len = (a << 8) + b; //Debug.Log("Length of ws: " + len); Byte[] key = new Byte[] { bytes[offset + 4], bytes[offset + 5], bytes[offset + 6], bytes[offset + 7] }; Byte[] decoded = new Byte[len]; for (int i = 0; i < len; i++) { int realPos = offset + 8 + i; decoded[i] = (Byte)(bytes[realPos] ^ key[i % 4]); } offset += 8 + len; ret.Add(decoded); } } return ret; } 
+4
source

Source: https://habr.com/ru/post/907871/


All Articles