From 831eab5faa6cf5b3d064fa3741667e1ede1ed660 Mon Sep 17 00:00:00 2001 From: VollRahm Date: Wed, 31 Mar 2021 01:06:59 +0200 Subject: [PATCH] - Added JS Interpreter and auth token logic - Added costura --- src/FodyWeavers.xml | 3 + src/FodyWeavers.xsd | 141 +++++++++++++++++++++++++++++++++ src/JSCode.cs | 15 ++++ src/Program.cs | 7 +- src/R6dbAPI.cs | 109 ++++++++++++++------------ src/UplayNameChecker.csproj | 151 +++++++++++++++++++++++++++++++++++- src/packages.config | 52 +++++++++++++ 7 files changed, 423 insertions(+), 55 deletions(-) create mode 100644 src/FodyWeavers.xml create mode 100644 src/FodyWeavers.xsd create mode 100644 src/JSCode.cs create mode 100644 src/packages.config diff --git a/src/FodyWeavers.xml b/src/FodyWeavers.xml new file mode 100644 index 0000000..5029e70 --- /dev/null +++ b/src/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/FodyWeavers.xsd b/src/FodyWeavers.xsd new file mode 100644 index 0000000..05e92c1 --- /dev/null +++ b/src/FodyWeavers.xsd @@ -0,0 +1,141 @@ + + + + + + + + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with line breaks. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with line breaks. + + + + + The order of preloaded assemblies, delimited with line breaks. + + + + + + This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. + + + + + Controls if .pdbs for reference assemblies are also embedded. + + + + + Controls if runtime assemblies are also embedded. + + + + + Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. + + + + + Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. + + + + + As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. + + + + + Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. + + + + + Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with |. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with |. + + + + + The order of preloaded assemblies, delimited with |. + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/JSCode.cs b/src/JSCode.cs new file mode 100644 index 0000000..d4c32a3 --- /dev/null +++ b/src/JSCode.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace UplayNameChecker +{ + public static class JSCode + { + public const string CharDecrypter = "function decryptChar(d, e, f) { var g = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/' ['split'](''); var h = g['slice'](0, e); var i = g['slice'](0, f); var j = d['split']('')['reverse']()['reduce'](function(a, b, c) { if (h['indexOf'](b) !== -1) return a += h['indexOf'](b) * (Math['pow'](e, c)) }, 0); var k = ''; while (j > 0) { k = i[j % f] + k; j = (j - (j % f)) / f } return k || '0' }"; + public const string StringDecoder = "function decodeFunction(h, u, n, t, e, r) { r = \"\"; for (var i = 0, len = h.length; i < len; i++) { var s = \"\"; while (h[i] !== n[e]) { s += h[i]; i++ } for (var j = 0; j < n.length; j++) s = s.replace(new RegExp(n[j], \"g\"), j); r += String.fromCharCode(decryptChar(s, e, 10) - t) } return decodeURIComponent(escape(r)) }"; + public const string UselessBSCode= "\n};\nwindow.dispatchEvent(new Event('authscript'));\n"; + } +} diff --git a/src/Program.cs b/src/Program.cs index 2782a4a..0b9a394 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -17,7 +17,8 @@ namespace UplayNameChecker static async Task MainAsync() { Log.Info("UplayNameChecker v2 by VollRagm"); - + R6dbAPI api = new R6dbAPI(); + if (!File.Exists("names.txt")) Log.Fatal("names.txt not found."); @@ -42,12 +43,12 @@ namespace UplayNameChecker foreach (var name in namesToCheck) { bool available = await r6db.IsNameAvailable(name); - Log.Critical($"{name} is {(available ? "" : "not ")} available."); + Log.Critical($"{name} is {(available ? "" : "not ")}available."); if (available) File.AppendAllLines("availableNames.txt", new string[] { name }); - await Task.Delay(200); //give the api a little bit to breate :) + await Task.Delay(200); //give the api a little bit to breathe :) } Console.WriteLine(); Log.Info("Written results to availableNames.txt."); diff --git a/src/R6dbAPI.cs b/src/R6dbAPI.cs index b77321e..b08bc93 100644 --- a/src/R6dbAPI.cs +++ b/src/R6dbAPI.cs @@ -1,8 +1,11 @@ -using System; +using Jint; +using Jint.Native; +using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace UplayNameChecker @@ -11,21 +14,31 @@ namespace UplayNameChecker { private HttpClient httpClient = new HttpClient(); private const string URI = "https://api.statsdb.net/r6/namecheck/"; + private string APIKey = ""; public async Task IsNameAvailable(string name) { + if (string.IsNullOrEmpty(APIKey)) APIKey = await GenerateAuthToken(); + try { var reqUri = URI + System.Net.WebUtility.UrlEncode(name); - var timestamp = GetCurrentTimestamp(); - var apiKey = GenerateAuthToken(timestamp); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, reqUri); - request.Headers.Add("x-api-key", apiKey); + request.Headers.Add("x-api-key", APIKey); request.Headers.Add("origin", "https://r6db.net"); var response = await httpClient.SendAsync(request); - return (await response.Content.ReadAsStringAsync()).Contains("exists\":false"); + var str = await response.Content.ReadAsStringAsync(); + + if (str.Contains("Unauthorized")) + { + Log.Info("Error 403, API-Key might have expired, generating new one..."); + APIKey = await GenerateAuthToken(); + return await IsNameAvailable(name); //lets hope this doesnt cause a Stackoverflow Exception :D + } + + return (str.Contains("exists\":false")); } catch (Exception ex) { @@ -34,62 +47,56 @@ namespace UplayNameChecker } } - public string GenerateAuthToken(ulong timestamp) + public async Task GenerateAuthToken() { - var seed = "a3d6b18fa919072d65d890c47b336f1f78fc11c4"; - var sTimestamp = timestamp.ToString(); - var code = ""; + try + { + var paramaters = await RequestAuthGeneratorCode(); + var generateAuthToken = ParseAuthTokenGenerator(paramaters[0], int.Parse(paramaters[1]), paramaters[2], + int.Parse(paramaters[3]), int.Parse(paramaters[4]), + int.Parse(paramaters[5])); - for(int i = 0; i < sTimestamp.Length; i++) + var authcode = generateAuthToken.Invoke(new JsValue(GetCurrentTimestamp())).AsString(); + return Convert.ToBase64String(Encoding.UTF8.GetBytes(authcode)); + } + catch(Exception ex) { - var t = int.Parse(sTimestamp[i].ToString()); - var c = (int)seed[i % seed.Length]; - switch (t) - { - case 0: break; - case 1: - c = c - 1; - break; - case 2: - c = c >> 1; - break; - case 3: - c = c << 1; - break; - case 4: - c = (int)Math.Pow(t, c % 4); - break; - case 5: - c = (int)Math.Round(Math.Sqrt(c)); - break; - case 6: - c = c << t; - goto case 7; - case 7: - c = c - 12; - break; - case 8: - c = 0; - break; - default: - c = -69420; - break; - } - if (c == -69420) continue; - code += c.ToString(); + Log.Fatal("Couldn't generate auth token: " + ex.Message); + return ""; } - var str2 = "authscript:" + code + ":" + timestamp + $":{GetTodaysTimestamp()}"; - return Convert.ToBase64String(Encoding.UTF8.GetBytes(str2)); } - private ulong GetCurrentTimestamp() + private async Task RequestAuthGeneratorCode() { - return (ulong)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; + var response = await httpClient.GetAsync("https://api.statsdb.net/authscript"); + var str = await response.Content.ReadAsStringAsync(); + + //js fixups :/ + str = str.Substring(str.IndexOf("decodeURIComponent(escape(r))}") + "decodeURIComponent(escape(r))}".Length + 2).Replace("))", "").Replace("\"",""); + return str.Split(','); } - private ulong GetTodaysTimestamp() + private JsValue ParseAuthTokenGenerator(string encoded, int unknown0, string key, int unknown1, int unknown2, int unknown3) + { + Engine engine = new Engine(); + + //those 2 shouldn't change + engine.Execute(JSCode.CharDecrypter); + engine.Execute(JSCode.StringDecoder); + + var jsCode = engine.Invoke("decodeFunction", encoded, unknown0, key, unknown1, unknown2, unknown3).AsString() + .Replace(JSCode.UselessBSCode, "") + .Replace("btoa", "") + "}"; // jint has no btoa support + + engine.Execute(jsCode); + + //return callable generateAuthToken function + return engine.GetValue("generateAuthToken"); + } + + private ulong GetCurrentTimestamp() { - return (ulong)DateTime.Today.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; + return (ulong)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; } } } diff --git a/src/UplayNameChecker.csproj b/src/UplayNameChecker.csproj index 9ef36f0..b2edcba 100644 --- a/src/UplayNameChecker.csproj +++ b/src/UplayNameChecker.csproj @@ -1,5 +1,6 @@  + Debug @@ -12,6 +13,8 @@ 512 true true + + AnyCPU @@ -33,16 +36,153 @@ 4 + + ..\..\packages\Costura.Fody.5.1.0\lib\netstandard1.0\Costura.dll + + + ..\..\packages\Jint.2.11.58\lib\net451\Jint.dll + + + ..\..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll + True + True + + + ..\..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll + True + True + + + + ..\..\packages\System.Console.4.3.0\lib\net46\System.Console.dll + True + True + + + ..\..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll + True + True + + + ..\..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll + True + True + + + ..\..\packages\System.IO.4.3.0\lib\net462\System.IO.dll + True + True + + + ..\..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + True + True + + + + ..\..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll + True + True + + + ..\..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll + True + True + + + ..\..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll + True + True + + + ..\..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll + True + True + + + ..\..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll + True + True + + + ..\..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll + True + True + + + ..\..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll + True + True + + + + ..\..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll + True + True + + + ..\..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + True + True + + + ..\..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll + True + True + + + ..\..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll + True + True + + + ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + True + True + + + ..\..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll + True + True + + + ..\..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + ..\..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + ..\..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + ..\..\packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll + True + True + - + + ..\..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll + True + True + + @@ -50,6 +190,15 @@ + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/src/packages.config b/src/packages.config new file mode 100644 index 0000000..0d61387 --- /dev/null +++ b/src/packages.config @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file