2012-03-26 14 views
2

(GUIとを、例えばCALC.EXE)上(GUI WITH)プロセスの実行。ログオン画面でWindows XPのログオン画面(.NET /のPInvoke)私は、アプリケーションを実行する小さな<strong>サービス</strong>記述する必要が

私はすでにこの問題を見つけました(と答え):あなたは、これがどのように動作するか理解していない場合 Running a process at the Windows 7 Welcome Screen

コードのコメントを読んでください:それはでWindows 7で動作します

 // grab the winlogon process 
     Process winLogon = null; 
     foreach (Process p in Process.GetProcesses()) 
     { 
      if (p.ProcessName.Contains("winlogon")) 
      { 
       winLogon = p; 
       break; 
      } 
     } 
     // grab the winlogon's token 
     IntPtr userToken = IntPtr.Zero; 
     if (!OpenProcessToken(winLogon.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, out userToken)) 
     { 
      log("ERROR: OpenProcessToken returned false - " + Marshal.GetLastWin32Error()); 
     } 

     // create a new token 
     IntPtr newToken = IntPtr.Zero; 
     SECURITY_ATTRIBUTES tokenAttributes = new SECURITY_ATTRIBUTES(); 
     tokenAttributes.nLength = Marshal.SizeOf(tokenAttributes); 
     SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES(); 
     threadAttributes.nLength = Marshal.SizeOf(threadAttributes); 
     // duplicate the winlogon token to the new token 
     if (!DuplicateTokenEx(userToken, 0x10000000, ref tokenAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, 
      TOKEN_TYPE.TokenImpersonation, out newToken)) 
     { 
      log("ERROR: DuplicateTokenEx returned false - " + Marshal.GetLastWin32Error()); 
     } 
     TOKEN_PRIVILEGES tokPrivs = new TOKEN_PRIVILEGES(); 
     tokPrivs.PrivilegeCount = 1; 
     LUID seDebugNameValue = new LUID(); 
     if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out seDebugNameValue)) 
     { 
      log("ERROR: LookupPrivilegeValue returned false - " + Marshal.GetLastWin32Error()); 
     } 
     tokPrivs.Privileges = new LUID_AND_ATTRIBUTES[1]; 
     tokPrivs.Privileges[0].Luid = seDebugNameValue; 
     tokPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
     // escalate the new token's privileges 
     if (!AdjustTokenPrivileges(newToken, false, ref tokPrivs, 0, IntPtr.Zero, IntPtr.Zero)) 
     { 
      log("ERROR: AdjustTokenPrivileges returned false - " + Marshal.GetLastWin32Error()); 
     } 
     PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 
     STARTUPINFO si = new STARTUPINFO(); 
     si.cb = Marshal.SizeOf(si); 
     si.lpDesktop = "Winsta0\\Winlogon"; 
     // start the process using the new token 
     if (!CreateProcessAsUser(newToken, "calc.exe", null, ref tokenAttributes, ref threadAttributes, 
      true, (uint)CreateProcessFlags.CREATE_NEW_CONSOLE | (uint)CreateProcessFlags.INHERIT_CALLER_PRIORITY, IntPtr.Zero, 
      "C:\\Windows\\System32", ref si, out pi)) 
     { 
      log("ERROR: CreateProcessAsUser returned false - " + Marshal.GetLastWin32Error()); 
     } 

     Process _p = Process.GetProcessById(pi.dwProcessId); 
     if (_p != null) 
     { 
      log("Process " + _p.Id + " Name " + _p.ProcessName); 
     } 
     else 
     { 
      log("Process not found"); 
     } 

XP私はCreateProcessAsUser(MSDN:)の呼び出し中にエラー1349 ERROR_BAD_TOKEN_TYPEを取得しましたトークンの種類は、試行された使用には不適切です)。

Windows XPでこれを実現する方法は?上記のコードである必要はありませんが、サービスとして動作するはずです(system-account?)。ご支援のための

おかげ フラクサー

答えて

3

これは間違いなく、特権の問題(Windows Vistaと7はセキュリティにおける顕著な変化を持っている)に関係しています。むしろこのようなWTSQueryUserTokenを介してユーザトークンを取得しようと、winlogon.exeののトークンを取得しようとし、それを偽装より:

WTSQueryUserToken (WTSGetActiveConsoleSessionId(), out userToken); 

上記のステートメントでトークンを取得するために使用されOpenProcessTokenラインを交換してください。

あなたの新しいコードは次のようにする必要があります:

//  if (!OpenProcessToken(winLogon.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | //TOKEN_DUPLICATE, out userToken)) 
//  { 
//   log("ERROR: OpenProcessToken returned false - " + //Marshal.GetLastWin32Error()); 
//  } 

WTSQueryUserToken (WTSGetActiveConsoleSessionId(), out userToken); 

は、このようなあなたのDLLのインポートを行います。

[DllImport("Kernel32.dll", SetLastError = true)] 
[return:MarshalAs(UnmanagedType.U4)] 
public static extern int WTSGetActiveConsoleSessionId (); 

あなたは、私がこのコードをコメントアウト部分を交換するだけで済みます。

+0

あなたの答えをありがとう!トークン '&newToken'でどうすればいいですか? 'CreateNewProcessAsUser'のためだけに使用していますか? – MariusK

+0

私は私の答えを編集します。 –

+0

あなたの編集に感謝します。私はコードを置き換えたが、 'CreateProcessAsUser'を呼び出す際にエラーコード1349を得る。 – MariusK

関連する問題