@@ -8886,30 +8886,34 @@ struct VM {
88868886
88878887 constexpr SIZE_T stubSize = 44 ;
88888888 const bool isAmd = cpu::is_amd ();
8889+
8890+ // allocate RW memory so we can write template + immediates
88898891 void * stub = VirtualAlloc (nullptr , stubSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
88908892 if (!stub) {
88918893 return false ;
88928894 }
88938895
8896+ // copy the template while writable
88948897 if (isAmd) {
88958898 memcpy (stub, amdTemplate, stubSize);
88968899 }
88978900 else {
88988901 memcpy (stub, intelTemplate, stubSize);
88998902 }
89008903
8904+ // patch in the immediate values
8905+ *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 2 ) = PW1;
8906+ *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 12 ) = PW3;
8907+ *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 22 ) = reinterpret_cast <u64 >(static_cast <void *>(&vmcallInfo));
8908+ *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 35 ) = reinterpret_cast <u64 >(static_cast <void *>(&vmcallResult));
8909+
89018910 DWORD oldProtect = 0 ;
89028911 if (!VirtualProtect (stub, stubSize, PAGE_EXECUTE_READ, &oldProtect)) {
89038912 VirtualFree (stub, 0 , MEM_RELEASE);
89048913 return false ;
89058914 }
8906- FlushInstructionCache (GetCurrentProcess (), stub, stubSize);
89078915
8908- // patch in the immediate values (PW1, PW3, &vmcallInfo, &vmcallResult) at the correct offsets:
8909- *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 2 ) = PW1;
8910- *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 12 ) = PW3;
8911- *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 22 ) = reinterpret_cast <u64 >(static_cast <void *>(&vmcallInfo));
8912- *reinterpret_cast <u64 *>(reinterpret_cast <u8 *>(stub) + 35 ) = reinterpret_cast <u64 >(static_cast <void *>(&vmcallResult));
8916+ FlushInstructionCache (GetCurrentProcess (), stub, stubSize);
89138917
89148918 // lambda that executes the stub (Intel or AMD) and checks for the CE signature
89158919 auto tryPass = [&]() -> bool {
0 commit comments