Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Win7 + TrayIcon + системная учетная запись, Работа с треем другого пользователя 
:(
    Опции темы
Romero
Дата 22.2.2011, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Подправил код слегка. Избавился от Jedi.
Код

type
  PWTS_PROCESS_INFO = ^WTS_PROCESS_INFO;
  WTS_PROCESS_INFO = packed record
    SessionId: DWORD;
    ProcessId: DWORD;
    pProcessName: PChar;
    pUserSid: PSID;
  end;

type
  procedure ConvertSidToStringSid(SID: PSID; var StringSid: LPSTR); stdcall;
    external advapi32 name 'ConvertSidToStringSidA';

  function WTSEnumerateProcesses(hServer: THandle; Reserved,Version: DWORD;
    var ppProcessInfo: PWTS_PROCESS_INFO;var Count: DWORD): BOOL; stdcall;
      external 'wtsapi32.dll' name 'WTSEnumerateProcessesA';

  procedure WTSFreeMemory(pMemory: Pointer); stdcall;
    external 'wtsapi32.dll' name 'WTSFreeMemory';

  function WTSQueryUserToken(SessionId: DWORD; phToken: pHandle):bool;stdcall;external 'wtsapi32.dll';

  function WTSGetActiveConsoleSessionId: DWORD; stdcall; external 'Kernel32.dll';

...

//получаем SID активного пользователя (того, кто монитором "владеет" на момент запуска)
function GetCurrentUserSID:string;
var
  hToken:THandle;
  ReturnLength:DWORD;
  UserToken:PSIDAndAttributes;
  res:LPSTR;
begin
  if WTSQueryUserToken(WtsGetActiveConsoleSessionID,@hToken) then
  begin
    GetTokenInformation(hToken,TokenUser,UserToken,0,ReturnLength);
    GetMem(UserToken,ReturnLength);
    try
      if GetTokenInformation(hToken,TokenUser,UserToken,ReturnLength,ReturnLength) then
        begin
          ConvertSidToStringSid(UserToken.Sid,res);
          Result:=res;
        end;
    finally
      FreeMem(UserToken);
    end;
  end;
end;

//запуск приложения от имени активного пользователя
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;

//поиск запущенного процесса по имени файла и SID пользователя; я проверяю наличие процесса по имени файла, но по-хорошему надо бы как-то иначе реализовать...
function CheckTask(ExeFileName,CurUserSID:string):Boolean;
var
  Count,i:DWORD;
  pProcessInfo,pCur:PWTS_PROCESS_INFO;
  UserSID:LPSTR;
begin
  Result:=false;
  if not WTSEnumerateProcesses(0,0,1,pProcessInfo,Count)then
    Exit;
  for i:=0 to Count-1 do
    begin
      pCur:=Ptr(DWORD(pProcessInfo)+(i*SizeOf(WTS_PROCESS_INFO)));
      if UpperCase(pCur.pProcessName)=UpperCase(ExeFileName) then
      begin
        ConvertSidToStringSid(pCur.pUserSid,UserSID);
        if UserSID=CurUserSID then
          Result:=true;
      end;
    end;
  WTSFreeMemory(pProcessInfo);
end;

В основной рабочей процедуре службы в цикле через заданный интервал проверяю наличие процесса и, если нужно, выполняю запуск:
Код

  if not CheckTask('program.exe',GetCurrentUserSID) then
    RunApp('path/program.exe');



Это сообщение отредактировал(а) Romero - 22.2.2011, 13:18
PM   Вверх
Romero
Дата 22.2.2011, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Теоретический вопрос. Для выполнения действий процедуры RunApp у службы должны быть права системы. А можно ли получить подобные привилегии (и удачно запустить программу от чужого имени) из обычного приложения (которое не имеет прав системы, но, допустим, запущена от имени Администратора)?

И еще, когда я гляжу на другие найденные в Интернете примеры кода запуска процесса от имени активного пользователя, у меня возникает ощущение, что в моем коде чего-то не хватает. Он слишком лаконичный smile Например, по сравнению с функцией RunApplication отсюда. С виду то всё работает, но вдруг что упустил важного.
PM   Вверх
kami
Дата 22.2.2011, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Romero @  22.2.2011,  14:06 Найти цитируемый пост)
С виду то всё работает, но вдруг что упустил важного.

