Skip to content

Commit a545c89

Browse files
authored
Merge pull request #84 from kernelwernel/dev
Dev
2 parents d0cd36a + b8b5de5 commit a545c89

5 files changed

Lines changed: 2591 additions & 458 deletions

File tree

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
- [ ] make a man file in markdown for the cli tool
3333
- [ ] implement smbios version technique [here](https://github.com/Print3M/Anti-VM/blob/eb524ed89e783b36c149acc450b2350d4198b06b/detectors.cpp#L88)
3434
- [ ] implement a display size technique for linux with EDID
35-
- [ ] implement a technique that matches the CPU product name and match it with a database of core counts for that specific CPU product
35+
- [X] implement a technique that matches the CPU product name and match it with a database of core counts for that specific CPU product
3636
- [ ] add usage example in the .hpp file directly below the banner
3737

3838
# Distant plans

auxiliary/updater.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,7 @@ def update(filename):
8888
" * - start of internal VM detection techniques => line __TECHNIQUES__",
8989
" * - struct for internal core components => line __CORE__",
9090
" * - start of public VM detection functions => line __PUBLIC__",
91-
" * - start of externally defined variables => line __EXTERNAL__",
92-
" */",
93-
""
91+
" * - start of externally defined variables => line __EXTERNAL__"
9492
]
9593

9694
# replace the macro strings with the file line numbers

