0

Вызов приложения с графическим интерфейсом с помощьюCreateProcessAsUser не устанавливая пользователя правильно

[DllImport(
    "advapi32.dll", 
    EntryPoint = "CreateProcessAsUser", 
    SetLastError = true, 
    CharSet = CharSet.Ansi, 
    CallingConvention = CallingConvention.StdCall)] 
private static extern bool CreateProcessAsUser(
    IntPtr hToken, 
    string lpApplicationName, 
    string lpCommandLine, 
    ref SECURITY_ATTRIBUTES lpProcessAttributes, 
    ref SECURITY_ATTRIBUTES lpThreadAttributes, 
    bool bInheritHandle, 
    int dwCreationFlags, 
    IntPtr lpEnvironment, 
    string lpCurrentDirectory, 
    ref STARTUPINFO lpStartupInfo, 
    out PROCESS_INFORMATION lpProcessInformation); 


bool result = CreateProcessAsUser(
    hUserTokenDup, 
    null, 
    applicationName + " " + arguments, 
    ref sa,     // pointer to process SECURITY_ATTRIBUTES 
    ref sa,     // pointer to thread SECURITY_ATTRIBUTES 
    false,     // handles are not inheritable 
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,  // creation flags 
    IntPtr.Zero,   // pointer to new environment block 
    null,     // name of current directory 
    ref si,     // pointer to STARTUPINFO structure 
    out procInfo);   // receives information about new process 

от службы LocalSystem Windows, работает. Окно появляется на экране пользователя, но пользователь процесса по-прежнему является LocalSystem. Есть ли способ изменить это?

PS По просьбе я hUserTokenDup от

[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] 
private static extern bool DuplicateTokenEx(
    IntPtr ExistingTokenHandle, 
    uint dwDesiredAccess, 
    ref SECURITY_ATTRIBUTES lpThreadAttributes, 
    int TokenType, 
    int ImpersonationLevel, 
    ref IntPtr DuplicateTokenHandle); 

DuplicateTokenEx(
    hPToken, 
    MAXIMUM_ALLOWED, 
    ref sa, 
    (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, 
    (int)TOKEN_TYPE.TokenPrimary, 
    ref hUserTokenDup); 
+0

Не могли бы вы уточнить, откуда вы получаете hUserTokenDup? Я считаю, что суть проблемы. –

+0

@Josh Я добавил желаемую информацию –

+0

Где находится "hPToken"? –

ответ

2

В моей службе, я использую WTSGetActiveConsoleSessionId(), WTSQueryUserToken() и DuplicationTokenEx() перед вызовом CreateProcessAsUser(), и она отлично работает для меня. Происшедший процесс запускается в учетной записи пользователя, а не в учетной записи службы.

+0

Из методов, которые вы используете перечисленные, единственный, который я не использую, это 'WTSQueryUserToken'. Я займусь этим. –

+0

Вместо этого я использую 'OpenProcess' и' OpenProcessToken' –

+1

Можете ли вы показать этот код? Кроме того, что-то еще я использую, которым вы не являетесь, является 'CreateEnvironmentBlock()', который затем используется с флагом 'CREATE_UNICODE_ENVIRONMENT'' CreateProcessAsUser() '(я также использую флаг' DETACHED_PROCESS'). –

2

Похоже, вместо того, чтобы использовать DuplicateTokenEx, чтобы скопировать текущий маркер, вам нужно позвонить LogonUser, чтобы получить маркер, представляющий целевого пользователя. Простое вызов DuplicateTokenEx создаст токен для пользователя локальной системы. Если я правильно понял ваш фрагмент кода.

Кроме того, поскольку вы нацеливаете интерактивного пользователя, рассмотрите функцию CreateProcessWithLogonW.

+0

У меня нет учетных данных пользователя, требуемых 'LogonUser' и' CreateProcessWithLogonW' –

0

Благодаря Реми Лебо за подсказку, чтобы использовать WTSGetActiveConsoleSessionId()

Функция ниже должны вызвать из «System» -user как победа-службы и нуждается в бегущую физической консоли (обычный пользователь -logon-session, сеанс удаленного терминала). Вы можете начать с win-сервиса новый процесс в текущем сеансе входа в систему с этими атрибутами безопасности пользователя. Если вызывающий абонент не является «Системой», тогда невозможно запустить новый процесс с олицетворяемыми пользователями.

public static bool StartProcessAndBypassUAC(ProcessStartInfo ps, out PROCESS_INFORMATION procInfo) 
{ 
// code based on http://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-32-and-64-bit-Archite 
    uint winlogonPid = 0; 
    IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero; 
    procInfo = new PROCESS_INFORMATION(); 

    // obtain the currently active session id; every logged on user in the system has a unique session id 
    uint dwSessionId = WTSGetActiveConsoleSessionId(); 

    if (dwSessionId == 0xFFFFFFFF) 
    { 
     // no physical console 
     return false; 
    } 

    if (!WTSQueryUserToken(dwSessionId, ref hPToken)) 
    { 
     return false ; 
    } 

    // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser 
    // I would prefer to not have to use a security attribute variable and to just 
    // simply pass null and inherit (by default) the security attributes 
    // of the existing token. However, in C# structures are value types and therefore 
    // cannot be assigned the null value. 
    SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 
    sa.Length = Marshal.SizeOf(sa); 

    // copy the access token of the winlogon process; the newly created token will be a primary token 
    if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup)) 
    { 
     CloseHandle(hProcess); 
     CloseHandle(hPToken); 
     return false; 
    } 

    // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning 
    // the window station has a desktop that is invisible and the process is incapable of receiving 
    // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user 
    // interaction with the new process. 
    STARTUPINFO si = new STARTUPINFO(); 
    si.cb = (int)Marshal.SizeOf(si); 
    si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop 

    // flags that specify the priority and creation method of the process 
    int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; 

    // create a new process in the current user's logon session 
    bool result = CreateProcessAsUser(hUserTokenDup,  // client's access token 
            null,     // file to execute 
            ps.FileName,   // command line 
            ref sa,     // pointer to process SECURITY_ATTRIBUTES 
            ref sa,     // pointer to thread SECURITY_ATTRIBUTES 
            true,     // handles are not inheritable 
            dwCreationFlags,  // creation flags 
            IntPtr.Zero,   // pointer to new environment block 
            ps.WorkingDirectory, // name of current directory 
            ref si,     // pointer to STARTUPINFO structure 
            out procInfo   // receives information about new process 
            ); 

    // invalidate the handles 
    CloseHandle(hProcess); 
    CloseHandle(hPToken); 
    CloseHandle(hUserTokenDup); 

    return result; // return the result 
} 
Смежные вопросы