title: CreateRemoteThread succeeded, but LoadLibrary failed for some target app
body: <p>I am using CreateRemoteThread() + LoadLibrary() method to inject code.
  Everything is OK when I running my injector in my Windows7 64bit OS laptop, and it still work in Windows Server 2012 R2 64bit for some target app.</p>
  
  <p>BUT, in this Windows Server 2012 environment, for some target app, which is old MFC application, the CreateRemoteThread succeeded but the DllMain did not get called and I found the LoadLibrary() seems failed, by using GetExitCodeThread() on the created remote thread.</p>
  
  <p>For the memory to write in target process, I counted the terminating 0 byte.</p>
  
  <p>Also, I already knew the kernel32.dll address are the same for both the Windows 7 and Windows Server 2012, using the method introduced in below URL answer part.</p>
  
  <p><a href="https://stackoverflow.com/questions/39261436/">CreateRemoteThread fails,maybe the lpBaseAddress in the target process is invalid,but it is allocated by the system?</a></p>
  
  <p>The GetExitCodeThread() below got an zero exit code.</p>
  
  <pre><code>    HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
      if(hThread == NULL) {
          OutputDebugString(_T("Error: the remote thread could not be created.\n"));
          writeLog("Error: the remote thread could not be created.");
      }
      else {
          DWORD dResult = WAIT_OBJECT_0;
          dResult = WaitForSingleObject(hThread, 1000*3);// the thread may already exited, so do not wait INFINITE
          DWORD dwExitCode = 0;
          GetExitCodeThread(hThread, &amp;dwExitCode);
          if(dwExitCode == 0)
          {
              writeLog("Error: LoadLibraryA failed.");
          }
          else
          {
              OutputDebugString(_T("Success: the remote thread was successfully created.\n"));
              writeLog("Success: the remote thread was successfully created.");
          }
      }
  </code></pre>
  
  <p>Do you have any idea what should I suspect next?</p>
  
  <p>To summarize, in below diagram, you can see the only fail is only when I run injector on Windows Server 2012 to inject into some old MFC application.</p>
  
  <p><a href="https://i.stack.imgur.com/8PvTb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8PvTb.png" alt="results on the 2 OS"></a></p>
  
  <p>In below diagram, there is the information about HOW old the MFC application is:</p>
  
  <p><a href="https://i.stack.imgur.com/3hEff.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3hEff.png" alt="dlls the old MFC using"></a></p>
  
  <p>I am trying to provide enough information, kindly let me know if you need some more information.</p>
  
  <p>below is the complete code for inject my dll:</p>
  
  <pre><code>void inject(int procID, char* pszHookDll)
  {
      g_nTargetProcId = procID;
      HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
      g_hTargetProc = process;
  
      BOOL bInit = SymInitialize(g_hTargetProc, g_sPdbFolder, TRUE);// for analysing the information spy.dll send out
  
      if(process == NULL) {
          writeLog("Error: the specified process couldn't be found.");
      }
      /*
      * Get address of the LoadLibrary function.
      */
      LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
      if(addr == NULL) {
          writeLog("Error: the LoadLibraryA function was not found inside kernel32.dll library.");
      }
      //addr = getProcAddrInTargetProcess(procID, process);
  
      /*
      * Allocate new memory region inside the process's address space.
      */
      int nBufSize = strlen(pszHookDll)+1;
      LPVOID arg = (LPVOID)VirtualAllocEx(process, NULL, nBufSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
      if(arg == NULL) {
          writeLog("Error: the memory could not be allocated inside the chosen process.");
      }
  
      /*
      * Write the argument to LoadLibraryA to the process's newly allocated memory region.
      */
      int n = WriteProcessMemory(process, arg, pszHookDll, nBufSize, NULL);
      if(n == 0) {
          writeLog("Error: there was no bytes written to the process's address space.");
      }
  
      /*
      * Inject our DLL into the process's address space.
      */
      HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
      if(hThread == NULL) {
          writeLog("Error: the remote thread could not be created.");
      }
      else {
          DWORD dResult = WAIT_OBJECT_0;
          dResult = WaitForSingleObject(hThread, 1000*3);
          DWORD dwExitCode = 0;
          GetExitCodeThread(hThread, &amp;dwExitCode);
          if(dwExitCode == 0)
          {
              writeLog("Error: LoadLibraryA failed.");
          }
          else
          {
              OutputDebugString(_T("Success: the remote thread was successfully created.\n"));
              writeLog("Success: the remote thread was successfully created.");
          }
      }
  
      /*
      * Close the handle to the process, becuase we've already injected the DLL.
      */
      //CloseHandle(process);close after symcleanup
  }
  </code></pre>