src/cli.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ int main(int argc, char* argv[]) {
238238
checker(VM::UPTIME, "uptime");
239239
checker(VM::ODD_CPU_THREADS, "unusual thread count");
240240
checker(VM::INTEL_THREAD_MISMATCH, "Intel thread count mismatch");
241+
checker(VM::XEON_THREAD_MISMATCH, "Intel Xeon thread count mismatch");
241242

242243
std::printf("\n");
243244

src/vmaware.hpp

Lines changed: 225 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,36 @@
1919
* - Full credits: https://github.com/kernelwernel/VMAware#credits-and-contributors-%EF%B8%8F
2020
* - License: GPL-3.0
2121
*
22+
*
2223
* ================================ SECTIONS ==================================
23-
* - enums for publicly accessible techniques => line 252
24-
* - struct for internal cpu operations => line 447
25-
* - struct for internal memoization => line 684
26-
* - struct for internal utility functions => line 757
27-
* - struct for internal core components => line 5713
28-
* - start of internal VM detection techniques => line 1423
29-
* - start of public VM detection functions => line 5786
30-
* - start of externally defined variables => line 6053
24+
* - enums for publicly accessible techniques => line 282
25+
* - struct for internal cpu operations => line 480
26+
* - struct for internal memoization => line 772
27+
* - struct for internal utility functions => line 834
28+
* - struct for internal core components => line 7073
29+
* - start of internal VM detection techniques => line 1510
30+
* - start of public VM detection functions => line 7187
31+
* - start of externally defined variables => line 7487
32+
*
33+
*
34+
* ================================ EXAMPLE ==================================
35+
#include "vmaware.hpp"
36+
#include <iostream>
37+
38+
int main() {
39+
if (VM::detect()) {
40+
std::cout << "Virtual machine detected!" << std::endl;
41+
std::cout << "VM name: " << VM::brand() << std::endl;
42+
} else {
43+
std::cout << "Running in baremetal" << std::endl;
44+
}
45+
46+
std::cout << "VM certainty: " << (int)VM::percentage() << "%" << std::endl;
47+
}
48+
3149
*/
3250

51+
3352
#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))
3453
#define MSVC 1
3554
#define LINUX 0
@@ -348,7 +367,7 @@ struct VM {
348367
UPTIME,
349368
ODD_CPU_THREADS,
350369
INTEL_THREAD_MISMATCH,
351-
INTEL_XEON_THREAD_MISMATCH,
370+
XEON_THREAD_MISMATCH,
352371
EXTREME,
353372
NO_MEMO,
354373
WIN_HYPERV_DEFAULT,
@@ -589,20 +608,22 @@ struct VM {
589608
#endif
590609
}
591610

592-
[[nodiscard]] static std::string get_model() {
611+
struct model_struct {
612+
bool found;
613+
bool is_xeon;
614+
bool is_i_series;
615+
std::string string;
616+
};
617+
618+
[[nodiscard]] static model_struct get_model() {
593619
const std::string brand = get_brand();
594620

595621
constexpr const char* intel_i_series_regex = "i[0-9]-[A-Z0-9]{1,7}";
596622
constexpr const char* intel_xeon_series_regex = "[DEW]-[A-Z0-9]{1,7}";
597623

598-
constexpr std::array<const char*, 2> regex_templates {{
599-
intel_i_series_regex,
600-
intel_xeon_series_regex
601-
}};
602-
603624
std::string match_str = "";
604625

605-
for (const auto regex : regex_templates) {
626+
auto match = [&](const char* regex) -> bool {
606627
std::regex pattern(regex);
607628

608629
auto words_begin = std::sregex_iterator(brand.begin(), brand.end(), pattern);
@@ -614,11 +635,32 @@ struct VM {
614635
}
615636

616637
if (!match_str.empty()) {
617-
return match_str;
638+
return true;
639+
}
640+
641+
return false;
642+
};
643+
644+
bool found = false;
645+
bool is_xeon = false;
646+
bool is_i_series = false;
647+
std::string string = "";
648+
649+
if (cpu::is_intel()) {
650+
if (match(intel_i_series_regex)) {
651+
found = true;
652+
is_i_series = true;
653+
string = match_str;
654+
} else if (match(intel_xeon_series_regex)) {
655+
found = true;
656+
is_xeon = true;
657+
string = match_str;
618658
}
619659
}
620660

621-
return "";
661+
// no AMD (for now)
662+
663+
return model_struct{ found, is_xeon, is_i_series, string };
622664
};
623665

624666
#if (CPP >= 17)
@@ -5877,7 +5919,7 @@ struct VM {
58775919
/**
58785920
* @brief Check for CPUs that don't match their thread count
58795921
* @category All, x86
5880-
* @links https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
5922+
* @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
58815923
*/
58825924
[[nodiscard]] static bool intel_thread_mismatch() try {
58835925
if (core::disabled(INTEL_THREAD_MISMATCH)) {
@@ -5891,15 +5933,19 @@ struct VM {
58915933
return false;
58925934
}
58935935

5894-
const std::string model = cpu::get_model();
5936+
const cpu::model_struct model = cpu::get_model();
58955937

5896-
debug("INTEL_THREAD_MISMATCH: CPU model = ", model);
5938+
if (!model.found) {
5939+
return false;
5940+
}
58975941

5898-
if (model.empty()) {
5942+
if (!model.is_i_series) {
58995943
return false;
59005944
}
59015945

5902-
std::unordered_map<std::string, u8> thread_database = {
5946+
debug("INTEL_THREAD_MISMATCH: CPU model = ", model.string);
5947+
5948+
const std::unordered_map<std::string, u8> thread_database = {
59035949
// i3 series
59045950
{ "i3-1000G1", 4 },
59055951
{ "i3-1000G4", 4 },
@@ -6856,11 +6902,11 @@ struct VM {
68566902
};
68576903

68586904
// basically means "if there's 0 matches in the database, return false"
6859-
if (thread_database.count(model) == 0) {
6905+
if (thread_database.count(model.string) == 0) {
68606906
return false;
68616907
}
68626908

6863-
const u8 threads = thread_database.at(model);
6909+
const u8 threads = thread_database.at(model.string);
68646910

68656911
debug("INTEL_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
68666912

@@ -6873,6 +6919,158 @@ struct VM {
68736919
}
68746920

68756921

6922+
/**
6923+
* @brief Check for Intel Xeon CPUs that don't match their thread count
6924+
* @category All, x86
6925+
* @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
6926+
*/
6927+
[[nodiscard]] static bool xeon_thread_mismatch() try {
6928+
if (core::disabled(XEON_THREAD_MISMATCH)) {
6929+
return false;
6930+
}
6931+
6932+
#if (!x86)
6933+
return false;
6934+
#else
6935+
if (!cpu::is_intel()) {
6936+
return false;
6937+
}
6938+
6939+
const cpu::model_struct model = cpu::get_model();
6940+
6941+
if (!model.found) {
6942+
return false;
6943+
}
6944+
6945+
if (!model.is_i_series) {
6946+
return false;
6947+
}
6948+
6949+
debug("XEON_THREAD_MISMATCH: CPU model = ", model.string);
6950+
6951+
const std::unordered_map<std::string, u8> xeon_thread_database = {
6952+
// Xeon D
6953+
{ "D-1518", 8 },
6954+
{ "D-1520", 8 },
6955+
{ "D-1521", 8 },
6956+
{ "D-1527", 8 },
6957+
{ "D-1528", 12 },
6958+
{ "D-1529", 8 },
6959+
{ "D-1531", 12 },
6960+
{ "D-1537", 16 },
6961+
{ "D-1539", 16 },
6962+
{ "D-1540", 16 },
6963+
{ "D-1541", 16 },
6964+
{ "D-1548", 16 },
6965+
{ "D-1557", 24 },
6966+
{ "D-1559", 24 },
6967+
{ "D-1567", 24 },
6968+
{ "D-1571", 32 },
6969+
{ "D-1577", 32 },
6970+
{ "D-1581", 32 },
6971+
{ "D-1587", 32 },
6972+
{ "D-1513N", 8 },
6973+
{ "D-1523N", 8 },
6974+
{ "D-1533N", 12 },
6975+
{ "D-1543N", 16 },
6976+
{ "D-1553N", 16 },
6977+
{ "D-1602", 4 },
6978+
{ "D-1612", 8 },
6979+
{ "D-1622", 8 },
6980+
{ "D-1627", 8 },
6981+
{ "D-1632", 16 },
6982+
{ "D-1637", 12 },
6983+
{ "D-1623N", 8 },
6984+
{ "D-1633N", 12 },
6985+
{ "D-1649N", 16 },
6986+
{ "D-1653N", 16 },
6987+
{ "D-2141I", 16 },
6988+
{ "D-2161I", 24 },
6989+
{ "D-2191", 36 },
6990+
{ "D-2123IT", 8 },
6991+
{ "D-2142IT", 16 },
6992+
{ "D-2143IT", 16 },
6993+
{ "D-2163IT", 24 },
6994+
{ "D-2173IT", 28 },
6995+
{ "D-2183IT", 32 },
6996+
{ "D-2145NT", 16 },
6997+
{ "D-2146NT", 16 },
6998+
{ "D-2166NT", 24 },
6999+
{ "D-2177NT", 28 },
7000+
{ "D-2187NT", 32 },
7001+
7002+
// Xeon E
7003+
{ "E-2104G", 4 },
7004+
{ "E-2124", 4 },
7005+
{ "E-2124G", 4 },
7006+
{ "E-2126G", 6 },
7007+
{ "E-2134", 8 },
7008+
{ "E-2136", 12 },
7009+
{ "E-2144G", 8 },
7010+
{ "E-2146G", 12 },
7011+
{ "E-2174G", 8 },
7012+
{ "E-2176G", 12 },
7013+
{ "E-2186G", 12 },
7014+
{ "E-2176M", 12 },
7015+
{ "E-2186M", 12 },
7016+
{ "E-2224", 4 },
7017+
{ "E-2224G", 4 },
7018+
{ "E-2226G", 6 },
7019+
{ "E-2234", 8 },
7020+
{ "E-2236", 12 },
7021+
{ "E-2244G", 8 },
7022+
{ "E-2246G", 12 },
7023+
{ "E-2274G", 8 },
7024+
{ "E-2276G", 12 },
7025+
{ "E-2278G", 16 },
7026+
{ "E-2286G", 12 },
7027+
{ "E-2288G", 16 },
7028+
{ "E-2276M", 12 },
7029+
{ "E-2286M", 16 },
7030+
7031+
// Xeon W
7032+
{ "W-2102", 4 },
7033+
{ "W-2104", 4 },
7034+
{ "W-2123", 8 },
7035+
{ "W-2125", 8 },
7036+
{ "W-2133", 12 },
7037+
{ "W-2135", 12 },
7038+
{ "W-2140B", 16 },
7039+
{ "W-2145", 16 },
7040+
{ "W-2150B", 20 },
7041+
{ "W-2155", 20 },
7042+
{ "W-2170B", 28 },
7043+
{ "W-2175", 28 },
7044+
{ "W-2191B", 36 },
7045+
{ "W-2195", 36 },
7046+
{ "W-3175X", 56 },
7047+
{ "W-3223", 16 },
7048+
{ "W-3225", 16 },
7049+
{ "W-3235", 24 },
7050+
{ "W-3245", 32 },
7051+
{ "W-3245M", 32 },
7052+
{ "W-3265", 48 },
7053+
{ "W-3265M", 48 },
7054+
{ "W-3275", 56 },
7055+
{ "W-3275M", 56 }
7056+
};
7057+
7058+
if (xeon_thread_database.count(model.string) == 0) {
7059+
return false;
7060+
}
7061+
7062+
const u8 threads = xeon_thread_database.at(model.string);
7063+
7064+
debug("XEON_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
7065+
7066+
return (std::thread::hardware_concurrency() != threads);
7067+
#endif
7068+
}
7069+
catch (...) {
7070+
debug("INTEL_THREAD_MISMATCH: catched error, returned false");
7071+
return false;
7072+
}
7073+
68767074
struct core {
68777075
MSVC_DISABLE_WARNING(PADDING)
68787076
struct technique {
@@ -7462,7 +7660,8 @@ const std::map<VM::u8, VM::core::technique> VM::core::table = {
74627660
{ VM::MUTEX, { 85, VM::mutex }},
74637661
{ VM::UPTIME, { 10, VM::uptime }},
74647662
{ VM::ODD_CPU_THREADS, { 80, VM::odd_cpu_threads }},
7465-
{ VM::INTEL_THREAD_MISMATCH, { 70, VM::intel_thread_mismatch }}
7663+
{ VM::INTEL_THREAD_MISMATCH, { 85, VM::intel_thread_mismatch }},
7664+
{ VM::XEON_THREAD_MISMATCH, { 85, VM::xeon_thread_mismatch }}
74667665

74677666
// __TABLE_LABEL, add your technique above
74687667
// { VM::FUNCTION, { POINTS, FUNCTION_POINTER }}

0 commit comments

Comments
 (0)