1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
3#[repr(usize)]
4pub enum VMBrand {
5 #[default]
6 Invalid = 0,
7 VBox,
8 VMware,
9 VMwareExpress,
10 VMwareESX,
11 VMwareGSX,
12 VMwareWorkstation,
13 VMwareFusion,
14 VMwareHard,
15 Bhyve,
16 KVM,
17 QEMU,
18 QEMUKVM,
19 KVMHyperV,
20 QEMUKVMHyperV,
21 HyperV,
22 HyperVVPC,
23 Parallels,
24 Xen,
25 ACRN,
26 QNX,
27 Hybrid,
28 Sandboxie,
29 Docker,
30 Wine,
31 VPC,
32 Anubis,
33 JoeBox,
34 ThreatExpert,
35 CWSandbox,
36 Comodo,
37 Bochs,
38 NVMM,
39 BSDVMM,
40 IntelHAXM,
41 Unisys,
42 LMHS,
43 Cuckoo,
44 BlueStacks,
45 Jailhouse,
46 AppleVZ,
47 IntelKGT,
48 AzureHyperV,
49 SimpleVisor,
50 HyperVRoot,
51 UML,
52 PowerVM,
53 GCE,
54 OpenStack,
55 KubeVirt,
56 AWSNitro,
57 Podman,
58 WSL,
59 OpenVZ,
60 Barevisor,
61 HyperPlatform,
62 MiniVisor,
63 IntelTDX,
64 LKVM,
65 AMDSEV,
66 AMDSEVes,
67 AMDSEVsnp,
68 NekoProject,
69 NoirVisor,
70 Qihoo,
71 NSJail,
72 DBVM,
73 UTM,
74 Compaq,
75 Insignia,
76 Connectix,
77 Count,
79}
80
81#[rustfmt::skip]
82static BRAND_STRINGS: &[&str] = &[
83 "Unknown",
84 "VirtualBox",
85 "VMware",
86 "VMware Express",
87 "VMware ESX",
88 "VMware GSX",
89 "VMware Workstation",
90 "VMware Fusion",
91 "VMware (with VmwareHardenedLoader)",
92 "bhyve",
93 "KVM",
94 "QEMU",
95 "QEMU+KVM",
96 "KVM Hyper-V Enlightenment",
97 "QEMU+KVM Hyper-V Enlightenment",
98 "Microsoft Hyper-V",
99 "Microsoft Virtual PC/Hyper-V",
100 "Parallels",
101 "Xen HVM",
102 "ACRN",
103 "QNX hypervisor",
104 "Hybrid Analysis",
105 "Sandboxie",
106 "Docker",
107 "Wine",
108 "Virtual PC",
109 "Anubis",
110 "JoeBox",
111 "ThreatExpert",
112 "CWSandbox",
113 "Comodo",
114 "Bochs",
115 "NetBSD NVMM",
116 "OpenBSD VMM",
117 "Intel HAXM",
118 "Unisys s-Par",
119 "Lockheed Martin LMHS",
120 "Cuckoo",
121 "BlueStacks",
122 "Jailhouse",
123 "Apple VZ",
124 "Intel KGT (Trusty)",
125 "Microsoft Azure Hyper-V",
126 "SimpleVisor",
127 "Hyper-V artifact (host with Hyper-V enabled)",
128 "User-mode Linux",
129 "IBM PowerVM",
130 "Google Compute Engine (KVM)",
131 "OpenStack (KVM)",
132 "KubeVirt (KVM)",
133 "AWS Nitro System (KVM-based)",
134 "Podman",
135 "WSL",
136 "OpenVZ",
137 "Barevisor",
138 "HyperPlatform",
139 "MiniVisor",
140 "Intel TDX",
141 "LKVM",
142 "AMD SEV",
143 "AMD SEV-ES",
144 "AMD SEV-SNP",
145 "Neko Project II",
146 "NoirVisor",
147 "Qihoo 360 Sandbox",
148 "nsjail",
149 "DBVM",
150 "UTM",
151 "Compaq FX!32",
152 "Insignia RealPC",
153 "Connectix Virtual PC",
154];
155
156impl VMBrand {
157 pub fn as_str(self) -> &'static str {
158 let idx = self as usize;
159 if idx < BRAND_STRINGS.len() {
160 BRAND_STRINGS[idx]
161 } else {
162 "Unknown"
163 }
164 }
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
170#[repr(u8)]
171pub enum Technique {
172 GpuCapabilities = 0,
174 AcpiSignature = 1,
175 PowerCapabilities = 2,
176 DiskSerial = 3,
177 Ivshmem = 4,
178 Drivers = 5,
179 Handles = 6,
180 VirtualProcessors = 7,
181 HypervisorQuery = 8,
182 Audio = 9,
183 Display = 10,
184 Dll = 11,
185 VmwareBackdoor = 12,
186 Wine = 13,
187 VirtualRegistry = 14,
188 Mutex = 15,
189 DeviceString = 16,
190 VpcInvalid = 17,
191 VmwareStr = 18,
192 Gamarue = 19,
193 CuckooDir = 20,
194 CuckooPipe = 21,
195 BootLogo = 22,
196 Trap = 23,
197 Ud = 24,
198 Blockstep = 25,
199 DbvmHypercall = 26,
200 KernelObjects = 27,
201 Nvram = 28,
202 Edid = 29,
203 CpuHeuristic = 30,
204 Clock = 31,
205 Msr = 32,
206 KvmInterception = 33,
207 Breakpoint = 34,
208 SystemRegisters = 35,
210 Firmware = 36,
211 Devices = 37,
212 Azure = 38,
213 SmbiosVmBit = 39,
215 Kmsg = 40,
216 Cvendor = 41,
217 QemuFwCfg = 42,
218 Systemd = 43,
219 Ctype = 44,
220 Dockerenv = 45,
221 Dmidecode = 46,
222 Dmesg = 47,
223 Hwmon = 48,
224 LinuxUserHost = 49,
225 VmwareIomem = 50,
226 VmwareIoports = 51,
227 VmwareScsi = 52,
228 VmwareDmesg = 53,
229 QemuVirtualDmi = 54,
230 QemuUsb = 55,
231 HypervisorDir = 56,
232 UmlCpu = 57,
233 VboxModule = 58,
234 SysinfoProc = 59,
235 DmiScan = 60,
236 PodmanFile = 61,
237 WslProc = 62,
238 FileAccessHistory = 63,
239 Mac = 64,
240 NsjailPid = 65,
241 BluestacksFolders = 66,
242 AmdSevMsr = 67,
243 Temperature = 68,
244 Processes = 69,
245 ThreadCount = 70,
247 MacMemsize = 71,
249 MacIokit = 72,
250 MacSip = 73,
251 IoregGrep = 74,
252 Hwmodel = 75,
253 MacSys = 76,
254 HypervisorBit = 77,
256 Vmid = 78,
257 ThreadMismatch = 79,
258 Timer = 80,
259 CpuBrand = 81,
260 HypervisorStr = 82,
261 CpuidSignature = 83,
262 BochsCpu = 84,
263 KgtSignature = 85,
264}
265
266impl Technique {
267 pub const COUNT: usize = 86;
268}
269
270#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
272pub struct Flagset {
273 lo: u64,
274 hi: u64,
275}
276
277impl Flagset {
278 pub fn new() -> Self {
279 Self::default()
280 }
281
282 pub fn from_techniques(techs: &[Technique]) -> Self {
284 let mut fs = Self::new();
285 for &t in techs {
286 fs.set(t);
287 }
288 fs
289 }
290
291 pub fn set(&mut self, t: Technique) {
293 let idx = t as u8;
294 if idx < 64 {
295 self.lo |= 1u64 << idx;
296 } else {
297 self.hi |= 1u64 << (idx - 64);
298 }
299 }
300
301 pub fn is_set(&self, t: Technique) -> bool {
303 let idx = t as u8;
304 if idx < 64 {
305 (self.lo >> idx) & 1 != 0
306 } else {
307 (self.hi >> (idx - 64)) & 1 != 0
308 }
309 }
310
311 pub fn is_empty(&self) -> bool {
313 self.lo == 0 && self.hi == 0
314 }
315
316 pub fn all() -> Self {
318 let mut fs = Self::new();
320 let count = Technique::COUNT as u8;
321 for idx in 0..count {
322 if idx < 64 {
323 fs.lo |= 1u64 << idx;
324 } else {
325 fs.hi |= 1u64 << (idx - 64);
326 }
327 }
328 fs
329 }
330}
331
332#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
334pub enum HyperXState {
335 #[default]
336 Unknown,
337 RealVM,
338 ArtifactVM,
339 Enlightenment,
340}
341
342pub const THRESHOLD_SCORE: u32 = 150;
344pub const HIGH_THRESHOLD_SCORE: u32 = 300;
345pub const VM_SHORTCUT: bool = true;