title: C++ SYSENTER x86 calls in inline assembly
body: <p>I'm about to learning how sysenter on x86 works. and i created a simple console application on x86 platform, which should call the NtWriteVirtualMemory function manually in inline assembly.</p>
  <p>i started with this code here, but it seems that the compiler dont understand the opcode &quot;sysenter&quot; so i decided to <code>_emit</code> them with the bytes for sysenter.(maybe i need to change something in my project settings?) it compiles but when its about to calling the function visual studio gives me an error that my <code>ret</code> is an illegal instruction while executing, and the program stops.</p>
  <p>someone have knowledge how to do that correctly?</p>
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;iostream&gt;
  
  
  
  __declspec(naked) void __KiFastSystemCall()
  {
      __asm
      {
          mov edx, esp
  
          // need to emit &quot;sysenter&quot; because of syntaxerrors, &quot;Opcode&quot;; &quot;newline&quot;
          _emit 0x0F
          _emit 0x34
          
          ret // illegal instructiona after execute?
  
      }
  
  }
  
  void Test_NtWriteVirtualMemory(HANDLE hProcess, PVOID BaseAddress, PVOID Buffer, SIZE_T sizeToWrite, SIZE_T* NumberOfBytesWritten)
  {
      __asm
      {
          push NumberOfBytesWritten
          push sizeToWrite
          push Buffer
          push BaseAddress
          push hProcess
  
          mov eax, 0x3A // Syscall ID NtWriteVirtualMemory in Windows10
  
  
          mov edx, __KiFastSystemCall
          call edx
  
          add esp, 0x14 // 5 push *  4 bytes 20 dec
  
          retn
      }
  }
  
  void Test_NtWriteVirtualMemory(HANDLE hProcess, PVOID BaseAddress, PVOID Buffer, SIZE_T sizeToWrite, SIZE_T* NumberOfBytesWritten)
  {
      __asm
      {
          push NumberOfBytesWritten
          push sizeToWrite
          push Buffer
          push BaseAddress
          push hProcess
  
  
          mov eax, 0x3a // Syscall ID NtWriteVirtualMemory in Windows10
          mov edx, 0x76F88E00
          call edx
          ret 0x14
      }
  }
  
  
  
  int main()
  {
      std::cout &lt;&lt; &quot;Test Hello World\n&quot;;
  
      HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetProcessId(&quot;MyGame.exe&quot;));
      if (hProcess == NULL)
          return false;
  
      DWORD TestAddress = 0x87A0B4; // harcoded
      DWORD TestValue = 4;
      Test_NtWriteVirtualMemory(hProcess, (PVOID)TestAddress, (PVOID)TestValue, sizeof(DWORD), NULL);
  
  
      CloseHandle(hProcess);
  
      return 0;
  }
  
  </code></pre>