title: CreateRemoteThread returning ERROR_ACCESS_DENIED - Windows 7 DLL Injection
body: <p>I'm trying to write a program that uses <code>CreateRemoteThread</code> to inject a dll.</p>
  
  <p>The problem is that CreateRemoteThread is refusing to work. GetLastError() is returning 5 which is ERROR_ACCESS_DENIED. I cant figure why!</p>
  
  <p>I am working from this video <a href="http://www.youtube.com/watch?v=H3O3hmXkt1I" rel="noreferrer">http://www.youtube.com/watch?v=H3O3hmXkt1I</a> . </p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;direct.h&gt;
  #include &lt;Windows.h&gt;
  #include &lt;TlHelp32.h&gt;
  
  using namespace std;
  
  
  char* GetCurrentDir()
  {
      char*   szRet = (char*)malloc(MAX_PATH);
      _getcwd(szRet, MAX_PATH);
      return szRet;
  }
  
  LPCTSTR SzToLPCTSTR(char* szString)
  {
      LPTSTR  lpszRet;
      size_t  size = strlen(szString)+1;
  
      lpszRet = (LPTSTR)malloc(MAX_PATH);
      mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
  
      return lpszRet;
  }
  
  void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDelay)
  {
      HANDLE          hSnap;
      PROCESSENTRY32  peProc;
      BOOL            bAppeared = FALSE;
  
      while(!bAppeared)
      {
          if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
          {
              peProc.dwSize = sizeof(PROCESSENTRY32);
              if(Process32First(hSnap, &amp;peProc))
                  while(Process32Next(hSnap, &amp;peProc) &amp;&amp; !bAppeared)
                      if(!lstrcmp(lpcszProc, peProc.szExeFile))
                          bAppeared = TRUE;
          }
          CloseHandle(hSnap);
          Sleep(dwDelay);
      }
  }
  
  DWORD GetProcessIdByName(LPCTSTR lpcszProc)
  {
      HANDLE          hSnap;
      PROCESSENTRY32  peProc;
      DWORD           dwRet = -1;
  
      if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
      {
          peProc.dwSize = sizeof(PROCESSENTRY32);
          if(Process32First(hSnap, &amp;peProc))
              while(Process32Next(hSnap, &amp;peProc))
                  if(!lstrcmp(lpcszProc, peProc.szExeFile))
                      dwRet = peProc.th32ProcessID;
      }
      CloseHandle(hSnap);
  
      return dwRet;
  }
  
  BOOL InjectDll(DWORD dwPid, char* szDllPath)
  {
      DWORD   dwMemSize;
      HANDLE  hProc;
      LPVOID  lpRemoteMem, lpLoadLibrary;
      BOOL    bRet = FALSE;
  
      if((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) != NULL)
      {
          dwMemSize = strlen(szDllPath);
          if((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
              if(WriteProcessMemory(hProc, lpRemoteMem, szDllPath, dwMemSize, NULL))
              {
                  lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
                  if(CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
                  {
                      bRet = TRUE;
                  }
                  cout &lt;&lt; GetLastError();
              }
      }
      CloseHandle(hProc);
  
      return bRet;
  }
  
  int main()
  {
      char    szProc[MAX_PATH], szDll[MAX_PATH];
      char*   szDllPath = (char*)malloc(MAX_PATH);
      LPTSTR  lpszProc = NULL;
  
      for(;;)
      {
          cout &lt;&lt; "Process: ";
          cin &gt;&gt; szProc;
          cout &lt;&lt; "DLL: ";
          cin &gt;&gt; szDll;
  
          szDllPath = GetCurrentDir();
          strcat_s(szDllPath, MAX_PATH, "\\");
          strcat_s(szDllPath, MAX_PATH, szDll);
  
          cout &lt;&lt; "Waiting for process.. ." &lt;&lt; szDllPath &lt;&lt; " " &lt;&lt; szDll &lt;&lt; endl;
          WaitForProcessToAppear(SzToLPCTSTR(szProc), 100);
          if(InjectDll(GetProcessIdByName(SzToLPCTSTR(szProc)), szDllPath))
              cout &lt;&lt; "Injection Succeeded!" &lt;&lt; endl;
          else
              cout &lt;&lt; "Injection Failed!" &lt;&lt; endl;
          cout &lt;&lt; "\n";
  
      }
  
      return 0;
  </code></pre>
  
  <p>After a fair amount of googling I cant find a reason why this should not be working.</p>
  
  <p>Does CreateRemoteThread not work under Windows 7 ? 
  If it does, have I made any obvious mistakes ?</p>