Попробуйте запустить что-нибудь "не свое", тогда узнаете smile
У меня больше всего проблем возникло с запуском ACDSee - нехватало параметров в Environment.
В остальном - читайте в MSDN описания тех функций, которые задействуете.
Например, про первый параметр CreateProcessAsUser пишут
Цитата

A handle to the primary token that represents a user. The handle must have the TOKEN_QUERY, TOKEN_DUPLICATE, and TOKEN_ASSIGN_PRIMARY access rights. For more information, see Access Rights for Access-Token Objects. The user represented by the token must have read and execute access to the application specified by the lpApplicationName or the lpCommandLine parameter.


Цитата(Romero @  22.2.2011,  14:06 Найти цитируемый пост)
можно ли получить подобные привилегии (и удачно запустить программу от чужого имени) из обычного приложения

Если смотреть в библию, то упираемся в WTSQueryUserToken:
Цитата

To call this function successfully, the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege.


Добавлено через 6 минут и 5 секунд
Цитата(Romero @  22.2.2011,  09:49 Найти цитируемый пост)
2. Что значит "изначально"? Установить службу, а затем переключиться в сеанс Гостя? 

Установить службу> выйти из системы> войти под гостем> сменить пользователя на админа (т.е. чтобы получилось 2 одновременно запущенные сессии - первая "гость" и вторая "админ")

Добавлено через 7 минут и 26 секунд
Цитата(Romero @  22.2.2011,  09:49 Найти цитируемый пост)
1. В теории должно работать. Я когда этот способ нашел, читал, что для WinXP сработает.

Проверил под виртуальной XP SP3 - работает.
PM MAIL WWW   Вверх
Romero
Дата 24.2.2011, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



В выходные проверил на Win7x64 - работает. В сеансе Гостя - тоже. Проверял так: запустил сеанс Админа, Программа стартанула; переключился на Гостя (сеанс Админа был активен) - стартанула (в списке процессов видно, что от имени Гостя, как и положено), переключился на другого Админа - тоже стартанула (в списке процессов уже три копии - каждая от имени своего юзера). Или критично было именно "выйти из системы", после чего первым запустить сеанс Гостя?

На ХР когда проверял, возникла проблема, но сейчас до меня дошло, что это мог я сам накосячить. Перепроверю позже.

Запускать "не своё" нужды нет. Пока проблем в работе моей связки не обнаружил, буду считать, что все удачно "прокатило" smile Тестирование на нескольких сотнях компов покажет, хватает ли этого кода...

Спасибо за ответы, kami!
PM   Вверх
Romero
Дата 26.4.2011, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Подскажите, пожалуйста, что изменить в моем коде выше, чтобы Программа продолжалась запускаться на рабочем столе активного пользователя, НО с правами родителя (то есть службы)?
PM   Вверх
kami
Дата 26.4.2011, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Romero @  26.4.2011,  14:43 Найти цитируемый пост)
запускаться на рабочем столе активного пользователя, НО с правами родителя

а что не так сейчас?
Что говорит по этому поводу ProcessExplorer? (а именно - закладка Security свойств процесса)
PM MAIL WWW   Вверх
Romero
Дата 27.4.2011, 08:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Цитата(kami @  26.4.2011,  21:02 Найти цитируемый пост)
Что говорит по этому поводу ProcessExplorer? (а именно - закладка Security свойств процесса) 

Я так понимаю, речь о верхней строке в этой вкладке? Там указан активный пользователь.
PM   Вверх
kami
Дата 27.4.2011, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Romero, нет, о последней строке в верхнем списке, называется "обязательная метка>чего-то там".
Вот это "чего-то там" может быть "обязательный уровень системы", "средний обязательный уровень" и так далее.
Также достаточно важным является нижний список - установленные процессу привилегии. Ибо даже не будучи запущенным "от системы", но имея нужную привилегию, можно выполнить достаточно многое (но не всё, как пример - WTSQueryUserToken, рассмотренный ранее). Какая привилегия нужна - это, само собой - в MSDN.

