Skip to content

Commit bbde575

Browse files
committed
update: redesigned VM::brand(), cmake warning fixes, and code clarity changes
1 parent c1e9f23 commit bbde575

File tree

4 files changed

+92
-85
lines changed

4 files changed

+92
-85
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,5 @@ list.txt
6868
/.vs/VSWorkspaceState.json
6969
TODO.md
7070
auxiliary/path*
71-
packages/
71+
packages/
72+
auxiliary/test.cpp

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ elseif(APPLE)
9191
elseif(LINUX)
9292
if(CMAKE_BUILD_TYPE MATCHES "Debug")
9393
message(STATUS "Build set to debug mode")
94-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fmax-errors=5 -DDEBUG -O0 -fsanitize=address,leak")
94+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -DDEBUG -O0 -fsanitize=address,leak")
9595
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
9696
message(STATUS "Build set to release mode")
9797
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g0 -O2")

src/cli.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ int main(int argc, char* argv[]) {
12911291
VM::add_custom(35, anyrun_directory);
12921292

12931293
if (arg_count == 0) {
1294-
general(VM::NULL_ARG, VM::NULL_ARG, VM::DYNAMIC);
1294+
general(VM::NULL_ARG, VM::NULL_ARG, VM::NULL_ARG);
12951295
return 0;
12961296
}
12971297

@@ -1399,6 +1399,8 @@ int main(int argc, char* argv[]) {
13991399
const VM::enum_flags all = (arg_bitset.test(ALL) ? VM::ALL : VM::NULL_ARG);
14001400
const VM::enum_flags dynamic = (arg_bitset.test(DYNAMIC) ? VM::DYNAMIC : VM::NULL_ARG);
14011401

1402+
std::cout << "\n\n\n\nDYNAMIC: " << static_cast<u32>(dynamic) << "\n\n\n";
1403+
14021404
if (returners > 0) { // at least one of the options are set
14031405
if (returners > 1) { // more than 2 options are set
14041406
std::cerr << "--stdout, --percent, --detect, --brand, --type, and --conclusion must NOT be a combination, choose only a single one\n";

src/vmaware.hpp

Lines changed: 86 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,29 +3091,30 @@ struct VM {
30913091
}
30923092

30933093
struct brand {
3094-
static char brand_cache[512];
3094+
static std::string brand_cache;
30953095
static bool cached;
30963096

3097-
static void store(const char* s) {
3098-
str_copy(brand_cache, s, sizeof(brand_cache));
3097+
static void store(const std::string& s) {
3098+
brand_cache = s;
30993099
cached = true;
3100+
debug("VM::brand(): cached brand string");
31003101
}
31013102

31023103
static bool is_cached() { return cached; }
3103-
static const char* fetch() { return brand_cache; }
3104+
static std::string fetch() { return brand_cache; }
31043105
};
31053106

31063107
struct multi_brand {
3107-
static char brand_cache[1024];
3108+
static std::string brand_cache;
31083109
static bool cached;
31093110

3110-
static void store(const char* s) {
3111-
str_copy(brand_cache, s, sizeof(brand_cache));
3111+
static void store(const std::string& s) {
3112+
brand_cache = s;
31123113
cached = true;
31133114
}
31143115

31153116
static bool is_cached() { return cached; }
3116-
static const char* fetch() { return brand_cache; }
3117+
static std::string fetch() { return brand_cache; }
31173118
};
31183119

31193120
// helper specifically for conclusion strings
@@ -4706,7 +4707,10 @@ struct VM {
47064707
#endif
47074708
};
47084709

4709-
thread_local u32 aux = 0;
4710+
#if (MSVC)
4711+
thread_local u32 aux = 0;
4712+
#endif
4713+
47104714
auto cpuid = [](unsigned int leaf) noexcept -> u64 {
47114715
#if (MSVC)
47124716
// make regs volatile so writes cannot be optimized out, if this isn't added and the code is compiled in release mode, cycles would be around 40 even under Hyper-V
@@ -11933,8 +11937,7 @@ struct VM {
1193311937
debug("VM::brand(): returned multi brand from cache");
1193411938
return memo::multi_brand::fetch();
1193511939
}
11936-
}
11937-
else {
11940+
} else {
1193811941
if (memo::brand::is_cached()) {
1193911942
debug("VM::brand(): returned brand from cache");
1194011943
return memo::brand::fetch();
@@ -11990,6 +11993,15 @@ struct VM {
1199011993
std::array<brand_element_t, core::MAX_BRANDS> active_brands;
1199111994
size_t active_count = 0;
1199211995

11996+
// wrappers for simplicity, these will most likely be inlined by the compiler anyway
11997+
auto fetch_brand_name = [&](const size_t index) -> const char* {
11998+
return active_brands[index].first;
11999+
};
12000+
12001+
auto fetch_brand_score = [&](const size_t index) -> brand_score_t {
12002+
return active_brands[index].second;
12003+
};
12004+
1199312005
for (size_t i = 0; i < core::brand_count; ++i) {
1199412006
if (core::brand_scoreboard[i].score > 0) {
1199512007
active_brands[active_count++] = std::make_pair(core::brand_scoreboard[i].name, core::brand_scoreboard[i].score);
@@ -11998,48 +12010,62 @@ struct VM {
1199812010

1199912011
// if all brands have a point of 0, return "Unknown"
1200012012
if (active_count == 0) {
12013+
memo::brand::store(brands::NULL_BRAND);
1200112014
return brands::NULL_BRAND;
1200212015
}
12003-
12004-
// if there's only a single brand, return it immediately
12005-
// We skip this early return if the single brand is HYPERV_ARTIFACT,
12006-
// so that the removal logic at the end of the function can process it
12007-
if (active_count == 1 && active_brands[0].first != TMP_HYPERV_ARTIFACT) {
12008-
return active_brands[0].first;
12009-
}
12010-
12016+
1201112017
// helper lambdas for array manipulation
12012-
auto find_index = [&](const char* name) noexcept -> int {
12018+
auto find_index = [&](const char* name) noexcept -> i8 {
1201312019
for (size_t i = 0; i < active_count; ++i) {
1201412020
// pointer comparison is sufficient for static brands
12015-
if (active_brands[i].first == name) return static_cast<int>(i);
12021+
if (fetch_brand_name(i) == name) {
12022+
return static_cast<i8>(i);
12023+
}
1201612024
}
1201712025
return -1;
1201812026
};
1201912027

12020-
auto remove_at = [&](int index) noexcept {
12028+
auto remove_at = [&](const u8 index) noexcept {
1202112029
if (index >= 0 && index < static_cast<int>(active_count)) {
1202212030
if (index != static_cast<int>(active_count - 1)) {
1202312031
active_brands[static_cast<size_t>(index)] = active_brands[active_count - 1];
1202412032
}
1202512033
active_count--;
1202612034
}
1202712035
};
12028-
12036+
1202912037
// remove Hyper-V artifacts if found with other brands
1203012038
if (active_count > 1) {
12031-
const int idx = find_index(TMP_HYPERV_ARTIFACT);
12039+
const i8 idx = find_index(TMP_HYPERV_ARTIFACT);
1203212040
if (idx != -1) {
1203312041
remove_at(idx);
1203412042
}
1203512043
}
1203612044

12045+
// if there's only a single brand, return it immediately
12046+
// We skip this early return if the single brand is HYPERV_ARTIFACT,
12047+
// but we must also nullify the result if the score is above 0,
12048+
// which would most likely indicate a hardened VM instead and return "Unknown".
12049+
if (active_count == 1) {
12050+
const std::string& initial_brand = fetch_brand_name(0);
12051+
12052+
if (initial_brand == TMP_HYPERV_ARTIFACT) {
12053+
if (score > 0) {
12054+
memo::brand::store(brands::NULL_BRAND);
12055+
return brands::NULL_BRAND;
12056+
}
12057+
}
12058+
12059+
memo::brand::store(initial_brand);
12060+
return initial_brand;
12061+
}
12062+
1203712063
// merge 2 brands
1203812064
auto merge = [&](const char* a, const char* b, const char* result) noexcept -> void {
12039-
int idx_a = find_index(a);
12065+
i8 idx_a = find_index(a);
1204012066
if (idx_a == -1) return;
1204112067

12042-
int idx_b = find_index(b);
12068+
i8 idx_b = find_index(b);
1204312069
if (idx_b == -1) return;
1204412070

1204512071
remove_at(idx_a);
@@ -12051,11 +12077,11 @@ struct VM {
1205112077

1205212078
// same as above, but for 3
1205312079
auto triple_merge = [&](const char* a, const char* b, const char* c, const char* result) noexcept -> void {
12054-
int idx_a = find_index(a);
12080+
i8 idx_a = find_index(a);
1205512081
if (idx_a == -1) return;
12056-
int idx_b = find_index(b);
12082+
i8 idx_b = find_index(b);
1205712083
if (idx_b == -1) return;
12058-
int idx_c = find_index(c);
12084+
i8 idx_c = find_index(c);
1205912085
if (idx_c == -1) return;
1206012086

1206112087
remove_at(idx_a);
@@ -12064,20 +12090,10 @@ struct VM {
1206412090

1206512091
active_brands[active_count++] = std::make_pair(result, 2);
1206612092
};
12067-
12068-
// some edgecase handling for Hyper-V and VirtualPC
12069-
int idx_hv = find_index(TMP_HYPERV);
12070-
int idx_vpc = find_index(TMP_VPC);
12071-
12072-
if (idx_hv != -1 && idx_vpc != -1) {
12073-
// existence is confirmed by index != -1
12074-
merge(TMP_VPC, TMP_HYPERV, TMP_HYPERV_VPC);
12075-
}
12076-
else if (idx_hv != -1 && idx_vpc == -1) {
12077-
// logic handled by merge check essentially
12078-
}
12079-
12093+
1208012094
// Brand post-processing / merging
12095+
merge(TMP_VPC, TMP_HYPERV, TMP_HYPERV_VPC);
12096+
1208112097
merge(TMP_AZURE, TMP_HYPERV, TMP_AZURE);
1208212098
merge(TMP_AZURE, TMP_VPC, TMP_AZURE);
1208312099
merge(TMP_AZURE, TMP_HYPERV_VPC, TMP_AZURE);
@@ -12086,6 +12102,11 @@ struct VM {
1208612102
merge(TMP_KVM, TMP_HYPERV, TMP_KVM_HYPERV);
1208712103
merge(TMP_QEMU, TMP_HYPERV, TMP_QEMU_KVM_HYPERV);
1208812104
merge(TMP_QEMU_KVM, TMP_HYPERV, TMP_QEMU_KVM_HYPERV);
12105+
12106+
merge(TMP_KVM, TMP_HYPERV_VPC, TMP_KVM_HYPERV);
12107+
merge(TMP_QEMU, TMP_HYPERV_VPC, TMP_QEMU_KVM_HYPERV);
12108+
merge(TMP_QEMU_KVM, TMP_HYPERV_VPC, TMP_QEMU_KVM_HYPERV);
12109+
1208912110
merge(TMP_KVM, TMP_KVM_HYPERV, TMP_KVM_HYPERV);
1209012111
merge(TMP_QEMU, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
1209112112
merge(TMP_QEMU_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
@@ -12105,61 +12126,44 @@ struct VM {
1210512126
merge(TMP_VMWARE_HARD, TMP_GSX, TMP_VMWARE_HARD);
1210612127
merge(TMP_VMWARE_HARD, TMP_WORKSTATION, TMP_VMWARE_HARD);
1210712128

12108-
// determine threshold (150 or 300)
12109-
u16 confirmed_vm_threshold = threshold_score;
12110-
if (core::is_enabled(flags, HIGH_THRESHOLD)) {
12111-
confirmed_vm_threshold = high_threshold_score;
12112-
}
12113-
12114-
// check if Hyper-V artifact is present
12115-
const int idx_art = find_index(TMP_HYPERV_ARTIFACT);
12116-
if (idx_art != -1) {
12117-
// If score confirms it is a VM, remove the "Artifact" label (because we're in a VM, not in a host machine)
12118-
// so it falls back to "Unknown" if no other brands exist
12119-
if (score >= confirmed_vm_threshold) {
12120-
remove_at(idx_art);
12121-
}
12122-
}
12123-
1212412129
if (active_count > 1) {
1212512130
std::sort(active_brands.begin(), active_brands.begin() + static_cast<std::ptrdiff_t>(active_count), [](
1212612131
const brand_element_t& a,
1212712132
const brand_element_t& b
12128-
) {
12129-
return a.second > b.second;
12133+
) {
12134+
return a.second > b.second; // .second = brand score (usually u8)
1213012135
});
1213112136
}
1213212137

1213312138
#ifdef __VMAWARE_DEBUG__
1213412139
for (size_t i = 0; i < active_count; ++i) {
12135-
debug("scoreboard: ", (int)active_brands[i].second, " : ", active_brands[i].first);
12140+
debug("scoreboard: ", (brand_score_t)fetch_brand_score(i), " : ", fetch_brand_name(i));
1213612141
}
1213712142
#endif
1213812143

12139-
if (active_count > 0) {
12140-
if (!is_multiple) {
12141-
memo::brand::store(active_brands[0].first);
12142-
debug("VM::brand(): cached brand string");
12143-
return memo::brand::fetch();
12144-
}
12145-
else {
12146-
char* buffer = memo::multi_brand::brand_cache;
12147-
buffer[0] = '\0';
12148-
const size_t buf_size = sizeof(memo::multi_brand::brand_cache);
12144+
if (active_count == 0) {
12145+
memo::brand::store(brands::NULL_BRAND);
12146+
return brands::NULL_BRAND;
12147+
}
1214912148

12150-
str_copy(buffer, active_brands[0].first, buf_size);
12151-
for (size_t i = 1; i < active_count; i++) {
12152-
str_cat(buffer, " or ", buf_size);
12153-
str_cat(buffer, active_brands[i].first, buf_size);
12154-
}
12149+
if (is_multiple) {
12150+
std::string buffer = {};
12151+
buffer += fetch_brand_name(0);
1215512152

12156-
memo::multi_brand::cached = true;
12157-
debug("VM::brand(): cached multiple brand string");
12158-
return memo::multi_brand::fetch();
12153+
for (size_t i = 1; i < active_count; i++) {
12154+
buffer += " or ";
12155+
buffer += fetch_brand_name(i);
1215912156
}
12157+
12158+
memo::multi_brand::store(buffer);
12159+
debug("VM::brand(): cached multiple brand string");
12160+
return buffer;
1216012161
}
1216112162

12162-
return brands::NULL_BRAND;
12163+
const std::string& result_brand = fetch_brand_name(0);
12164+
12165+
memo::brand::store(result_brand);
12166+
return result_brand;
1216312167
}
1216412168

1216512169

@@ -12945,8 +12949,8 @@ size_t VM::core::brand_count = []() -> size_t {
1294512949

1294612950
// initial definitions for cache items because C++ forbids in-class initializations
1294712951
std::array<VM::memo::cache_entry, VM::enum_size + 1> VM::memo::cache_table{};
12948-
char VM::memo::brand::brand_cache[512] = { 0 };
12949-
char VM::memo::multi_brand::brand_cache[1024] = { 0 };
12952+
std::string VM::memo::brand::brand_cache = "";
12953+
std::string VM::memo::multi_brand::brand_cache = "";
1295012954
char VM::memo::cpu_brand::brand_cache[128] = { 0 };
1295112955
char VM::memo::bios_info::manufacturer[256] = { 0 };
1295212956
char VM::memo::bios_info::model[128] = { 0 };

0 commit comments

Comments
 (0)