-
Приветствую, задача такая, необходимо как-то надежно задетектировать что приложение находится под терминальной сессией. Как это делается штатным способом: через вызов GetSystemMetrics(SM_REMOTESESSION).
Что происходит в этом случае: Windows проверяет наличие данных в PEB->SharedData, если эти эти данные есть, то берет ID сессии оттуда, если нет, то берет ID текущей сессии из PEB->SessionId. Далее проверяется - если ID равен нулю, то терминальной сессии нет. Если получен ID сессии отличный от нуля, то это число сверяется с тем, которое записано в KE_USER_SHARED_DATA -> ActiveConsoleId. Если значения двух чисел совпали, то терминальной сессии нет.
Проблема в том что такой детект отключается легко, т.к. PEB доступен на перезапись извне и достаточно обнулить PEB->SharedData + PEB->SessionId получив его адрес через NtQueryInformationProcess с флагами ProcessWow64Information/ProcessBasicInformation и считав поле PebBaseAddress, а потом произвести вызов WriteProcessMemory.
Соответственно вопрос: кто какие еще знает способы детектирования терминальной сессии?
-
Пока что единственный альтернативный вариант приходящий в голову, это найти любой сторонний процесс в рамках текущей WinStaX и считать эти поля оттуда. Но что-то мне кажется что есть еще какие либо изменения с системных структурах, куда можно подсмотреть, в которых происходят изменения в случае работы под терминалом.
-
Может энвироменты висят какие или атомы?
-
Енвиронменты тоже в памяти сидят и доступны на перезапись, а вот с атомами мысль. Спасибо - гляну.
-
драйвер экрана?
TokenSessionId, TokenGroups:SECURITY_TERMINAL_SERVER_RID/SECURITY_LOGON_IDS_RID, etc. - судя по PEB - не вариант(SE_TCB_NAME)...
И ни разу не интересовался - откуда WTSQuerySessionInformation берёт WTS_CURRENT_SESSION, но судя по примечанию не из того же... To retrieve the session ID for the current session when Remote Desktop Services is running, call WTSQuerySessionInformation and specify WTS_CURRENT_SESSION for the SessionId parameter and WTSSessionId for the WTSInfoClass parameter. The session ID will be returned in the ppBuffer parameter. If Remote Desktop Services is not running, calls to WTSQuerySessionInformation fail. In this situation, you can retrieve the current session ID by calling the ProcessIdToSessionId function.
To determine whether your application is running on the physical console, you must specify WTS_CURRENT_SESSION for the SessionId parameter, and WTSClientProtocolType as the WTSInfoClass parameter. If ppBuffer is "0", the session is attached to the physical console.
-
С токеном интересная идея, спасибо!
-
Не уверен, насчет защищенности, но возможен вариант WTSEnumerateSessions WTSQuerySessionInformation с параметром WTSClientProtocolType, по которому можно узнать RDP это или консоль. ну и сравнить WTSGetActiveConsoleSessionId
вообще, например, в XP терминальный API внутри во многом завязан на namep pipe'ах, например \\.\Pipe\TerminalServer\SystemExecSrvr\ но, видимо, в каждой версии ОС там свой протокол, нужно серьезно реверсить, чтобы понять что к чему. мне такой подход только один раз пригодился для XP, да и то, реализацию нашел, а не сделал сам, ибо самому не по зубам. но твоих знаний, в принципе, должно хватить, чтобы самостоятельно реверс протокола сделать.
|