Добавлено через 1 минуту и 32 секунды
И вообще - почему возникли сомнения, что программа, запущенная на активном десктопе,  не обладает нужными правами?
PM MAIL WWW   Вверх
Romero
Дата 27.4.2011, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Цитата(kami @  27.4.2011,  12:19 Найти цитируемый пост)
о последней строке в верхнем списке, называется "обязательная метка>чего-то там"

Там стоит "Integrity".

Цитата(kami @  27.4.2011,  12:19 Найти цитируемый пост)
И вообще - почему возникли сомнения, что программа, запущенная на активном десктопе,  не обладает нужными правами? 

Как минимум по тому, что у запускаемой службой Программы нет прав писать в Program files - это первое, что заметил. Думаю, это явно говорит, что права от службы не передались.
PM   Вверх
kami
Дата 28.4.2011, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Поднял свой старый код, вспомнил, почему забросил это дело.
Всё начинается с WTSQueryUserToken.
По какой-то (не выясненной мной) причине, у этого полученного токена в TokenGroups для группы "администраторы" стоит SE_GROUP_USE_FOR_DENY_ONLY. А для работы программы с правами админа, в идеале должно быть значение SE_GROUP_OWNER. Сие (SE_GROUP_USE_FOR_DENY_ONLY) автоматически означает, что права администратора для всего, что будет запускаться под этим токеном будут заблокированы. Установка TokenIntegrityLevel для токена не даст ничего, по причине (опять-таки) блокировки прав доступа.
А теперь - самое интересное - никакими манипуляциями заменить SE_GROUP_USE_FOR_DENY_ONLY на любое другое значение нельзя. Так прописано в MSDN и подтверждено опытами.
Позже выложу код, как пытался это сделать.

Общий вывод: сервису чего-то не хватает для того, чтобы получить primarytoken с правильно установленным значением SID and Attributes для группы "администраторы".


Может, Гуру чего посоветуют...

Это сообщение отредактировал(а) kami - 28.4.2011, 18:42
PM MAIL WWW   Вверх
Romero
Дата 12.5.2011, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Почитал про имперсонацию, попробовал после получения токена активного пользователя дать ему права таким образом:
Код

OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,sysToken);
DuplicateToken(sysToken,SecurityImpersonation,@hToken);

Фокус не прошел. Может, я неправильно понял теорию? smile
PM   Вверх
kami
Дата 12.5.2011, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Romero @  12.5.2011,  15:44 Найти цитируемый пост)
Может, я неправильно понял теорию

Смотря что нужно было этим кодом сделать и откуда он вызывается. Это раз. 
Второе - DuplicateToken создает impersonationToken. CreateProcessAsUser требует для работы primary token, который можно получить с помощью DuplicateTokenEx.
Ну и - само собой, если в "исходном" токене нет нужных правов, то в дубликате они не появятся.

Добавлено @ 20:33
ах да, кроме
Цитата(Romero @  12.5.2011,  15:44 Найти цитируемый пост)
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUER

не помешает добавить TOKEN_EXECUTE

Это сообщение отредактировал(а) kami - 12.5.2011, 20:34
PM MAIL WWW   Вверх
Romero
Дата 13.5.2011, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Цитата(kami @  12.5.2011,  20:28 Найти цитируемый пост)
Смотря что нужно было этим кодом сделать и откуда он вызывается. Это раз. 
Второе - DuplicateToken создает impersonationToken. CreateProcessAsUser требует для работы primary token, который можно получить с помощью DuplicateTokenEx.
Ну и - само собой, если в "исходном" токене нет нужных правов, то в дубликате они не появятся.

Нужно передать привилегии вызывающего процесса (службы, запущенной под системной учеткой). Вызывается после получения юзерского токена, перед вызовом CreateProcessAsUser.
Вот про различие токенов я и не разобрался, попробую сегодня DuplicateTokenEx, спасибо.
В исходном токене, я надеюсь, все нужные права будут при таком подходе:
Код

OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_EXECUTE,sysToken);

PM   Вверх
Romero
Дата 13.5.2011, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Код

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

где hToken - токен активного юзера, sysToken - токен службы, запущенной от имени системы.
Результат - приложение запускается на рабочем столе юзера, но и с его правами (проверяю попыткой записи в системную директорию).
Где-то что-то не докрутил еще...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0969 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.