@@ -691,7 +691,7 @@ struct VM {
691691
692692 static constexpr size_t MAX_DISABLED_TECHNIQUES = 64 ;
693693 struct disabled_tech_container {
694- enum_flags flags[MAX_DISABLED_TECHNIQUES];
694+ enum_flags flags[MAX_DISABLED_TECHNIQUES] = {} ;
695695 size_t count = 0 ;
696696
697697 VMAWARE_CONSTEXPR_14 void push_back (enum_flags f) {
@@ -721,7 +721,7 @@ struct VM {
721721 VM (VM&&) = delete ;
722722
723723 struct enum_vector {
724- enum_flags data[enum_size];
724+ enum_flags data[enum_size] = {} ;
725725 size_t count = 0 ;
726726
727727 VMAWARE_CONSTEXPR_14 void push_back (enum_flags f) {
@@ -10366,8 +10366,8 @@ struct VM {
1036610366 static std::array<technique, enum_size + 1 > technique_table;
1036710367
1036810368 // specific to VM::add_custom(), where custom techniques will be stored here
10369- static constexpr size_t MAX_CUSTOM_TECHNIQUES = 32 ;
10370- static std::array< custom_technique, MAX_CUSTOM_TECHNIQUES > custom_table;
10369+ static constexpr size_t MAX_CUSTOM_TECHNIQUES = 256 ;
10370+ static std::vector<VM::core:: custom_technique> custom_table; // users should not have a limit of how many functions they should add, this is the only exception of a heap-allocated object in our core
1037110371 static size_t custom_table_size;
1037210372
1037310373 // VM scoreboard table specifically for VM::brand()
@@ -10528,35 +10528,35 @@ struct VM {
1052810528 }
1052910529
1053010530 // for custom VM techniques, won't be used most of the time
10531- for ( size_t i = 0 ; i < custom_table_size; ++i ) {
10532- const auto & technique = custom_table[i];
10531+ if (!core::custom_table. empty () ) {
10532+ for ( const auto & technique : core:: custom_table) {
1053310533
10534- // if cached, return that result
10535- if (memo::is_cached (technique.id )) {
10536- const memo::data_t data = memo::cache_fetch (technique.id );
10534+ // if cached, return that result
10535+ if (memo::is_cached (technique.id )) {
10536+ const memo::data_t data = memo::cache_fetch (technique.id );
1053710537
10538- if (data.result ) {
10539- points += data.points ;
10538+ if (data.result ) {
10539+ points += data.points ;
10540+ }
10541+ continue ;
1054010542 }
1054110543
10542- continue ;
10543- }
10544+ // run the custom technique
10545+ const bool result = technique. run ();
1054410546
10545- // run the custom technique
10546- const bool result = technique.run ();
10547+ // accumulate a few important values
10548+ if (result) {
10549+ points += technique.points ;
10550+ detected_count_num++;
10551+ }
1054710552
10548- // accumulate a few important values
10549- if (result) {
10550- points += technique.points ;
10551- detected_count_num++;
10553+ // cache the result
10554+ memo::cache_store (
10555+ technique.id ,
10556+ result,
10557+ technique.points
10558+ );
1055210559 }
10553-
10554- // cache the result
10555- memo::cache_store (
10556- technique.id ,
10557- result,
10558- technique.points
10559- );
1056010560 }
1056110561
1056210562 return points;
@@ -10568,6 +10568,27 @@ struct VM {
1056810568 * ARGUMENT HANDLER SECTION *
1056910569 * *
1057010570 * ============================================================================================== */
10571+
10572+ /* *
10573+ * basically what this entire recursive variadic template inheritance
10574+ * fuckery does is manage the variadic arguments being given through
10575+ * the arg_handler function, which could either be a std::bitset<N>,
10576+ * a uint8_t, or a combination of both of them. This will handle
10577+ * both argument types and implement them depending on what their
10578+ * types are. If it's a std::bitset<N>, do the |= operation on
10579+ * flag_collector. If it's a uint8_t, simply .set() that into the
10580+ * flag_collector. That's the gist of it.
10581+ *
10582+ * Also I won't even deny, the majority of this section was 90% generated
10583+ * by chatgpt. Can't be arsed with this C++ variadic templatisation shit.
10584+ * Like is it really my fault that I have a hard time understanging C++'s
10585+ * god awful metaprogramming designs? And don't even get me started on SFINAE.
10586+ *
10587+ * You don't need an IQ of 3 digits to realise how dogshit this language
10588+ * is, when you end up in situations where there's a few correct solutions
10589+ * to a problem, but with a billion ways you can do the same thing but in
10590+ * the "wrong" way. I genuinely can't wait for Carbon to come out.
10591+ */
1057110592 public:
1057210593 public:
1057310594 static flagset flag_collector;
@@ -10850,12 +10871,12 @@ struct VM {
1085010871 // lambda to manage exceptions
1085110872 auto throw_error = [&](const char * text) -> void {
1085210873 std::stringstream ss;
10853- #if (VMA_CPP >= 20 && !CLANG)
10874+ #if (VMA_CPP >= 20 && !CLANG)
1085410875 ss << " , error in " << loc.function_name () << " at " << loc.file_name () << " :" << loc.line () << " )" ;
10855- #endif
10876+ #endif
1085610877 ss << " . Consult the documentation's flag handler for VM::check()" ;
1085710878 throw std::invalid_argument (std::string (text) + ss.str ());
10858- };
10879+ };
1085910880
1086010881 // check if flag is out of range
1086110882 if (flag_bit > enum_size) {
@@ -10871,9 +10892,9 @@ struct VM {
1087110892 throw_error (" Flag argument must be a technique flag and not a settings flag" );
1087210893 }
1087310894
10874- #if (VMA_CPP >= 23)
10875- [[assume (flag_bit < technique_end)]];
10876- #endif
10895+ #if (VMA_CPP >= 23)
10896+ [[assume (flag_bit < technique_end)]];
10897+ #endif
1087710898
1087810899 // if the technique is already cached, return the cached value instead
1087910900 if (memo::is_cached (flag_bit)) {
@@ -10897,9 +10918,9 @@ struct VM {
1089710918 detected_count_num++;
1089810919 }
1089910920 }
10900- #ifdef __VMAWARE_DEBUG__
10901- total_points += pair.points ;
10902- #endif
10921+ #ifdef __VMAWARE_DEBUG__
10922+ total_points += pair.points ;
10923+ #endif
1090310924
1090410925 // store the technique result in the cache table
1090510926 memo::cache_store (flag_bit, result, pair.points );
@@ -11259,17 +11280,17 @@ struct VM {
1125911280 [[assume (percent > 0 && percent <= 100 )]];
1126011281 #endif
1126111282
11262- static u16 id = 0 ;
11263- id++;
11283+ size_t current_index = core::custom_table.size ();
1126411284
1126511285 core::custom_technique query{
1126611286 percent,
11267- static_cast <u16 >(static_cast <int >(base_technique_count) + static_cast <int >(id) ),
11287+ static_cast <u16 >(static_cast <int >(base_technique_count) + static_cast <int >(current_index) + 1 ),
1126811288 detection_func
1126911289 };
1127011290
1127111291 technique_count++;
11272- core::custom_table[core::custom_table_size++] = query;
11292+
11293+ core::custom_table.push_back (query);
1127311294 }
1127411295
1127511296
@@ -11781,7 +11802,13 @@ bool VM::memo::conclusion::cached = false;
1178111802std::array<VM::core::brand_entry, VM::core::MAX_BRANDS> VM::core::brand_scoreboard = []() {
1178211803 std::array<VM::core::brand_entry, VM::core::MAX_BRANDS> arr{};
1178311804 size_t i = 0 ;
11784- auto insert = [&](const char * n) noexcept { if (i < MAX_BRANDS) arr[i++] = { n, 0 }; };
11805+
11806+ auto insert = [&](const char * n) noexcept {
11807+ if (i < VM::core::MAX_BRANDS) {
11808+ arr[i] = { n, 0 };
11809+ i++;
11810+ }
11811+ };
1178511812
1178611813 insert (brands::VBOX);
1178711814 insert (brands::VMWARE);
@@ -11904,7 +11931,9 @@ VM::disabled_tech_container VM::disabled_techniques = []() {
1190411931VM::u16 VM::technique_count = base_technique_count;
1190511932
1190611933// this is initialised as empty, because this is where custom techniques can be added at runtime
11907- std::array<VM::core::custom_technique, VM::core::MAX_CUSTOM_TECHNIQUES> VM::core::custom_table{};
11934+ std::vector<VM::core::custom_technique> VM::core::custom_table = {
11935+
11936+ };
1190811937size_t VM::core::custom_table_size = 0 ;
1190911938
1191011939// the 0~100 points are debatable, but we think it's fine how it is. Feel free to disagree
0 commit comments