title: WriteProcessMemory to SYSTEM process with SeDebugPrivilege enabled. (C, Vista)
body: <p>I'm interested in injecting DLLs into SYSTEM owned processes on my Vista machine. I'm going about this using the traditional method of VirtualAllocEx, WriteProcessMemory and CreateRemoteThread.  However, because this will be operating on SYSTEM processes, I enable SeDebugPivilege on the injecting process before opening the target process.</p>
  
  <pre><code>
  int EnableDebugPriv(LPCTSTR name) {
      HANDLE hToken;
      LUID luid;
      TOKEN_PRIVILEGES tkp;
  
      if(!OpenProcessToken(GetCurrentProcess(),
                           /*TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY*/
                           TOKEN_ALL_ACCESS,
                           &hToken))
          return 0;
  
      if(!LookupPrivilegeValue(NULL,name,&luid))
          return 0;
  
      tkp.PrivilegeCount=1;
      tkp.Privileges[0].Luid=luid;
      tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
  
      if(!AdjustTokenPrivileges(hToken,false,&tkp,sizeof(tkp),NULL,NULL))
      {
          printf("!AdjustTokenPrivileges - %d\n",GetLastError());
          return 0;
      }
      if(GetLastError()==ERROR_NOT_ALL_ASSIGNED)
      {
          return 0;
      }
  
      CloseHandle(hToken);
      return 1;
  }
  </code></pre>
  
  <p>Where the <code>SE_DEBUG_NAME</code> constant is passed as name.</p>
  
  <p>After enabling SeDebugPrivilege, I go through the process of opening the target process, locating LoadLibrary, allocating space, writing the DLL path to memory, and creating the thread (checking all return values along the way):</p>
  
  <pre><code>
  if(NULL==(p=OpenProcess(PROCESS_ALL_ACCESS,FALSE,(DWORD)pid)))
  ...
  if(NULL==(loadLib=(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), 
                                           "LoadLibraryA")))
  ...
  if(NULL==(dllBuff=(LPVOID)VirtualAllocEx(p,
                                           NULL,
                                           strlen(dllPath)+1,
                                           MEM_RESERVE|MEM_COMMIT,
                                           PAGE_READWRITE)))
  ...
  if(NULL==WriteProcessMemory(p,
                              (LPVOID)dllBuff,
                              dllPath,
                              strlen(dllPath),
                              &written))
  ...
  if(!CreateRemoteThread(p,
                         NULL,
                         NULL,
                         (LPTHREAD_START_ROUTINE)loadLib,
                         (LPVOID)dllBuff,
                         NULL,
                         NULL))
  ...
  </code></pre>
  
  <p><code>dllPath</code> is a char* of the DLL's path (obviously), and <code>pid</code> is the PID of the target process.  Both of these values are taken in through the command line and validated before being used.</p>
  
  <p>The problem I'm having is that nothing is returning errors until CreateRemoteThread, which is returning an 8 ("Not enough storage").  HOWEVER, WriteProcessMemory is NOT writing any bytes to the process. After the call the written variable is always 0.  No bytes are being written, but the function is not failing. I'm not sure why this is happening. I looked into other privileges, like the SeRestorePrivilege which promises write access to all processes, but nothing works.</p>
  
  <p>I'm executing this program with Administrator rights.</p>
  
  <p>Note: this WriteProcessMemory and CreateRemoteThread problem only happen when I run this program against higher privileged users (SYSTEM, LOCAL SERVICE, etc...). It works perfectly against a program owned by me (same privileges).</p>
  
  <p>Edit: Here's a link to the whole source. <a href="http://pastebin.com/m77110d8e" rel="nofollow noreferrer">http://pastebin.com/m77110d8e</a> There's not much else there besides basic error checking, but maybe it will help?</p>