@@ -9989,65 +9989,24 @@ struct VM {
99899989
99909990
99919991 /* *
9992- * @brief Check if the CPU is capable of running certain instructions successfully
9993- * @category Windows
9994- * @implements VM::CPU_HEURISTIC
9995- */
9992+ * @brief Check if the CPU is capable of running certain instructions successfully
9993+ * @category Windows
9994+ * @implements VM::CPU_HEURISTIC
9995+ */
99969996 [[nodiscard]] static bool cpu_heuristic () {
9997- using NtAllocateVirtualMemory_t = NTSTATUS (__stdcall*)(HANDLE, PVOID*, ULONG_PTR, PSIZE_T, ULONG, ULONG);
9998- using NtProtectVirtualMemory_t = NTSTATUS (__stdcall*)(HANDLE, PVOID*, PSIZE_T, ULONG, PULONG);
9999- using NtFreeVirtualMemory_t = NTSTATUS (__stdcall*)(HANDLE, PVOID*, PSIZE_T, ULONG);
10000- using NtFlushInstructionCache_t = NTSTATUS (__stdcall*)(HANDLE, PVOID, SIZE_T);
10001-
100029997 // 1) Check for commonly disabled instructions on patches
10003- const HMODULE ntdll = util::get_ntdll ();
10004- if (!ntdll) return false ;
10005-
10006- const char * names[] = { " NtAllocateVirtualMemory" , " NtProtectVirtualMemory" , " NtFlushInstructionCache" , " NtFreeVirtualMemory"
10007- };
10008- void * funcs[ARRAYSIZE (names)] = {};
10009- util::get_function_address (ntdll, names, funcs, ARRAYSIZE (names));
10010-
10011- const auto pNtAllocateVirtualMemory = reinterpret_cast <NtAllocateVirtualMemory_t>(funcs[0 ]);
10012- const auto pNtProtectVirtualMemory = reinterpret_cast <NtProtectVirtualMemory_t>(funcs[1 ]);
10013- const auto pNtFlushInstructionCache = reinterpret_cast <NtFlushInstructionCache_t>(funcs[2 ]);
10014- const auto pNtFreeVirtualMemory = reinterpret_cast <NtFreeVirtualMemory_t>(funcs[3 ]);
10015-
10016- if (!pNtAllocateVirtualMemory || !pNtProtectVirtualMemory || !pNtFlushInstructionCache || !pNtFreeVirtualMemory) {
10017- return false ;
10018- }
10019-
10020- PVOID freeBase = nullptr ;
10021- SIZE_T freeSize = 0 ;
10022-
100239998 bool ok = true ;
10024- alignas (16 ) unsigned char plaintext[16 ] = {
10025- 0x00 ,0x11 ,0x22 ,0x33 , 0x44 ,0x55 ,0x66 ,0x77 ,
10026- 0x88 ,0x99 ,0xAA ,0xBB , 0xCC ,0xDD ,0xEE ,0xFF
10027- };
10028- alignas (16 ) unsigned char key[16 ] = {
10029- 0x0F ,0x0E ,0x0D ,0x0C , 0x0B ,0x0A ,0x09 ,0x08 ,
10030- 0x07 ,0x06 ,0x05 ,0x04 , 0x03 ,0x02 ,0x01 ,0x00
10031- };
10032- alignas (16 ) unsigned char out[16 ] = { 0 };
10033-
10034- __try {
10035- __m128i block = _mm_loadu_si128 (reinterpret_cast <const __m128i*>(plaintext));
10036- __m128i key_vec = _mm_loadu_si128 (reinterpret_cast <const __m128i*>(key));
100379999
10038- __m128i tmp = _mm_xor_si128 (block, key_vec) ;
10039- tmp = _mm_aesenc_si128 (tmp, key_vec );
10000+ u32 a = 0 , b = 0 , c = 0 , d = 0 ;
10001+ cpu::cpuid (a, b, c, d, 1u );
1004010002
10041- _mm_storeu_si128 (reinterpret_cast <__m128i*>(out), tmp);
10042- }
10043- __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION
10044- ? EXCEPTION_EXECUTE_HANDLER
10045- : EXCEPTION_CONTINUE_SEARCH) {
10003+ constexpr u32 AES_NI_BIT = 1u << 25 ;
10004+ if ((c & AES_NI_BIT) == 0 ) {
1004610005 ok = false ;
1004710006 }
1004810007
1004910008 if (!ok) {
10050- debug (" CPU_HEURISTIC: Failed to handle AES encryption correctly " );
10009+ debug (" CPU_HEURISTIC: CPU does not report AES " );
1005110010 return true ;
1005210011 }
1005310012
@@ -10082,6 +10041,8 @@ struct VM {
1008210041
1008310042 LPVOID amd_target_mem = nullptr ;
1008410043 LPVOID exec_mem = nullptr ;
10044+ PVOID freeBase = nullptr ;
10045+ SIZE_T freeSize = 0 ;
1008510046
1008610047 const bool claimed_amd = cpu::is_amd ();
1008710048 const bool claimed_intel = cpu::is_intel ();
@@ -10099,6 +10060,27 @@ struct VM {
1009910060 // one cache line = 64 bytes
1010010061 const SIZE_T targetSize = 64 ;
1010110062
10063+ const HMODULE ntdll = util::get_ntdll ();
10064+ if (!ntdll) return false ;
10065+
10066+ const char * names[] = { " NtAllocateVirtualMemory" , " NtProtectVirtualMemory" , " NtFlushInstructionCache" , " NtFreeVirtualMemory"
10067+ };
10068+ void * funcs[ARRAYSIZE (names)] = {};
10069+ util::get_function_address (ntdll, names, funcs, ARRAYSIZE (names));
10070+
10071+ using NtAllocateVirtualMemory_t = NTSTATUS (__stdcall*)(HANDLE, PVOID*, ULONG_PTR, PSIZE_T, ULONG, ULONG);
10072+ using NtProtectVirtualMemory_t = NTSTATUS (__stdcall*)(HANDLE, PVOID*, PSIZE_T, ULONG, PULONG);
10073+ using NtFreeVirtualMemory_t = NTSTATUS (__stdcall*)(HANDLE, PVOID*, PSIZE_T, ULONG);
10074+ using NtFlushInstructionCache_t = NTSTATUS (__stdcall*)(HANDLE, PVOID, SIZE_T);
10075+ const auto pNtAllocateVirtualMemory = reinterpret_cast <NtAllocateVirtualMemory_t>(funcs[0 ]);
10076+ const auto pNtProtectVirtualMemory = reinterpret_cast <NtProtectVirtualMemory_t>(funcs[1 ]);
10077+ const auto pNtFlushInstructionCache = reinterpret_cast <NtFlushInstructionCache_t>(funcs[2 ]);
10078+ const auto pNtFreeVirtualMemory = reinterpret_cast <NtFreeVirtualMemory_t>(funcs[3 ]);
10079+
10080+ if (!pNtAllocateVirtualMemory || !pNtProtectVirtualMemory || !pNtFlushInstructionCache || !pNtFreeVirtualMemory) {
10081+ return false ;
10082+ }
10083+
1010210084 {
1010310085 PVOID base = nullptr ;
1010410086 SIZE_T sz = targetSize;
0 commit comments