![]() |
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]() ![]() ![]() |
|
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Добрый день, уважаемые знатоки.
Необходимо переписать один из своих старых проектов, который разрабатывался во времена Windows XP. Причина - некорректная работа в Windows 7. А именно... Первая часть проекта - программа с иконкой в системном трее. Назовем ее "Программа". Вторая часть - служба, запускаемая с правами системы. Она контролирует наличие запущенного процесса Программы: при необходимости выполняет ее запуск или перезапуск. При этом критично, чтобы Программа запускалась именно с правами системы (передаваемыми ей от службы). Суть проблемы - в "семерке" иконка в трее запущенной службой Программы не отображается. Я так понял, что в Win7, в отличие от WinXP, у каждого пользователя свой рабочий стол, а соответственно и трей. Поэтому и иконка Программы "появляется" в трее системного аккаунта, а не активного пользователя. Вопрос: как обойти сие нововведение Windows? Вероятно, создавая иконку, нужно каким-то образом указать "чужой" трей, но как это сделать - не нашел. Возможно, предложите свои решения. Обе части проекта написаны мной, можно механизм взаимодействия как угодно переписать. Вариант запуска службой Программы от имени активного пользователя - не подходит точно. |
|||
|
||||
kami |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Правильно.
И не найдете. "Чужой трей" находится на чужом рабочем столе, в чужой оконной станции и чужой терминальной сессии. Вы туда не влезете.
Тогда - CreateProcesAsUser или CreateProcessWithLogonW. |
||||
|
|||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
Нет никакого трея системы. В остальном Ками прав.
Это сообщение отредактировал(а) bems - 18.2.2011, 19:11 -------------------- Обижено школьников: 8 |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
А, забыл - есть же еще планировщик заданий
![]() Кстати, такая политика появилась не в Win7, а в Win Vista Добавлено через 2 минуты и 54 секунды Не получится, я пробовал. Устанавливаемый десктоп должен принадлежать родной для процесса WinSta, а WinSta сервиса<> WinSta десктопного приложения.
SetThreadDesktop |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
Но из системной учетки это точно возможно, нужно только найти правильный путь. -------------------- Обижено школьников: 8 |
|||
|
||||
CodeMonkey |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 16 Всего: 89 |
Почему это? Чую запах ###-кода. Добавлено через 12 минут и 21 секунду P.S. И гляньте ещё вот это.
А откуда уверенность? -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
||||
|
|||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
В свое время пришлось очень плотно заниматься этой проблемой. Знаний и навыков было, конечно, гораздо меньше...
Результатом был отлов смены сессии (в HandlerEx) и запуск процесса через CreateProcessAsUser, с какими-то извращениями над полученным токеном. |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
Потому что еще не было такого, чтобы ей что-то эффективно запретили. Весь вопрос только в количестве извращений на тысячу строк кода. Это конечно не меняет того факта, что не нужно запускать интерактивные программы в контексте системы -------------------- Обижено школьников: 8 |
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Спасибо огромное за ответы!
Насчет целесообразности запуска Программы именно с привилегиями системы я еще подумаю на неделе. Дело в том, что писалось это все несколько лет назад (опыта было меньше, винды еще не так к безопасности подходили...), и теперь, возможно, есть смысл более обдуманно подойти к проектированию. Системные права нужны (в подробности вдаваться не буду, если позволите), но другое дело, что можно перепоручить ту часть функционала, где они требуются, самой службе, а не Программе. А ей уж оставить лишь иконку, да окошки. На всякий случае научился запускать Программу из службы с правами и в сеансе активного пользователя (надо только еще проверить хорошо, что везде и всегда работает - раньше не сталкивался с такими механизмами). Но с этим вариантом еще возникает ряд вопросов. Обмозгую хорошенько на свежую голову и спрошу здесь, коли не разберусь с чем. |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Большая просьба - если будет работать с быстрым переключением пользователей, т.е. десктопная часть будет запускаться под каждым из залогиненных пользователей - выложите код. Безумно интересно, как Вы справились с этой проблемой. |
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
kami, мне мыслится сей механизм так: в моей службе по таймеру проверяется наличие запущенного процесса Программы. В эту проверку можно добавить сравнение SID пользователя, от которого запущен процесс, с SID активного пользователя. Если не совпадают, запускать процесс под активным пользователем. С определением SID найденного процесса я разобрался, а с SID активного пользователя - нет. Не сталкивались с этим?
Для запуска Программы в контексте активного пользователя я использую JediWinAPI. Поэтому можно и SID пользователя определять ее средствами. Но я никак не могу найти толковой документации по данной библиотеке. |
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Кажется, получилось!
![]() Действовал, как описал выше. Сейчас приберусь в коде, и выложу результат. Надеюсь, покажете, что и где оптимизировать можно - писал сумбурно, дергая отовсюду и адаптируя чужие куски кода. |
|||
|
||||
Romero |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Итак, вот что у меня получилось... Тестирование пока провел лишь на Windows 7 32bit. Остальные варианты позже тоже проверю (меня интересует еще по большому счету лишь Windows XP и 64-битные вариации обеих ОС). Помогите с оптимизацией алгоритма и кодов, плиз.
В основной рабочей процедуре службы в цикле через заданный интервал проверяю наличие процесса и, если нужно, выполняю запуск:
|
||||
|
|||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
1. Не котируется в WinXP при использовании быстрого переключения пользователей, будет возвращать SessionID первого из залогиненных :( (хотя, может и ошибаюсь, но у меня так не получалось) Upd. действительно, возвращается активный пользователь... ![]() 2. Попробуйте изначально войти под "гостем". Емнип, там какие-то траблы были с привилегиями как сервиса, так и полученного токена пользователя. 3. Ну и таймер - это...хотя, Ваше право. Тоже решение. Это сообщение отредактировал(а) kami - 21.2.2011, 20:05 |
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
1. В теории должно работать. Я когда этот способ нашел, читал, что для WinXP сработает. Но на практике позже проверю, когда время будет.
2. Что значит "изначально"? Установить службу, а затем переключиться в сеанс Гостя? Вообще, для Гостя мне не очень нужно, чтобы работало, но ради эксперимента попробую. 3. Не совсем таймер - цикл со слипом, пока службе не передается "SERVICE_STOP". Но тут других решений я не вижу. Нужно обеспечить постоянное присутствие одного процесса Программы. Поскольку она все же будет запущена с правами пользователя, на случай убийства пользователем процесса служба будет производить проверку каждые Х секунд. |
|||
|
||||
Romero |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Подправил код слегка. Избавился от Jedi.
В основной рабочей процедуре службы в цикле через заданный интервал проверяю наличие процесса и, если нужно, выполняю запуск:
Это сообщение отредактировал(а) Romero - 22.2.2011, 13:18 |
||||
|
|||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Теоретический вопрос. Для выполнения действий процедуры RunApp у службы должны быть права системы. А можно ли получить подобные привилегии (и удачно запустить программу от чужого имени) из обычного приложения (которое не имеет прав системы, но, допустим, запущена от имени Администратора)?
И еще, когда я гляжу на другие найденные в Интернете примеры кода запуска процесса от имени активного пользователя, у меня возникает ощущение, что в моем коде чего-то не хватает. Он слишком лаконичный ![]() |
|||
|
||||
kami |
|
||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Попробуйте запустить что-нибудь "не свое", тогда узнаете ![]() У меня больше всего проблем возникло с запуском ACDSee - нехватало параметров в Environment. В остальном - читайте в MSDN описания тех функций, которые задействуете. Например, про первый параметр CreateProcessAsUser пишут
Если смотреть в библию, то упираемся в WTSQueryUserToken:
Добавлено через 6 минут и 5 секунд
Установить службу> выйти из системы> войти под гостем> сменить пользователя на админа (т.е. чтобы получилось 2 одновременно запущенные сессии - первая "гость" и вторая "админ") Добавлено через 7 минут и 26 секунд
Проверил под виртуальной XP SP3 - работает. |
||||||||||
|
|||||||||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
В выходные проверил на Win7x64 - работает. В сеансе Гостя - тоже. Проверял так: запустил сеанс Админа, Программа стартанула; переключился на Гостя (сеанс Админа был активен) - стартанула (в списке процессов видно, что от имени Гостя, как и положено), переключился на другого Админа - тоже стартанула (в списке процессов уже три копии - каждая от имени своего юзера). Или критично было именно "выйти из системы", после чего первым запустить сеанс Гостя?
На ХР когда проверял, возникла проблема, но сейчас до меня дошло, что это мог я сам накосячить. Перепроверю позже. Запускать "не своё" нужды нет. Пока проблем в работе моей связки не обнаружил, буду считать, что все удачно "прокатило" ![]() Спасибо за ответы, kami! |
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Подскажите, пожалуйста, что изменить в моем коде выше, чтобы Программа продолжалась запускаться на рабочем столе активного пользователя, НО с правами родителя (то есть службы)?
|
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
||||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
||||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Romero, нет, о последней строке в верхнем списке, называется "обязательная метка>чего-то там".
Вот это "чего-то там" может быть "обязательный уровень системы", "средний обязательный уровень" и так далее. Также достаточно важным является нижний список - установленные процессу привилегии. Ибо даже не будучи запущенным "от системы", но имея нужную привилегию, можно выполнить достаточно многое (но не всё, как пример - WTSQueryUserToken, рассмотренный ранее). Какая привилегия нужна - это, само собой - в MSDN. Добавлено через 1 минуту и 32 секунды И вообще - почему возникли сомнения, что программа, запущенная на активном десктопе, не обладает нужными правами? |
|||
|
||||
Romero |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Там стоит "Integrity".
Как минимум по тому, что у запускаемой службой Программы нет прав писать в Program files - это первое, что заметил. Думаю, это явно говорит, что права от службы не передались. |
||||
|
|||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 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 |
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Почитал про имперсонацию, попробовал после получения токена активного пользователя дать ему права таким образом:
Фокус не прошел. Может, я неправильно понял теорию? ![]() |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Смотря что нужно было этим кодом сделать и откуда он вызывается. Это раз. Второе - DuplicateToken создает impersonationToken. CreateProcessAsUser требует для работы primary token, который можно получить с помощью DuplicateTokenEx. Ну и - само собой, если в "исходном" токене нет нужных правов, то в дубликате они не появятся. Добавлено @ 20:33 ах да, кроме не помешает добавить TOKEN_EXECUTE Это сообщение отредактировал(а) kami - 12.5.2011, 20:34 |
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
Нужно передать привилегии вызывающего процесса (службы, запущенной под системной учеткой). Вызывается после получения юзерского токена, перед вызовом CreateProcessAsUser. Вот про различие токенов я и не разобрался, попробую сегодня DuplicateTokenEx, спасибо. В исходном токене, я надеюсь, все нужные права будут при таком подходе:
|
|||
|
||||
Romero |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.6.2005 Репутация: 1 Всего: 1 |
где hToken - токен активного юзера, sysToken - токен службы, запущенной от имени системы. Результат - приложение запускается на рабочем столе юзера, но и с его правами (проверяю попыткой записи в системную директорию). Где-то что-то не докрутил еще... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: WinAPI и системное программирование" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |