From 5f2dd3f032963c830e39a023575d90f08bf471a2 Mon Sep 17 00:00:00 2001 From: yvbbrjdr Date: Thu, 27 Jul 2017 16:03:23 +0800 Subject: [PATCH] 1.0 --- .gitignore | 6 + DotfuscatorAttribute.cs | 32 ++ Properties/AssemblyInfo.cs | 21 + README.md | 5 +- a.cs | 344 ++++++++++++++ b.cs | 433 ++++++++++++++++++ c.cs | 401 ++++++++++++++++ d.cs | 317 +++++++++++++ e.cs | 19 + f.cs | 137 ++++++ g.cs | 185 ++++++++ h.cs | 44 ++ socks5.Controller/Analyzer.cs | 82 ++++ socks5.Controller/CallbackState.cs | 15 + socks5.Controller/IHandler.cs | 11 + socks5.Controller/LogLevel.cs | 13 + socks5.Controller/Logging.cs | 249 ++++++++++ socks5.Controller/ProxySocketTun.cs | 391 ++++++++++++++++ socks5.Controller/ProxySocketTunLocal.cs | 52 +++ .../StreamWriterWithTimestamp.cs | 27 ++ socks5.Model/Configuration.cs | 18 + socks5.Model/LRUCache.cs | 160 +++++++ socks5.csproj | 53 +++ 23 files changed, 3014 insertions(+), 1 deletion(-) create mode 100644 DotfuscatorAttribute.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 a.cs create mode 100644 b.cs create mode 100644 c.cs create mode 100644 d.cs create mode 100644 e.cs create mode 100644 f.cs create mode 100644 g.cs create mode 100644 h.cs create mode 100644 socks5.Controller/Analyzer.cs create mode 100644 socks5.Controller/CallbackState.cs create mode 100644 socks5.Controller/IHandler.cs create mode 100644 socks5.Controller/LogLevel.cs create mode 100644 socks5.Controller/Logging.cs create mode 100644 socks5.Controller/ProxySocketTun.cs create mode 100644 socks5.Controller/ProxySocketTunLocal.cs create mode 100644 socks5.Controller/StreamWriterWithTimestamp.cs create mode 100644 socks5.Model/Configuration.cs create mode 100644 socks5.Model/LRUCache.cs create mode 100644 socks5.csproj diff --git a/.gitignore b/.gitignore index 940794e..1e2ef04 100644 --- a/.gitignore +++ b/.gitignore @@ -286,3 +286,9 @@ __pycache__/ *.btm.cs *.odx.cs *.xsd.cs + +# macOS auto-generated file +.DS_Store + +# VS Code files +.vscode/ diff --git a/DotfuscatorAttribute.cs b/DotfuscatorAttribute.cs new file mode 100644 index 0000000..cc0f60f --- /dev/null +++ b/DotfuscatorAttribute.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.InteropServices; + +[AttributeUsage(AttributeTargets.Assembly), ComVisible(false)] +public sealed class DotfuscatorAttribute : Attribute +{ + private string a; + + private int c; + + public string A + { + get + { + return this.a; + } + } + + public int C + { + get + { + return this.c; + } + } + + public DotfuscatorAttribute(string a, int c) + { + this.a = a; + this.c = c; + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d1cd3bc --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,21 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: Dotfuscator("000:0:0:5.5.4521.29298", 0)] +[assembly: AssemblyCompany("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyProduct("socks5")] +[assembly: AssemblyTitle("socks5")] +[assembly: AssemblyTrademark("")] +[assembly: CompilationRelaxations(8)] +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: ComVisible(false)] +[assembly: Guid("9a9d914e-8de4-4f84-b38e-67ed719319fa")] +[assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] diff --git a/README.md b/README.md index ac9e6d0..4b6471e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # ssr868 -Decompiled code (by ILSpy) of breakwa11's passive Shadowsocks detector. + +Decompiled code (by ILSpy) of [breakwa11's passive Shadowsocks detector](https://github.com/breakwa11/shadowsocks-rss/issues/868). + +The code is generated by [ILSpy 2.4](http://ilspy.net/). I haven't yet tried to compile it, so it is just for reference. diff --git a/a.cs b/a.cs new file mode 100644 index 0000000..3c03149 --- /dev/null +++ b/a.cs @@ -0,0 +1,344 @@ +using socks5.Model; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Cryptography; + +internal class a +{ + private delegate IPHostEntry b(string A_0); + + public enum a + { + a = 117, + b + } + + private static LRUCache a = new LRUCache(3600); + + private static Process b = Process.GetCurrentProcess(); + + public static LRUCache d() + { + return global::a.a; + } + + public static void c() + { + GC.Collect(GC.MaxGeneration); + GC.WaitForPendingFinalizers(); + if (UIntPtr.Size == 4) + { + global::a.SetProcessWorkingSetSize(global::a.b.Handle, (UIntPtr)4294967295u, (UIntPtr)4294967295u); + return; + } + if (UIntPtr.Size == 8) + { + global::a.SetProcessWorkingSetSize(global::a.b.Handle, (UIntPtr)18446744073709551615uL, (UIntPtr)18446744073709551615uL); + } + } + + public static void a(byte[] A_0, int A_1) + { + byte[] array = new byte[A_1]; + new RNGCryptoServiceProvider().GetBytes(array); + array.CopyTo(A_0, 0); + } + + public static uint b() + { + byte[] array = new byte[4]; + new RNGCryptoServiceProvider().GetBytes(array); + return BitConverter.ToUInt32(array, 0); + } + + public static void a(IList A_0, Random A_1) + { + int i = A_0.Count; + while (i > 1) + { + int index = A_1.Next(i); + i--; + a value = A_0[index]; + A_0[index] = A_0[i]; + A_0[i] = value; + } + } + + public static bool a(byte[] A_0, int A_1, byte[] A_2, int A_3, int A_4) + { + for (int i = 0; i < A_4; i++) + { + if (A_0[A_1 + i] != A_2[A_3 + i]) + { + return false; + } + } + return true; + } + + public static int a(byte[] A_0, int A_1, byte[] A_2) + { + if (A_2.Length != 0 && A_1 >= A_2.Length) + { + for (int i = 0; i <= A_1 - A_2.Length; i++) + { + if (A_0[i] == A_2[0]) + { + int num = 1; + while (num < A_2.Length && A_0[i + num] == A_2[num]) + { + num++; + } + if (num >= A_2.Length) + { + return i; + } + } + } + } + return -1; + } + + public static bool a(IPAddress A_0, IPAddress A_1, int A_2) + { + byte[] addressBytes = A_0.GetAddressBytes(); + byte[] addressBytes2 = A_1.GetAddressBytes(); + int i = 8; + int num = 0; + while (i < A_2) + { + if (addressBytes[num] != addressBytes2[num]) + { + return false; + } + i += 8; + num++; + } + return addressBytes[num] >> i - A_2 == addressBytes2[num] >> i - A_2; + } + + public static bool a(IPAddress A_0, string A_1) + { + string[] array = A_1.Split(new char[] + { + '/' + }); + IPAddress iPAddress = IPAddress.Parse(array[0]); + if (A_0.AddressFamily == iPAddress.AddressFamily) + { + try + { + bool result = global::a.a(A_0, iPAddress, (int)Convert.ToInt16(array[1])); + return result; + } + catch + { + bool result = false; + return result; + } + return false; + } + return false; + } + + public static bool b(IPAddress A_0) + { + byte[] addressBytes = A_0.GetAddressBytes(); + if (addressBytes.Length == 4) + { + string[] array = new string[] + { + "127.0.0.0/8", + "169.254.0.0/16" + }; + for (int i = 0; i < array.Length; i++) + { + string a_ = array[i]; + if (global::a.a(A_0, a_)) + { + return true; + } + } + return false; + } + if (addressBytes.Length == 16) + { + string[] array = new string[] + { + "::1/128" + }; + for (int i = 0; i < array.Length; i++) + { + string a_2 = array[i]; + if (global::a.a(A_0, a_2)) + { + return true; + } + } + return false; + } + return true; + } + + public static bool b(Socket A_0) + { + return global::a.b(((IPEndPoint)A_0.RemoteEndPoint).Address); + } + + public static bool a(IPAddress A_0) + { + byte[] addressBytes = A_0.GetAddressBytes(); + if (addressBytes.Length == 4) + { + if (A_0.Equals(new IPAddress(0L))) + { + return false; + } + string[] array = new string[] + { + "0.0.0.0/8", + "10.0.0.0/8", + "127.0.0.0/8", + "169.254.0.0/16", + "172.16.0.0/12", + "192.168.0.0/16" + }; + for (int i = 0; i < array.Length; i++) + { + string a_ = array[i]; + if (global::a.a(A_0, a_)) + { + return true; + } + } + return false; + } + else + { + if (addressBytes.Length == 16) + { + string[] array = new string[] + { + "::1/128", + "fc00::/7", + "fe80::/10" + }; + for (int i = 0; i < array.Length; i++) + { + string a_2 = array[i]; + if (global::a.a(A_0, a_2)) + { + return true; + } + } + return false; + } + return true; + } + } + + public static bool a(Socket A_0) + { + return global::a.a(((IPEndPoint)A_0.RemoteEndPoint).Address); + } + + public static string a(DateTime A_0) + { + return A_0.ToString("yyyyMMddHHmmssffff"); + } + + public static string a(string A_0) + { + string text = ""; + for (int i = 0; i < A_0.Length; i++) + { + if (A_0[i] == '%' && i < A_0.Length - 2) + { + string arg_34_0 = A_0.Substring(i + 1, 2).ToLower(); + int num = 0; + char c = arg_34_0[0]; + char c2 = arg_34_0[1]; + num += (int)((c < 'a') ? (c - '0') : ('\n' + (c - 'a'))); + num *= 16; + num += (int)((c2 < 'a') ? (c2 - '0') : ('\n' + (c2 - 'a'))); + text += ((char)num).ToString(); + i += 2; + } + else if (A_0[i] == '+') + { + text += " "; + } + else + { + text += A_0[i].ToString(); + } + } + return text; + } + + public static void b(ref a[] A_0, int A_1) + { + if (A_1 > A_0.Length) + { + Array.Resize(ref A_0, A_1); + } + } + + public static void a(ref a[] A_0, int A_1) + { + if (A_1 > A_0.Length) + { + Array.Resize(ref A_0, A_1 * 2); + } + } + + public static IPAddress a(string A_0, string A_1, bool A_2 = false) + { + IPAddress result = null; + try + { + global::a.b b = new global::a.b(Dns.GetHostEntry); + IAsyncResult asyncResult = b.BeginInvoke(A_0, null, null); + if (asyncResult.AsyncWaitHandle.WaitOne(10000, true)) + { + IPHostEntry iPHostEntry = b.EndInvoke(asyncResult); + IPAddress[] addressList = iPHostEntry.AddressList; + int i; + for (i = 0; i < addressList.Length; i++) + { + IPAddress iPAddress = addressList[i]; + if (iPAddress.AddressFamily == AddressFamily.InterNetwork) + { + IPAddress result2 = iPAddress; + return result2; + } + } + addressList = iPHostEntry.AddressList; + i = 0; + if (i < addressList.Length) + { + IPAddress result2 = addressList[i]; + return result2; + } + } + } + catch + { + } + return result; + } + + public static string a() + { + return Assembly.GetExecutingAssembly().Location; + } + + [DllImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool SetProcessWorkingSetSize(IntPtr A_0, UIntPtr A_1, UIntPtr A_2); +} diff --git a/b.cs b/b.cs new file mode 100644 index 0000000..696866c --- /dev/null +++ b/b.cs @@ -0,0 +1,433 @@ +using socks5.Controller; +using socks5.Model; +using System; +using System.Net; +using System.Net.Sockets; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; +using System.Timers; + +internal class b +{ + private class a : IHandler + { + private Configuration a; + + private byte[] b; + + private int c; + + private ProxySocketTunLocal d; + + private ProxySocketTun e; + + private bool f; + + private bool g; + + private string h; + + private int i; + + public const int j = 11680; + + private byte[] k = new byte[11680]; + + private byte[] l = new byte[11680]; + + private int m; + + protected int n = 600; + + protected System.Timers.Timer o; + + protected object p = new object(); + + protected DateTime q; + + public void a(Configuration A_0, byte[] A_1, int A_2, Socket A_3, string A_4, bool A_5) + { + this.b = A_1; + this.c = A_2; + this.d = new ProxySocketTunLocal(A_3); + this.d.local_sendback_protocol = A_4; + this.a = A_0; + this.g = A_5; + this.d(); + } + + private void d() + { + try + { + IPAddress iPAddress = null; + int port = 0; + if (this.b[0] == 1) + { + byte[] array = new byte[4]; + Array.Copy(this.b, 1, array, 0, array.Length); + iPAddress = new IPAddress(array); + port = ((int)this.b[5] << 8 | (int)this.b[6]); + this.h = iPAddress.ToString(); + } + else if (this.b[0] == 4) + { + byte[] array2 = new byte[16]; + Array.Copy(this.b, 1, array2, 0, array2.Length); + iPAddress = new IPAddress(array2); + port = ((int)this.b[17] << 8 | (int)this.b[18]); + this.h = iPAddress.ToString(); + } + else if (this.b[0] == 3) + { + int num = (int)this.b[1]; + byte[] array3 = new byte[num]; + Array.Copy(this.b, 2, array3, 0, array3.Length); + this.h = Encoding.UTF8.GetString(this.b, 2, num); + port = ((int)this.b[num + 2] << 8 | (int)this.b[num + 3]); + if (!IPAddress.TryParse(this.h, out iPAddress) && iPAddress == null) + { + iPAddress = global::a.d().Get(this.h); + } + if (iPAddress == null) + { + iPAddress = global::a.a(this.h, null, false); + } + if (iPAddress != null) + { + global::a.d().Set(this.h, new IPAddress(iPAddress.GetAddressBytes())); + global::a.d().Sweep(); + } + else if (!this.g) + { + throw new SocketException(11001); + } + } + this.i = port; + IPEndPoint ep = new IPEndPoint(iPAddress, port); + this.e = new ProxySocketTun(iPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + this.e.GetSocket().NoDelay = true; + this.e.BeginConnect(ep, new AsyncCallback(this.c), null); + } + catch (Exception arg_1D1_0) + { + Logging.LogUsefulException(arg_1D1_0); + this.e(); + } + } + + private bool a(string A_0, int A_1) + { + return true; + } + + private void c(IAsyncResult A_0) + { + if (this.f) + { + return; + } + try + { + this.e.EndConnect(A_0); + if (this.g && !this.a(this.h, this.i)) + { + throw new SocketException(10054); + } + this.c(); + } + catch (Exception arg_45_0) + { + Logging.LogUsefulException(arg_45_0); + this.e(); + } + } + + private void a(double A_0) + { + if (A_0 <= 0.0 && this.o == null) + { + return; + } + if (A_0 <= 0.0) + { + if (this.o == null) + { + return; + } + object obj = this.p; + lock (obj) + { + if (this.o != null) + { + this.o.Enabled = false; + this.o.Elapsed -= new ElapsedEventHandler(this.a); + this.o.Dispose(); + this.o = null; + } + return; + } + } + DateTime arg_8F_0 = this.q; + if ((DateTime.Now - this.q).TotalMilliseconds > 500.0) + { + object obj = this.p; + lock (obj) + { + if (this.o == null) + { + this.o = new System.Timers.Timer(A_0 * 1000.0); + this.o.Elapsed += new ElapsedEventHandler(this.a); + } + else + { + this.o.Interval = A_0 * 1000.0; + this.o.Stop(); + } + this.o.Start(); + this.q = DateTime.Now; + } + } + } + + private void a(object A_0, ElapsedEventArgs A_1) + { + if (this.f) + { + return; + } + this.e(); + } + + private void c() + { + if (this.f) + { + return; + } + try + { + this.e.BeginReceive(this.k, 11680, SocketFlags.None, new AsyncCallback(this.b), null); + this.d.BeginReceive(this.l, 11680, SocketFlags.None, new AsyncCallback(this.a), null); + this.d.Send(this.l, 0, SocketFlags.None); + this.a((double)this.n); + } + catch (Exception arg_77_0) + { + Logging.LogUsefulException(arg_77_0); + this.e(); + } + } + + private void b(IAsyncResult A_0) + { + if (this.f) + { + return; + } + try + { + int num = this.e.EndReceive(A_0); + if (num > 0) + { + this.a((double)this.n); + this.d.Send(this.k, num, SocketFlags.None); + if (Analyzer.instance().Add(this.h, this.i, this.e, this.k, num, true)) + { + Analyzer.instance().Close(this.h, this.i, this.e); + } + this.m += num; + if (this.m <= 2097152) + { + this.e.BeginReceive(this.k, 11680, SocketFlags.None, new AsyncCallback(this.b), null); + } + else + { + this.b(); + } + } + else + { + this.e(); + } + } + catch (Exception arg_D3_0) + { + Logging.LogUsefulException(arg_D3_0); + this.e(); + } + } + + private void b() + { + bool flag = false; + byte[] buffer = new byte[11680]; + DateTime d = DateTime.Now; + while (!this.f) + { + try + { + int num = this.e.Receive(buffer, 11680, SocketFlags.None); + DateTime now = DateTime.Now; + if (this.e != null && this.e.IsClose) + { + flag = true; + break; + } + if (this.f) + { + break; + } + this.a((double)this.n); + if (num > 0) + { + this.d.Send(buffer, num, SocketFlags.None); + if (Analyzer.instance().Add(this.h, this.i, this.e, buffer, num, true)) + { + Analyzer.instance().Close(this.h, this.i, this.e); + } + if ((now - d).TotalSeconds > 5.0) + { + this.m = 0; + this.e.BeginReceive(this.k, 11680, SocketFlags.None, new AsyncCallback(this.b), null); + return; + } + d = now; + } + else + { + this.e(); + } + } + catch (Exception arg_113_0) + { + Logging.LogUsefulException(arg_113_0); + flag = true; + break; + } + } + if (flag) + { + this.e(); + return; + } + } + + private void a(IAsyncResult A_0) + { + if (this.f) + { + return; + } + try + { + int num = this.d.EndReceive(A_0); + if (num > 0) + { + this.a((double)this.n); + this.e.Send(this.l, num, SocketFlags.None); + if (Analyzer.instance().Add(this.h, this.i, this.e, this.l, num, false)) + { + Analyzer.instance().Close(this.h, this.i, this.e); + } + this.d.BeginReceive(this.l, 11680, SocketFlags.None, new AsyncCallback(this.a), null); + } + else + { + this.e(); + } + } + catch (Exception arg_B0_0) + { + Logging.LogUsefulException(arg_B0_0); + this.e(); + } + } + + private void a(ProxySocketTun A_0) + { + lock (this) + { + if (A_0 != null) + { + try + { + A_0.Shutdown(SocketShutdown.Both); + } + catch + { + } + try + { + A_0.Close(); + } + catch + { + } + } + } + } + + public void e() + { + lock (this) + { + if (this.f) + { + return; + } + this.f = true; + } + this.a(0.0); + Thread.Sleep(100); + Analyzer.instance().Close(this.h, this.i, this.e); + this.a(this.e); + this.a(this.d); + } + + public override void Shutdown() + { + new IHandler.InvokeHandler(this.a).BeginInvoke(null, null); + } + + [CompilerGenerated] + private void a() + { + this.e(); + } + } + + private const int a = 1; + + private const int b = 2; + + private const int c = 0; + + private Configuration d; + + public b(Configuration A_0) + { + this.d = A_0; + } + + public bool b(byte[] A_0, int A_1, Socket A_2) + { + return this.a(A_0, A_1, A_2, null); + } + + public bool a(byte[] A_0, int A_1, Socket A_2, string A_3) + { + if (this.a(A_0, A_1, A_2) > 0) + { + new b.a().a(this.d, A_0, A_1, A_2, A_3, false); + return true; + } + return false; + } + + public int a(byte[] A_0, int A_1, Socket A_2) + { + return 2; + } +} diff --git a/c.cs b/c.cs new file mode 100644 index 0000000..ff89c12 --- /dev/null +++ b/c.cs @@ -0,0 +1,401 @@ +using socks5.Controller; +using socks5.Model; +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; + +internal class c +{ + private Configuration a; + + private byte[] b; + + private int c; + + private Socket d; + + private Socket e; + + private string f; + + protected const int g = 16384; + + protected byte[] h = new byte[32768]; + + public byte i; + + protected byte[] j; + + public c(Configuration A_0, byte[] A_1, int A_2, Socket A_3) + { + int arg_27_0 = ((IPEndPoint)A_3.LocalEndPoint).Port; + this.a = A_0; + this.b = A_1; + this.c = A_2; + this.d = A_3; + A_3.NoDelay = true; + this.g(); + } + + private void a(ref Socket A_0) + { + lock (this) + { + if (A_0 != null) + { + Socket socket = A_0; + A_0 = null; + try + { + socket.Shutdown(SocketShutdown.Both); + } + catch + { + } + try + { + socket.Close(); + } + catch + { + } + } + } + } + + private void h() + { + this.a(ref this.d); + this.a(ref this.e); + this.a = null; + } + + private bool a(Socket A_0, string A_1, string A_2) + { + return true; + } + + private void g() + { + try + { + if (this.c > 1) + { + if (this.b[0] == 5 && this.c >= 3) + { + this.f(); + } + else + { + this.h(); + } + } + else + { + this.h(); + } + } + catch (Exception arg_35_0) + { + Logging.LogUsefulException(arg_35_0); + this.h(); + } + } + + private void f() + { + byte[] expr_06 = new byte[2]; + expr_06[0] = 5; + byte[] array = expr_06; + if (this.b[0] != 5) + { + array = new byte[] + { + 0, + 91 + }; + Console.WriteLine("socks 4/5 protocol error"); + this.d.Send(array); + this.h(); + return; + } + bool flag = false; + bool flag2 = false; + bool flag3 = false; + for (int i = 0; i < (int)this.b[1]; i++) + { + if (this.b[2 + i] == 0) + { + flag = true; + flag3 = true; + } + else if (this.b[2 + i] == 2) + { + flag2 = true; + flag3 = true; + } + } + if (!flag3) + { + Console.WriteLine("Socks5 no acceptable auth method"); + this.h(); + return; + } + if (flag2 || !flag) + { + array[1] = 2; + this.d.Send(array); + this.e(); + return; + } + if (flag) + { + this.d.Send(array); + this.d(); + return; + } + Console.WriteLine("Socks5 Auth failed"); + this.h(); + } + + private void e() + { + try + { + if (this.d.Receive(this.h, 1024, SocketFlags.None) >= 3) + { + byte b = this.h[1]; + byte count = this.h[(int)(b + 2)]; + byte[] expr_34 = new byte[2]; + expr_34[0] = 1; + byte[] buffer = expr_34; + string @string = Encoding.UTF8.GetString(this.h, 2, (int)b); + string string2 = Encoding.UTF8.GetString(this.h, (int)(b + 3), (int)count); + if (this.a(this.d, @string, string2)) + { + this.d.Send(buffer); + this.d(); + } + } + else + { + Console.WriteLine("failed to recv data in HandshakeAuthReceiveCallback"); + this.h(); + } + } + catch (Exception arg_9A_0) + { + Logging.LogUsefulException(arg_9A_0); + this.h(); + } + } + + private void d() + { + try + { + int num = this.d.Receive(this.h, 5, SocketFlags.None); + if (num >= 5) + { + this.i = this.h[1]; + this.j = new byte[num - 3]; + Array.Copy(this.h, 3, this.j, 0, this.j.Length); + int num2 = 0; + if (this.j[0] == 1) + { + num2 = 3; + } + else if (this.j[0] == 4) + { + num2 = 15; + } + else if (this.j[0] == 3) + { + num2 = (int)this.j[1]; + } + if (num2 == 0) + { + throw new Exception("Wrong socks5 addr type"); + } + this.b(num2 + 2); + } + else + { + Console.WriteLine("failed to recv data in HandshakeReceive2Callback"); + this.h(); + } + } + catch (Exception arg_B2_0) + { + Logging.LogUsefulException(arg_B2_0); + this.h(); + } + } + + private void b(int A_0) + { + try + { + int num = this.d.Receive(this.h, A_0, SocketFlags.None); + if (num > 0) + { + Array.Resize(ref this.j, this.j.Length + num); + Array.Copy(this.h, 0, this.j, this.j.Length - num, num); + if (this.i == 3) + { + this.a(num); + } + else + { + this.f = "socks5"; + this.b(); + } + } + else + { + Console.WriteLine("failed to recv data in HandshakeReceive3Callback"); + this.h(); + } + } + catch (Exception arg_81_0) + { + Logging.LogUsefulException(arg_81_0); + this.h(); + } + } + + private void a(int A_0) + { + bool flag = this.d.AddressFamily == AddressFamily.InterNetworkV6; + int num = 0; + if (A_0 >= 9) + { + flag = (this.j[0] == 4); + if (!flag) + { + num = (int)this.j[5] * 256 + (int)this.j[6]; + } + else + { + num = (int)this.j[17] * 256 + (int)this.j[18]; + } + } + if (!flag) + { + this.j = new byte[7]; + this.j[0] = 9; + this.j[5] = (byte)(num / 256); + this.j[6] = (byte)(num % 256); + } + else + { + this.j = new byte[19]; + this.j[0] = 12; + this.j[17] = (byte)(num / 256); + this.j[18] = (byte)(num % 256); + } + int i = 0; + IPAddress iPAddress = flag ? IPAddress.IPv6Any : IPAddress.Any; + this.e = new Socket(iPAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + while (i < 65536) + { + try + { + this.e.Bind(new IPEndPoint(iPAddress, i)); + break; + } + catch (Exception) + { + } + i++; + } + i = ((IPEndPoint)this.e.LocalEndPoint).Port; + if (!flag) + { + byte[] array = new byte[] + { + 5, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + (byte)(i / 256), + (byte)(i % 256) + }; + Array.Copy(((IPEndPoint)this.d.LocalEndPoint).Address.GetAddressBytes(), 0, array, 4, 4); + this.d.Send(array); + this.b(); + return; + } + byte[] array2 = new byte[] + { + 5, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + (byte)(i / 256), + (byte)(i % 256) + }; + Array.Copy(((IPEndPoint)this.d.LocalEndPoint).Address.GetAddressBytes(), 0, array2, 4, 16); + this.d.Send(array2); + this.b(); + } + + private void c() + { + if (this.d.AddressFamily == AddressFamily.InterNetwork) + { + byte[] expr_15 = new byte[10]; + expr_15[0] = 5; + expr_15[3] = 1; + byte[] buffer = expr_15; + this.d.Send(buffer); + return; + } + byte[] expr_33 = new byte[22]; + expr_33[0] = 5; + expr_33[3] = 4; + byte[] buffer2 = expr_33; + this.d.Send(buffer2); + } + + private void b() + { + int arg_15_0 = ((IPEndPoint)this.d.LocalEndPoint).Port; + if (this.e == null) + { + new b(this.a).a(this.j, this.j.Length, this.d, this.f); + } + this.a(); + this.h(); + } + + private void a() + { + this.b = null; + this.d = null; + this.e = null; + this.h = null; + this.j = null; + } +} diff --git a/d.cs b/d.cs new file mode 100644 index 0000000..66290f5 --- /dev/null +++ b/d.cs @@ -0,0 +1,317 @@ +using socks5.Controller; +using socks5.Model; +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Runtime.CompilerServices; +using System.Timers; + +internal class d +{ + public interface b + { + bool a(byte[] A_0, int A_1, Socket A_2); + } + + [CompilerGenerated] + private sealed class a + { + public Socket a; + + public d b; + + internal void d(object A_0, ElapsedEventArgs A_1) + { + this.b.a(A_0, A_1, this.a); + } + + internal void c(object A_0, ElapsedEventArgs A_1) + { + this.b.a(A_0, A_1, this.a); + } + } + + private Configuration a; + + private bool b; + + private string c; + + private Socket d; + + private Socket e; + + private bool f; + + private IList g; + + protected Timer h; + + protected object i = new object(); + + public d(IList A_0) + { + this.g = A_0; + this.f = false; + } + + public IList b() + { + return this.g; + } + + private bool a(int A_0) + { + try + { + IPEndPoint[] activeTcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners(); + for (int i = 0; i < activeTcpListeners.Length; i++) + { + if (activeTcpListeners[i].Port == A_0) + { + return true; + } + } + } + catch + { + } + return false; + } + + public bool a(Configuration A_0) + { + try + { + if (this.b != A_0.shareOverLan || this.d == null || ((IPEndPoint)this.d.LocalEndPoint).Port != A_0.localPort) + { + return true; + } + } + catch (Exception) + { + } + return false; + } + + public void a(Configuration A_0, int A_1) + { + this.a = A_0; + this.b = A_0.shareOverLan; + this.c = ""; + this.f = false; + int num = (A_1 == 0) ? this.a.localPort : A_1; + if (this.a(num)) + { + throw new Exception("Port already in use"); + } + try + { + bool arg_6D_0 = true; + this.d = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + this.d.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + if (arg_6D_0) + { + try + { + this.e = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); + this.e.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + } + catch + { + this.e = null; + } + } + IPEndPoint localEP = new IPEndPoint(IPAddress.Any, num); + IPEndPoint localEP2 = new IPEndPoint(IPAddress.IPv6Any, num); + if (this.e != null) + { + this.e.Bind(localEP2); + this.e.Listen(1024); + } + this.d.Bind(localEP); + this.d.Listen(1024); + Console.WriteLine("socks5 started on port " + num.ToString()); + this.d.BeginAccept(new AsyncCallback(this.b), this.d); + if (this.e != null) + { + this.e.BeginAccept(new AsyncCallback(this.b), this.e); + } + } + catch (SocketException arg_154_0) + { + Logging.LogUsefulException(arg_154_0); + if (this.d != null) + { + this.d.Close(); + this.d = null; + } + if (this.e != null) + { + this.e.Close(); + this.e = null; + } + throw; + } + } + + public void a() + { + this.a(0.0, null); + this.f = true; + if (this.d != null) + { + this.d.Close(); + this.d = null; + } + if (this.e != null) + { + this.e.Close(); + this.e = null; + } + } + + private void a(double A_0, Socket A_1) + { + d.a a = new d.a(); + a.b = this; + a.a = A_1; + if (A_0 <= 0.0 && this.h == null) + { + return; + } + object obj = this.i; + lock (obj) + { + if (A_0 <= 0.0) + { + if (this.h != null) + { + this.h.Enabled = false; + this.h.Elapsed -= new ElapsedEventHandler(a.d); + this.h.Dispose(); + this.h = null; + } + } + else if (this.h == null) + { + this.h = new Timer(A_0 * 1000.0); + this.h.Elapsed += new ElapsedEventHandler(a.c); + this.h.Start(); + } + else + { + this.h.Interval = A_0 * 1000.0; + this.h.Stop(); + this.h.Start(); + } + } + } + + private void a(object A_0, ElapsedEventArgs A_1, Socket A_2) + { + if (this.h == null) + { + return; + } + try + { + A_2.BeginAccept(new AsyncCallback(this.b), A_2); + this.a(0.0, A_2); + } + catch (ObjectDisposedException) + { + } + catch (Exception arg_34_0) + { + Logging.LogUsefulException(arg_34_0); + this.a(5.0, A_2); + } + } + + public void b(IAsyncResult A_0) + { + if (this.f) + { + return; + } + Socket socket = (Socket)A_0.AsyncState; + try + { + Socket socket2 = socket.EndAccept(A_0); + if (!this.b && !global::a.b(socket2)) + { + socket2.Shutdown(SocketShutdown.Both); + socket2.Close(); + } + if ((this.c ?? "").Length == 0 && !global::a.a(socket2)) + { + socket2.Shutdown(SocketShutdown.Both); + socket2.Close(); + } + else + { + byte[] array = new byte[4096]; + object[] state = new object[] + { + socket2, + array + }; + socket2.BeginReceive(array, 0, array.Length, SocketFlags.None, new AsyncCallback(this.a), state); + } + } + catch (ObjectDisposedException) + { + } + catch (Exception arg_A0_0) + { + Console.WriteLine(arg_A0_0); + } + finally + { + try + { + socket.BeginAccept(new AsyncCallback(this.b), socket); + } + catch (ObjectDisposedException) + { + } + catch (Exception arg_C1_0) + { + Logging.LogUsefulException(arg_C1_0); + this.a(5.0, socket); + } + } + } + + private void a(IAsyncResult A_0) + { + object[] expr_0B = (object[])A_0.AsyncState; + Socket socket = (Socket)expr_0B[0]; + byte[] a_ = (byte[])expr_0B[1]; + try + { + int a_2 = socket.EndReceive(A_0); + using (IEnumerator enumerator = this.g.GetEnumerator()) + { + while (enumerator.MoveNext()) + { + if (enumerator.Current.a(a_, a_2, socket)) + { + return; + } + } + } + socket.Shutdown(SocketShutdown.Both); + socket.Close(); + } + catch (Exception arg_67_0) + { + Console.WriteLine(arg_67_0); + socket.Shutdown(SocketShutdown.Both); + socket.Close(); + } + } +} diff --git a/e.cs b/e.cs new file mode 100644 index 0000000..3fd9d09 --- /dev/null +++ b/e.cs @@ -0,0 +1,19 @@ +using System; + +internal class e : IComparable +{ + public long a; + + public int b; + + public e(int A_0, long A_1) + { + this.a = A_1; + this.b = A_0; + } + + public int CompareTo(object obj) + { + return this.a.CompareTo(((e)obj).a); + } +} diff --git a/f.cs b/f.cs new file mode 100644 index 0000000..f7de9ed --- /dev/null +++ b/f.cs @@ -0,0 +1,137 @@ +using socks5.Controller; +using socks5.Model; +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Runtime.CompilerServices; +using System.Threading; + +internal class f +{ + private class a : d.b + { + private delegate void b(); + + [CompilerGenerated] + private sealed class a + { + public byte[] a; + + public int b; + + public Socket c; + + public f.a d; + + internal void e() + { + new c(this.d.a, this.a, this.b, this.c); + } + } + + private Configuration a; + + public a(Configuration A_0) + { + this.a = A_0; + } + + protected bool a(byte[] A_0, int A_1) + { + return A_1 >= 2 && (A_0[0] == 5 || A_0[0] == 4 || (A_1 > 8 && A_0[0] == 67 && A_0[1] == 79 && A_0[2] == 78 && A_0[3] == 78 && A_0[4] == 69 && A_0[5] == 67 && A_0[6] == 84 && A_0[7] == 32)); + } + + public bool a(byte[] A_0, int A_1, Socket A_2) + { + f.a.a a = new f.a.a(); + a.d = this; + a.a = A_0; + a.b = A_1; + a.c = A_2; + if (!this.a(a.a, a.b)) + { + return false; + } + new f.a.b(a.e).BeginInvoke(null, null); + return true; + } + } + + private d a; + + private Configuration b; + + private bool c; + + protected void b() + { + this.b = new Configuration(); + bool flag = false; + for (int i = 1; i <= 5; i++) + { + try + { + if (this.a != null && !this.a.a(this.b)) + { + f.a value = new f.a(this.b); + this.a.b()[0] = value; + } + else + { + if (this.a != null) + { + this.a.a(); + this.a = null; + } + f.a item = new f.a(this.b); + this.a = new d(new List + { + item + }); + this.a.a(this.b, 0); + } + break; + } + catch (Exception ex) + { + if (ex is SocketException && ((SocketException)ex).SocketErrorCode == SocketError.AccessDenied) + { + ex = new Exception("Port already in use" + string.Format(" {0}", this.b.localPort), ex); + } + Logging.LogUsefulException(ex); + if (!flag) + { + break; + } + Thread.Sleep(1000 * i * i); + if (this.a != null) + { + this.a.a(); + this.a = null; + } + } + } + global::a.c(); + } + + public void a() + { + if (this.c) + { + return; + } + this.c = true; + if (this.a != null) + { + this.a.a(); + } + } + + private static void a(string[] A_0) + { + f expr_05 = new f(); + expr_05.b(); + Console.ReadLine(); + expr_05.a(); + } +} diff --git a/g.cs b/g.cs new file mode 100644 index 0000000..5c43e91 --- /dev/null +++ b/g.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; + +internal class g +{ + private string a; + + private long[] b = new long[2049]; + + private long[] c = new long[2049]; + + public int d; + + public int e; + + public int f; + + public int g; + + public int h = 500; + + private int i; + + private int j; + + private int k; + + public g(string A_0) + { + this.a = A_0; + } + + public void a(h A_0) + { + for (int i = 0; i <= 2048; i++) + { + this.b[i] += A_0.b[i]; + this.c[i] += A_0.c[i]; + A_0.b[i] = 0L; + A_0.c[i] = 0L; + } + this.d += A_0.d; + A_0.d = 0; + this.e += A_0.e; + A_0.e = 0; + this.f++; + if (A_0.h) + { + this.g++; + } + bool flag = false; + int num = 0; + int num2 = 0; + if (this.d + this.e > this.h && this.f >= 5) + { + flag = true; + this.h += 200; + int arg_118_0 = (int)((long)this.d - this.b[2048]); + int num3 = (int)((long)this.e - this.c[2048]); + if (arg_118_0 >= 100 && num3 >= 100) + { + int[] array = new int[200]; + int[] array2 = new int[200]; + e[] array3 = new e[200]; + for (int j = 0; j < 200; j++) + { + array3[j] = new e(j, this.c[j]); + } + Array.Sort(array3); + int num4 = 199; + while (num4 > 170 && (array3[num4].a != array3[num4 - 1].a || array3[num4].a != array3[num4 - 2].a)) + { + array[array3[num4].b] = 1; + num4--; + } + for (int k = 0; k < 200; k++) + { + array3[k] = new e(k, this.b[k]); + } + Array.Sort(array3); + int num5 = 199; + while (num5 > 170 && (array3[num5].a != array3[num5 - 1].a || array3[num5].a != array3[num5 - 2].a)) + { + array2[array3[num5].b] = 1; + num5--; + } + List list = new List(); + for (int l = 38; l < 170; l++) + { + if (array[l] == 1 && array[l + 8] == 1 && this.b[l] > 0L) + { + list.Add(l); + } + } + if (list.Count > 0) + { + int num6 = list[0]; + if (list.Count < 6) + { + if (this.g < this.f / 1024 || this.g <= 1) + { + if (num6 == 38) + { + this.b("Remote [" + this.a + "] looks like a Shadowsocks Server"); + num2 = 1; + } + else if (num6 == 72) + { + this.b("Remote [" + this.a + "] looks like a Shadowsocks Server with AEAD cipher"); + num2 = 2; + } + else if (num6 == 44 && this.c[6] > (long)(num3 / 300)) + { + this.b("Remote [" + this.a + "] looks like a V2ray Server with vmess + stream cipher"); + num2 = 11; + } + else if (num6 == 56 && this.c[18] > (long)(num3 / 300)) + { + this.b("Remote [" + this.a + "] looks like a V2ray Server with vmess + AEAD cipher"); + num2 = 12; + } + else if (num6 == 52 && this.c[12] > (long)(num3 / 300)) + { + this.b("Remote [" + this.a + "] looks like a V2ray Server with vmess MUX + stream cipher"); + num2 = 13; + } + else if (num6 == 64 && this.c[24] > (long)(num3 / 300)) + { + this.b("Remote [" + this.a + "] looks like a V2ray Server with vmess MUX + AEAD cipher"); + num2 = 14; + } + } + else if (this.g > this.f / 2) + { + num = 1; + if (num6 == 43) + { + this.b("Remote [" + this.a + "] looks like a Shadowsocks Server with TLS obfs"); + } + else if (num6 == 77) + { + this.b("Remote [" + this.a + "] looks like a Shadowsocks Server with AEAD cipher & TLS obfs"); + } + } + } + } + } + } + if (num2 > 0) + { + if (num == this.j && num2 == this.k) + { + this.i++; + this.a(" by " + ((int)(100.0 - Math.Pow(0.4, (double)this.i) * 100.0)).ToString() + "%"); + } + else + { + this.i = 0; + this.j = num; + this.k = num2; + this.a(" by 20%"); + } + } + if (flag) + { + this.b = new long[2049]; + this.c = new long[2049]; + this.d = 0; + this.e = 0; + this.f = 0; + this.g = 0; + this.h = 500; + } + } + + private void b(string A_0) + { + Console.Write(string.Format("[{0}] {1}", DateTime.Now, A_0)); + } + + private void a(string A_0) + { + Console.WriteLine(A_0); + } +} diff --git a/h.cs b/h.cs new file mode 100644 index 0000000..435696b --- /dev/null +++ b/h.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; + +internal class h +{ + public const int a = 2048; + + public long[] b = new long[2049]; + + public long[] c = new long[2049]; + + public int d; + + public int e; + + private int f; + + private List g = new List(); + + public bool h; + + public bool f(byte[] A_0, int A_1) + { + this.d++; + if (A_1 > 2048) + { + A_1 = 2048; + } + this.b[A_1] += 1L; + return (this.d + this.e) % 100 == 0; + } + + public bool a(byte[] A_0, int A_1) + { + this.e++; + this.f++; + this.c[A_1] += 1L; + if (this.f == 1 && A_1 > 3 && A_0[0] == 22 && A_0[1] == 3 && A_0[2] == 1) + { + this.h = true; + } + return (this.d + this.e) % 100 == 0; + } +} diff --git a/socks5.Controller/Analyzer.cs b/socks5.Controller/Analyzer.cs new file mode 100644 index 0000000..b177393 --- /dev/null +++ b/socks5.Controller/Analyzer.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +namespace socks5.Controller +{ + public class Analyzer + { + private static Analyzer a = new Analyzer(); + + private Dictionary b = new Dictionary(); + + private Dictionary c = new Dictionary(); + + public static Analyzer instance() + { + return Analyzer.a; + } + + public bool Add(string remote_host, int remote_port, ProxySocketTun socket, byte[] buffer, int size, bool remote) + { + if (socket == null) + { + return false; + } + h h = null; + Dictionary obj = this.b; + lock (obj) + { + if (this.b.ContainsKey(socket)) + { + h = this.b[socket]; + } + else + { + h = new h(); + this.b[socket] = h; + } + } + if (remote) + { + return h.f(buffer, size); + } + return h.a(buffer, size); + } + + public void Close(string remote_host, int remote_port, ProxySocketTun socket) + { + if (socket != null) + { + h h = null; + Dictionary obj = this.b; + lock (obj) + { + if (this.b.ContainsKey(socket)) + { + h = this.b[socket]; + this.b.Remove(socket); + } + } + if (h != null) + { + g g = null; + Dictionary obj2 = this.c; + lock (obj2) + { + string text = remote_host + ":" + remote_port.ToString(); + if (this.c.ContainsKey(text)) + { + g = this.c[text]; + } + else + { + g = new g(text); + this.c[text] = g; + } + } + g.a(h); + } + } + } + } +} diff --git a/socks5.Controller/CallbackState.cs b/socks5.Controller/CallbackState.cs new file mode 100644 index 0000000..0877c62 --- /dev/null +++ b/socks5.Controller/CallbackState.cs @@ -0,0 +1,15 @@ +using System; + +namespace socks5.Controller +{ + public class CallbackState + { + public byte[] buffer; + + public int size; + + public int protocol_size; + + public object state; + } +} diff --git a/socks5.Controller/IHandler.cs b/socks5.Controller/IHandler.cs new file mode 100644 index 0000000..f99722f --- /dev/null +++ b/socks5.Controller/IHandler.cs @@ -0,0 +1,11 @@ +using System; + +namespace socks5.Controller +{ + public abstract class IHandler + { + public delegate void InvokeHandler(); + + public abstract void Shutdown(); + } +} diff --git a/socks5.Controller/LogLevel.cs b/socks5.Controller/LogLevel.cs new file mode 100644 index 0000000..02388db --- /dev/null +++ b/socks5.Controller/LogLevel.cs @@ -0,0 +1,13 @@ +using System; + +namespace socks5.Controller +{ + public enum LogLevel + { + Debug, + Info, + Warn, + Error, + Assert + } +} diff --git a/socks5.Controller/Logging.cs b/socks5.Controller/Logging.cs new file mode 100644 index 0000000..83652db --- /dev/null +++ b/socks5.Controller/Logging.cs @@ -0,0 +1,249 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Net.Sockets; + +namespace socks5.Controller +{ + public class Logging + { + public static string LogFile; + + public static string LogFilePath; + + public static string LogFileName; + + protected static string date; + + private static FileStream a; + + private static StreamWriterWithTimestamp b; + + private static object c = new object(); + + public static bool OpenLogFile() + { + bool result; + try + { + Logging.a(); + string text = Path.Combine(Path.GetDirectoryName(global::a.a()), "temp"); + Logging.LogFilePath = text; + if (!Directory.Exists(text)) + { + Directory.CreateDirectory(text); + } + string str = DateTime.Now.ToString("yyyy-MM"); + Logging.LogFileName = "shadowsocks_" + str + ".log"; + Logging.LogFile = Path.Combine(text, Logging.LogFileName); + Logging.a = new FileStream(Logging.LogFile, FileMode.Append); + Logging.b = new StreamWriterWithTimestamp(Logging.a); + Logging.b.AutoFlush = true; + Console.SetError(Logging.b); + Logging.date = str; + result = true; + } + catch (IOException arg_A5_0) + { + Console.WriteLine(arg_A5_0.ToString()); + result = false; + } + return result; + } + + private static void a() + { + StreamWriterWithTimestamp expr_05 = Logging.b; + if (expr_05 != null) + { + expr_05.Dispose(); + } + FileStream expr_15 = Logging.a; + if (expr_15 != null) + { + expr_15.Dispose(); + } + Logging.b = null; + Logging.a = null; + } + + public static void Clear() + { + Logging.a(); + if (Logging.LogFile != null) + { + File.Delete(Logging.LogFile); + } + Logging.OpenLogFile(); + } + + public static void Error(object o) + { + Logging.Log(LogLevel.Error, o); + } + + public static void Info(object o) + { + Logging.Log(LogLevel.Info, o); + } + + [Conditional("DEBUG")] + public static void Debug(object o) + { + Logging.Log(LogLevel.Debug, o); + } + + private static string a(StackFrame[] A_0) + { + string text = string.Empty; + for (int i = 0; i < A_0.Length; i++) + { + StackFrame stackFrame = A_0[i]; + text += string.Format("{0}\r\n", stackFrame.GetMethod().ToString()); + } + return text; + } + + protected static void UpdateLogFile() + { + if (DateTime.Now.ToString("yyyy-MM") != Logging.date) + { + object obj = Logging.c; + lock (obj) + { + if (DateTime.Now.ToString("yyyy-MM") != Logging.date) + { + Logging.OpenLogFile(); + } + } + } + } + + public static void LogUsefulException(Exception e) + { + Logging.UpdateLogFile(); + if (e is SocketException) + { + SocketException ex = (SocketException)e; + if (ex.SocketErrorCode != SocketError.ConnectionAborted && ex.SocketErrorCode != SocketError.ConnectionReset && ex.SocketErrorCode != SocketError.NotConnected && ex.SocketErrorCode != (SocketError)(-2147467259) && ex.SocketErrorCode != SocketError.Shutdown && ex.SocketErrorCode != SocketError.Interrupted) + { + Logging.Error(e); + return; + } + } + else + { + Logging.Error(e); + } + } + + public static bool LogSocketException(string remarks, string server, Exception e) + { + Logging.UpdateLogFile(); + if (e is NullReferenceException) + { + return true; + } + if (e is ObjectDisposedException) + { + return true; + } + if (!(e is SocketException)) + { + return false; + } + SocketException ex = (SocketException)e; + if (ex.SocketErrorCode == (SocketError)(-2147467259)) + { + return true; + } + if (ex.ErrorCode == 11004) + { + Logging.Log(LogLevel.Warn, string.Concat(new string[] + { + "Proxy server [", + remarks, + "(", + server, + ")] DNS lookup failed" + })); + return true; + } + if (ex.SocketErrorCode == SocketError.HostNotFound) + { + Logging.Log(LogLevel.Warn, string.Concat(new string[] + { + "Proxy server [", + remarks, + "(", + server, + ")] Host not found" + })); + return true; + } + if (ex.SocketErrorCode == SocketError.ConnectionRefused) + { + Logging.Log(LogLevel.Warn, string.Concat(new string[] + { + "Proxy server [", + remarks, + "(", + server, + ")] connection refused" + })); + return true; + } + if (ex.SocketErrorCode == SocketError.NetworkUnreachable) + { + Logging.Log(LogLevel.Warn, string.Concat(new string[] + { + "Proxy server [", + remarks, + "(", + server, + ")] network unreachable" + })); + return true; + } + if (ex.SocketErrorCode == SocketError.TimedOut) + { + return true; + } + if (ex.SocketErrorCode == SocketError.Shutdown) + { + return true; + } + Logging.Log(LogLevel.Info, string.Concat(new string[] + { + "Proxy server [", + remarks, + "(", + server, + ")] ", + Convert.ToString(ex.SocketErrorCode), + ":", + ex.Message + })); + return true; + } + + public static void Log(LogLevel level, object s) + { + Logging.UpdateLogFile(); + string[] array = new string[] + { + "Debug", + "Info", + "Warn", + "Error", + "Assert" + }; + Console.Error.WriteLine(string.Format("[{0}] {1}", array[(int)level], s)); + } + + [Conditional("DEBUG")] + public static void LogBin(LogLevel level, string info, byte[] data, int length) + { + } + } +} diff --git a/socks5.Controller/ProxySocketTun.cs b/socks5.Controller/ProxySocketTun.cs new file mode 100644 index 0000000..389c648 --- /dev/null +++ b/socks5.Controller/ProxySocketTun.cs @@ -0,0 +1,391 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace socks5.Controller +{ + public class ProxySocketTun + { + protected Socket _socket; + + protected EndPoint _socketEndPoint; + + protected IPEndPoint _remoteUDPEndPoint; + + protected bool _proxy; + + protected string _proxy_server; + + protected int _proxy_udp_port; + + protected const int RecvSize = 2920; + + private byte[] a = new byte[2920]; + + private byte[] b = new byte[5840]; + + protected bool _close; + + public bool IsClose + { + get + { + return this._close; + } + } + + public bool GoS5Proxy + { + get + { + return this._proxy; + } + set + { + this._proxy = value; + } + } + + public AddressFamily AddressFamily + { + get + { + return this._socket.AddressFamily; + } + } + + public int Available + { + get + { + return this._socket.Available; + } + } + + public ProxySocketTun(Socket socket) + { + this._socket = socket; + } + + public ProxySocketTun(AddressFamily af, SocketType type, ProtocolType protocol) + { + this._socket = new Socket(af, type, protocol); + } + + public Socket GetSocket() + { + return this._socket; + } + + public void Shutdown(SocketShutdown how) + { + this._socket.Shutdown(how); + } + + public void Close() + { + this._socket.Close(); + this._socket = null; + this.a = null; + this.b = null; + } + + public IAsyncResult BeginConnect(EndPoint ep, AsyncCallback callback, object state) + { + this._close = false; + this._socketEndPoint = ep; + return this._socket.BeginConnect(ep, callback, state); + } + + public void EndConnect(IAsyncResult ar) + { + this._socket.EndConnect(ar); + } + + public int Receive(byte[] buffer, int size, SocketFlags flags) + { + return this._socket.Receive(buffer, size, SocketFlags.None); + } + + public IAsyncResult BeginReceive(byte[] buffer, int size, SocketFlags flags, AsyncCallback callback, object state) + { + CallbackState callbackState = new CallbackState(); + callbackState.buffer = buffer; + callbackState.size = size; + callbackState.state = state; + return this._socket.BeginReceive(buffer, 0, size, flags, callback, callbackState); + } + + public int EndReceive(IAsyncResult ar) + { + int num = this._socket.EndReceive(ar); + if (num > 0) + { + ((CallbackState)ar.AsyncState).size = num; + return num; + } + this._close = true; + return num; + } + + public int SendAll(byte[] buffer, int size, SocketFlags flags) + { + int num; + for (int i = this._socket.Send(buffer, size, SocketFlags.None); i < size; i += num) + { + num = this._socket.Send(buffer, i, size - i, SocketFlags.None); + } + return size; + } + + public virtual int Send(byte[] buffer, int size, SocketFlags flags) + { + return this.SendAll(buffer, size, SocketFlags.None); + } + + public int BeginSend(byte[] buffer, int size, SocketFlags flags, AsyncCallback callback, object state) + { + CallbackState callbackState = new CallbackState(); + callbackState.size = size; + callbackState.state = state; + this._socket.BeginSend(buffer, 0, size, SocketFlags.None, callback, callbackState); + return size; + } + + public int EndSend(IAsyncResult ar) + { + return this._socket.EndSend(ar); + } + + public IAsyncResult BeginReceiveFrom(byte[] buffer, int size, SocketFlags flags, ref EndPoint ep, AsyncCallback callback, object state) + { + CallbackState callbackState = new CallbackState(); + callbackState.buffer = buffer; + callbackState.size = size; + callbackState.state = state; + return this._socket.BeginReceiveFrom(buffer, 0, size, flags, ref ep, callback, callbackState); + } + + public int GetAsyncResultSize(IAsyncResult ar) + { + return ((CallbackState)ar.AsyncState).size; + } + + public byte[] GetAsyncResultBuffer(IAsyncResult ar) + { + return ((CallbackState)ar.AsyncState).buffer; + } + + public bool ConnectSocks5ProxyServer(string strRemoteHost, int iRemotePort, bool udp, string socks5RemoteUsername, string socks5RemotePassword) + { + int errorCode = 10054; + this._proxy = true; + byte[] array = new byte[10]; + array[0] = 5; + array[1] = ((socks5RemoteUsername.Length == 0) ? 1 : 2); + array[2] = 0; + array[3] = 2; + this._socket.Send(array, (int)(array[1] + 2), SocketFlags.None); + byte[] array2 = new byte[32]; + if (this._socket.Receive(array2, array2.Length, SocketFlags.None) < 2) + { + throw new SocketException(errorCode); + } + if (array2[0] != 5 || (array2[1] != 0 && array2[1] != 2)) + { + throw new SocketException(errorCode); + } + if (array2[1] != 0) + { + if (array2[1] != 2) + { + return false; + } + if (socks5RemoteUsername.Length == 0) + { + throw new SocketException(errorCode); + } + array = new byte[socks5RemoteUsername.Length + socks5RemotePassword.Length + 3]; + array[0] = 1; + array[1] = (byte)socks5RemoteUsername.Length; + for (int i = 0; i < socks5RemoteUsername.Length; i++) + { + array[2 + i] = (byte)socks5RemoteUsername[i]; + } + array[socks5RemoteUsername.Length + 2] = (byte)socks5RemotePassword.Length; + for (int j = 0; j < socks5RemotePassword.Length; j++) + { + array[socks5RemoteUsername.Length + 3 + j] = (byte)socks5RemotePassword[j]; + } + this._socket.Send(array, array.Length, SocketFlags.None); + this._socket.Receive(array2, array2.Length, SocketFlags.None); + if (array2[0] != 1 || array2[1] != 0) + { + throw new SocketException(10061); + } + } + if (!udp) + { + List list = new List(); + list.Add(5); + list.Add(1); + list.Add(0); + IPAddress iPAddress; + IPAddress.TryParse(strRemoteHost, out iPAddress); + if (iPAddress == null) + { + list.Add(3); + list.Add((byte)strRemoteHost.Length); + for (int k = 0; k < strRemoteHost.Length; k++) + { + list.Add((byte)strRemoteHost[k]); + } + } + else + { + byte[] addressBytes = iPAddress.GetAddressBytes(); + if (addressBytes.GetLength(0) > 4) + { + list.Add(4); + for (int l = 0; l < 16; l++) + { + list.Add(addressBytes[l]); + } + } + else + { + list.Add(1); + for (int m = 0; m < 4; m++) + { + list.Add(addressBytes[m]); + } + } + } + list.Add((byte)(iRemotePort / 256)); + list.Add((byte)(iRemotePort % 256)); + this._socket.Send(list.ToArray(), list.Count, SocketFlags.None); + if (this._socket.Receive(array2, array2.Length, SocketFlags.None) < 2 || array2[0] != 5 || array2[1] != 0) + { + throw new SocketException(errorCode); + } + return true; + } + else + { + List list2 = new List(); + list2.Add(5); + list2.Add(3); + list2.Add(0); + IPAddress iPAddress2 = ((IPEndPoint)this._socketEndPoint).Address; + byte[] addressBytes2 = iPAddress2.GetAddressBytes(); + if (addressBytes2.GetLength(0) > 4) + { + list2.Add(4); + for (int n = 0; n < 16; n++) + { + list2.Add(addressBytes2[n]); + } + } + else + { + list2.Add(1); + for (int num = 0; num < 4; num++) + { + list2.Add(addressBytes2[num]); + } + } + list2.Add(0); + list2.Add(0); + this._socket.Send(list2.ToArray(), list2.Count, SocketFlags.None); + this._socket.Receive(array2, array2.Length, SocketFlags.None); + if (array2[0] != 5 || array2[1] != 0) + { + throw new SocketException(errorCode); + } + byte[] array3; + int port; + if (array2[0] != 4) + { + array3 = new byte[4]; + Array.Copy(array2, 4, array3, 0, 4); + port = (int)array2[8] * 256 + (int)array2[9]; + } + else + { + array3 = new byte[16]; + Array.Copy(array2, 4, array3, 0, 16); + port = (int)array2[20] * 256 + (int)array2[21]; + } + iPAddress2 = new IPAddress(array3); + this._remoteUDPEndPoint = new IPEndPoint(iPAddress2, port); + return true; + } + } + + public void SetTcpServer(string server, int port) + { + this._proxy_server = server; + this._proxy_udp_port = port; + } + + public void SetUdpServer(string server, int port) + { + this._proxy_server = server; + this._proxy_udp_port = port; + } + + public void SetUdpEndPoint(IPEndPoint ep) + { + this._remoteUDPEndPoint = ep; + } + + public bool ConnectHttpProxyServer(string strRemoteHost, int iRemotePort, string socks5RemoteUsername, string socks5RemotePassword, string proxyUserAgent) + { + this._proxy = true; + IPAddress iPAddress; + IPAddress.TryParse(strRemoteHost, out iPAddress); + if (iPAddress != null) + { + strRemoteHost = iPAddress.ToString(); + } + string text = ((strRemoteHost.IndexOf(':') >= 0) ? ("[" + strRemoteHost + "]") : strRemoteHost) + ":" + iRemotePort.ToString(); + string str = Convert.ToBase64String(Encoding.UTF8.GetBytes(socks5RemoteUsername + ":" + socks5RemotePassword)); + string text2 = string.Concat(new string[] + { + "CONNECT ", + text, + " HTTP/1.0\r\nHost: ", + text, + "\r\n" + }); + if (!string.IsNullOrEmpty(proxyUserAgent)) + { + text2 = text2 + "User-Agent: " + proxyUserAgent + "\r\n"; + } + text2 += "Proxy-Connection: Keep-Alive\r\n"; + if (socks5RemoteUsername.Length > 0) + { + text2 = text2 + "Proxy-Authorization: Basic " + str + "\r\n"; + } + text2 += "\r\n"; + byte[] bytes = Encoding.UTF8.GetBytes(text2); + this._socket.Send(bytes, bytes.Length, SocketFlags.None); + byte[] array = new byte[1024]; + int num = this._socket.Receive(array, array.Length, SocketFlags.None); + if (num > 13) + { + string[] array2 = Encoding.UTF8.GetString(array, 0, num).Split(new char[] + { + ' ' + }); + if (array2.Length > 1 && array2[1] == "200") + { + return true; + } + } + return false; + } + } +} diff --git a/socks5.Controller/ProxySocketTunLocal.cs b/socks5.Controller/ProxySocketTunLocal.cs new file mode 100644 index 0000000..7bb43a4 --- /dev/null +++ b/socks5.Controller/ProxySocketTunLocal.cs @@ -0,0 +1,52 @@ +using System; +using System.Net.Sockets; +using System.Text; + +namespace socks5.Controller +{ + public class ProxySocketTunLocal : ProxySocketTun + { + public string local_sendback_protocol; + + public ProxySocketTunLocal(Socket socket) : base(socket) + { + } + + public ProxySocketTunLocal(AddressFamily af, SocketType type, ProtocolType protocol) : base(af, type, protocol) + { + } + + public override int Send(byte[] buffer, int size, SocketFlags flags) + { + if (this.local_sendback_protocol != null) + { + if (this.local_sendback_protocol == "http") + { + byte[] bytes = Encoding.UTF8.GetBytes("HTTP/1.1 200 Connection Established\r\n\r\n"); + this._socket.Send(bytes, bytes.Length, SocketFlags.None); + } + else if (this.local_sendback_protocol == "socks5") + { + if (this._socket.AddressFamily == AddressFamily.InterNetwork) + { + byte[] expr_67 = new byte[10]; + expr_67[0] = 5; + expr_67[3] = 1; + byte[] buffer2 = expr_67; + this._socket.Send(buffer2); + } + else + { + byte[] expr_86 = new byte[22]; + expr_86[0] = 5; + expr_86[3] = 4; + byte[] buffer3 = expr_86; + this._socket.Send(buffer3); + } + } + this.local_sendback_protocol = null; + } + return base.SendAll(buffer, size, SocketFlags.None); + } + } +} diff --git a/socks5.Controller/StreamWriterWithTimestamp.cs b/socks5.Controller/StreamWriterWithTimestamp.cs new file mode 100644 index 0000000..50cd33c --- /dev/null +++ b/socks5.Controller/StreamWriterWithTimestamp.cs @@ -0,0 +1,27 @@ +using System; +using System.IO; + +namespace socks5.Controller +{ + public class StreamWriterWithTimestamp : StreamWriter + { + public StreamWriterWithTimestamp(Stream stream) : base(stream) + { + } + + private string a() + { + return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] "; + } + + public override void WriteLine(string value) + { + base.WriteLine(this.a() + value); + } + + public override void Write(string value) + { + base.Write(this.a() + value); + } + } +} diff --git a/socks5.Model/Configuration.cs b/socks5.Model/Configuration.cs new file mode 100644 index 0000000..d946319 --- /dev/null +++ b/socks5.Model/Configuration.cs @@ -0,0 +1,18 @@ +using System; + +namespace socks5.Model +{ + [Serializable] + public class Configuration + { + public bool shareOverLan; + + public int localPort; + + public Configuration() + { + this.localPort = 1081; + this.shareOverLan = true; + } + } +} diff --git a/socks5.Model/LRUCache.cs b/socks5.Model/LRUCache.cs new file mode 100644 index 0000000..c66b936 --- /dev/null +++ b/socks5.Model/LRUCache.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; + +namespace socks5.Model +{ + public class LRUCache + { + protected Dictionary _store = new Dictionary(); + + protected Dictionary _key_2_time = new Dictionary(); + + protected Dictionary _time_2_key = new Dictionary(); + + protected object _lock = new object(); + + protected int _sweep_time; + + public LRUCache(int sweep_time = 3600) + { + this._sweep_time = sweep_time; + } + + public void SetTimeout(int time) + { + this._sweep_time = time; + } + + public bool isTimeout(K key) + { + object @lock = this._lock; + bool result; + lock (@lock) + { + if ((DateTime.Now - this._key_2_time[key]).TotalSeconds > (double)this._sweep_time) + { + result = true; + } + else + { + result = false; + } + } + return result; + } + + public bool ContainsKey(K key) + { + object @lock = this._lock; + bool result; + lock (@lock) + { + result = this._store.ContainsKey(key); + } + return result; + } + + public V Get(K key) + { + object @lock = this._lock; + V result; + lock (@lock) + { + if (this._store.ContainsKey(key)) + { + DateTime dateTime = this._key_2_time[key]; + this._key_2_time.Remove(key); + this._time_2_key.Remove(dateTime); + dateTime = DateTime.Now; + while (this._time_2_key.ContainsKey(dateTime)) + { + dateTime = dateTime.AddTicks(1L); + } + this._time_2_key[dateTime] = key; + this._key_2_time[key] = dateTime; + result = this._store[key]; + } + else + { + result = default(V); + } + } + return result; + } + + public V Set(K key, V val) + { + object @lock = this._lock; + lock (@lock) + { + DateTime dateTime; + if (this._store.ContainsKey(key)) + { + dateTime = this._key_2_time[key]; + this._key_2_time.Remove(key); + this._time_2_key.Remove(dateTime); + } + dateTime = DateTime.Now; + while (this._time_2_key.ContainsKey(dateTime)) + { + dateTime = dateTime.AddTicks(1L); + } + this._time_2_key[dateTime] = key; + this._key_2_time[key] = dateTime; + this._store[key] = val; + } + return val; + } + + public void Del(K key) + { + object @lock = this._lock; + lock (@lock) + { + if (this._store.ContainsKey(key)) + { + DateTime key2 = this._key_2_time[key]; + this._key_2_time.Remove(key); + this._time_2_key.Remove(key2); + this._store.Remove(key); + } + } + } + + public void Sweep() + { + object @lock = this._lock; + lock (@lock) + { + DateTime now = DateTime.Now; + int num = 0; + for (int i = 0; i < 100; i++) + { + bool flag2 = false; + using (Dictionary.Enumerator enumerator = this._time_2_key.GetEnumerator()) + { + if (enumerator.MoveNext()) + { + KeyValuePair current = enumerator.Current; + if ((now - current.Key).TotalSeconds < (double)this._sweep_time) + { + flag2 = true; + } + else + { + this._key_2_time.Remove(current.Value); + this._time_2_key.Remove(current.Key); + this._store.Remove(current.Value); + num++; + } + } + } + if (flag2) + { + break; + } + } + } + } + } +} diff --git a/socks5.csproj b/socks5.csproj new file mode 100644 index 0000000..7bf4b7b --- /dev/null +++ b/socks5.csproj @@ -0,0 +1,53 @@ + + + + {E804010C-28BA-4872-8D0B-8CEE06B446DC} + Debug + AnyCPU + Exe + socks5 + v4.0 + 4 + + + AnyCPU + + + bin\Debug\ + true + full + false + + + bin\Release\ + true + pdbonly + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file