Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Commit c46293d

Browse files
committed
better websocker unmask
1 parent 7cb42ed commit c46293d

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,22 +152,34 @@ private async Task onBeforeTunnelConnectRequest(object sender, TunnelConnectSess
152152
}
153153
}
154154

155+
private void WebSocket_DataSent(object sender, DataEventArgs e)
156+
{
157+
var args = (SessionEventArgs)sender;
158+
WebSocketDataSentReceived(args, e, true);
159+
}
160+
155161
private void WebSocket_DataReceived(object sender, DataEventArgs e)
156162
{
157163
var args = (SessionEventArgs)sender;
164+
WebSocketDataSentReceived(args, e, false);
165+
}
166+
167+
private void WebSocketDataSentReceived(SessionEventArgs args, DataEventArgs e, bool sent)
168+
{
169+
var color = sent ? ConsoleColor.Green : ConsoleColor.Blue;
158170

159171
foreach (var frame in args.WebSocketDecoder.Decode(e.Buffer, e.Offset, e.Count))
160172
{
161173
if (frame.OpCode == WebsocketOpCode.Binary)
162174
{
163175
var data = frame.Data.ToArray();
164176
string str = string.Join(",", data.ToArray().Select(x => x.ToString("X2")));
165-
writeToConsole(str, ConsoleColor.Blue).Wait();
177+
writeToConsole(str, color).Wait();
166178
}
167179

168180
if (frame.OpCode == WebsocketOpCode.Text)
169181
{
170-
writeToConsole(frame.GetText(), ConsoleColor.Blue).Wait();
182+
writeToConsole(frame.GetText(), color).Wait();
171183
}
172184
}
173185
}
@@ -233,6 +245,7 @@ private async Task onResponse(object sender, SessionEventArgs e)
233245
{
234246
if (e.HttpClient.ConnectRequest?.TunnelType == TunnelType.Websocket)
235247
{
248+
e.DataSent += WebSocket_DataSent;
236249
e.DataReceived += WebSocket_DataReceived;
237250
}
238251

src/Titanium.Web.Proxy/WebSocketDecoder.cs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Runtime.InteropServices;
45
using Titanium.Web.Proxy.StreamExtended.BufferPool;
56

67
namespace Titanium.Web.Proxy
@@ -60,25 +61,51 @@ public IEnumerable<WebSocketFrame> Decode(byte[] data, int offset, int count)
6061
}
6162
}
6263

63-
uint mask = 0;
64-
if (masked)
64+
if (size < 0)
6565
{
66-
//mask = (uint)(((long)data1[idx++] << 24) + (data1[idx++] << 16) + (data1[idx++] << 8) + data1[idx++]);
67-
mask = (uint)(data1[idx++] + (data1[idx++] << 8) + (data1[idx++] << 16) + ((long)data1[idx++] << 24));
66+
;
67+
}
68+
69+
if (data1.Length < idx + size)
70+
{
71+
break;
6872
}
6973

7074
if (masked)
7175
{
72-
uint m = mask;
73-
for (int i = 0; i < size; i++)
74-
{
75-
data[i + idx] = (byte)(data1[i + idx] ^ (byte)mask);
76+
//mask = (uint)(((long)data1[idx++] << 24) + (data1[idx++] << 16) + (data1[idx++] << 8) + data1[idx++]);
77+
//mask = (uint)(data1[idx++] + (data1[idx++] << 8) + (data1[idx++] << 16) + ((long)data1[idx++] << 24));
78+
var uData = MemoryMarshal.Cast<byte, uint>(data1.Slice(idx, (int)size + 4));
79+
idx += 4;
7680

77-
m >>= 8;
81+
uint mask = uData[0];
82+
long size1 = size;
83+
if (size > 4)
84+
{
85+
uData = uData.Slice(1);
86+
for (int i = 0; i < uData.Length; i++)
87+
{
88+
uData[i] = uData[i] ^ mask;
89+
}
7890

79-
if (m == 0)
80-
m = mask;
91+
size1 -= uData.Length * 4;
8192
}
93+
94+
if (size1 > 0)
95+
{
96+
int pos = (int)(idx + size - size1);
97+
data1[pos] ^= (byte)mask;
98+
99+
if (size1 > 1)
100+
{
101+
data1[pos + 1] ^= (byte)(mask >> 8);
102+
}
103+
104+
if (size1 > 2)
105+
{
106+
data1[pos + 2] ^= (byte)(mask >> 16);
107+
}
108+
; }
82109
}
83110

84111
var frameData = buffer.Slice(idx, (int)size);

0 commit comments

Comments
 (0)