Delphi+WinAPI. Не получается передать привилегии запускаемому процессу

Добрый день.

Использую следующий код на Delphi для запуска процесса на рабочем столе активного пользователя (пользователь, «владеющий» на момент запуска монитором) из-под службы в Windows 7 (служба запущена с правами системы):

function WTSQueryUserToken(SessionId: DWORD; phToken: pHandle):bool;stdcall;external 'wtsapi32.dll';
function WTSGetActiveConsoleSessionId: DWORD; stdcall; external 'Kernel32.dll';
...
procedure RunApp(FilePath:string);
var
  hToken:THandle;
  si:STARTUPINFO;
  pi:PROCESS_INFORMATION;
begin
  if WTSQueryUserToken(WtsGetActiveConsoleSessionID,@hToken) then
    begin
      ZeroMemory(@si,SizeOf(si));
      si.cb:=SizeOf(si);
      si.lpDesktop:=nil;
      CreateProcessAsUser(hToken,nil,PANSIChar(FilePath),nil,nil,False,0,nil,nil,si,pi);
      CloseHandle(hToken);
    end;
end;

Хочу допилить этот код для того, чтобы передать запускаемому процессу права родителя (тобиш системные привилегии от службы), но сохранив условие запуска на рабочем столе активного пользователя. Пытаюсь сделать это через имперсонацию праймари токена:

WTSQueryUserToken(WtsGetActiveConsoleSessionID,@hToken)
...
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_EXECUTE,sysToken);
DuplicateTokenEx(sysToken,MAXIMUM_ALLOWED,nil,SecurityImpersonation,TokenPrimary,hToken);
...
CreateProcessAsUser(hToken,nil,PANSIChar(FilePath),nil,nil,False,0,nil,nil,si,pi);

Но в результате все равно получаю процесс, запущенный с правами активного пользователя.
С WinAPI знаком плохо. Скорее всего, что-то упустил или вообще не в ту сторону пошел. Помогите с решением данной задачи.
  • Вопрос задан
  • 4657 просмотров
Пригласить эксперта
Ответы на вопрос 2
Комментировать
ruzzz
@ruzzz
C++/Python
Вместо текущего процесса OpenProcessToken(GetCurrentProcess()...
Берем токен от winlogon.exe с нужным SessionID.
Находим pid например так:
...
    while (Process32Next(hSnapshot, &entry))
    {
        if (_wcsicmp(entry.szExeFile, exePath) == 0 &&
            ProcessIdToSessionId(entry.th32ProcessID, &sid) &&
            sid == consoleSessionId)
        {
            CloseHandle(hSnapshot);
            return entry.th32ProcessID;
        }
    }
...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы