R
R
RomeroMsk2011-05-18 15:13:48
Delphi
RomeroMsk, 2011-05-18 15:13:48

Delphi+WinAPI. Unable to transfer privileges to a running process

Good afternoon.

I use the following Delphi code to start a process on the active user's desktop (the user who "owns" the monitor at the time of launch) from under a service in Windows 7 (the service is started with system rights):

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;

I want to finish this code in order to transfer parent rights to the process being launched (tobish system privileges from the service), but keeping the launch condition on the active user's desktop. I'm trying to do this through the impersonation of the primer token:

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);

But as a result, I still get a process running with the rights of the active user.
I'm not familiar with WinAPI. Most likely, he missed something or went in the wrong direction at all. Help with solving this problem.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
K
kami-soft, 2014-03-03
@kami-soft

How to start a GUI process from service, under Win...

R
Ruslan, 2016-03-09
@ruzzz

Instead of the current process, OpenProcessToken(GetCurrentProcess()...
We take a token from winlogon.exe with the desired SessionID.
Find the pid like this:

...
    while (Process32Next(hSnapshot, &entry))
    {
        if (_wcsicmp(entry.szExeFile, exePath) == 0 &&
            ProcessIdToSessionId(entry.th32ProcessID, &sid) &&
            sid == consoleSessionId)
        {
            CloseHandle(hSnapshot);
            return entry.th32ProcessID;
        }
    }
...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question