Узнать SID по PID и кое-что еще (winapi)

Обсуждение программ nnCron и nnCron LITE

Узнать SID по PID и кое-что еще (winapi)

Postby polly5315 » Wed, 10 Feb 2010, 11:36

Здравствуйте. Появилась задача узнавать идентификатор сессии и ее параметры исходя по идентификатору процесса, принадлежащему ей, а так же параметры пользователя, инициировавшего эту сессию. Как я понимаю, под одной сессией могут быть процессы разных пользователей (обычно там еще SYSTEM-процессы висят), но инициирована она одним конкретным пользователем. Хочется переписать плагин net.spf с использованием WinAPI, но нигде не могу найти документацию по необходимым функциям.

Необходимы следующие действия:
1) Получить SID по принадлежащему ему PID (какой сессии принадлежит процесс)
2) Получить пользователя по PID (под каким пользователем запущен процесс)
3) Получить пользователя по SID (кем инициирована сессия)
4) Получить массив PID-ов по SID
5) Отклчить (выполнить Disconnect) сессию по SID
6) Выполнить выход (Log off) из сессии по SID
Так же, возможно, нужно будет многое другое в этом контексте. Кстати, может написать отдельный плагин?
Буду рад всем примерам кода и указкам на документацию.
polly5315
 
Posts: 13
Joined: Fri, 29 Jan 2010, 14:01

Re: Узнать SID по PID и кое-что еще (winapi)

Postby Ilya » Thu, 11 Feb 2010, 01:25

polly5315 wrote:Необходимы следующие действия:
1) Получить SID по принадлежащему ему PID (какой сессии принадлежит процесс)

3) Получить пользователя по SID (кем инициирована сессия)

Так же, возможно, нужно будет многое другое в этом контексте. Кстати, может написать отдельный плагин?
Буду рад всем примерам кода и указкам на документацию.


Чуть-чуть поковырял.
Возможно отвечает на вопросы 1 и 3?
Пример грязный и

Code: Select all
<%
WINAPI: OpenProcessToken advapi32.dll
WINAPI: GetTokenInformation advapi32.dll
WINAPI: ConvertSidToStringSidA advapi32.dll
WINAPI: LookupAccountSidA advapi32.dll

VARIABLE prochandle
VARIABLE tokenhandle
VARIABLE TokenInformation
VARIABLE tmpvar
VARIABLE tmpvar1
1 CONSTANT TokenUser
CREATE uName 255 ALLOT
CREATE rdn 255 ALLOT
: proc-handle ( pid -- )
TRUE PROCESS_QUERY_INFORMATION OpenProcess DUP prochandle !
\ CloseHandle DROP
;

\ EOF
: test
S" firefox.exe" PROC-EXIST? proc-handle >R
tokenhandle TOKEN_QUERY R> OpenProcessToken
IF
CR ." tokenhandle:" tokenhandle @ .

tmpvar 0 0 TokenUser tokenhandle @ GetTokenInformation DROP
GetLastError ERROR_INSUFFICIENT_BUFFER =
IF
tmpvar @ ALLOCATE THROW TokenInformation !
tmpvar DUP @ TokenInformation @ TokenUser tokenhandle @ GetTokenInformation
   IF
   HERE TokenInformation @ @ ConvertSidToStringSidA
      IF
         HERE @ ASCIIZ> CR ." SID:" TYPE HERE @ LocalFree DROP
         255 DUP tmpvar ! tmpvar1 !
         HERE tmpvar1 rdn tmpvar uName TokenInformation @ @ 0 LookupAccountSidA
         IF
            CR ." Name:" uName ASCIIZ> TYPE
            CR ." DomainName:" rdn ASCIIZ> TYPE
         THEN
      THEN
   THEN
THEN
\ ============================
TokenInformation @ FREE THROW
tokenhandle @ CloseHandle DROP
THEN
prochandle @ CloseHandle DROP
CR ." The main end!"
;

%>


Code: Select all
#( sid
NoActive
Action:
test
)#
Ilya
 
Posts: 443
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Узнать SID по PID и кое-что еще (winapi)

Postby polly5315 » Thu, 11 Feb 2010, 08:25

Спасибо, сейчас тоже поковыряю
polly5315
 
Posts: 13
Joined: Fri, 29 Jan 2010, 14:01

Re: Узнать SID по PID и кое-что еще (winapi)

Postby AlikasS » Fri, 12 Feb 2010, 19:05

отличная вещь,
у меня получились такие штуки
Code: Select all
<%
WINAPI: OpenProcessToken advapi32.dll
WINAPI: GetTokenInformation advapi32.dll
WINAPI: ConvertSidToStringSidA advapi32.dll
WINAPI: LookupAccountSidA advapi32.dll

VARIABLE prochandle
VARIABLE tokenhandle
VARIABLE TokenInformation
VARIABLE tmpvar
VARIABLE tmpvar1
1 CONSTANT TokenUser
CREATE uName 255 ALLOT
CREATE rdn 255 ALLOT
: proc-handle ( pid -- )
TRUE PROCESS_QUERY_INFORMATION OpenProcess DUP prochandle !
;

:  EXE->SID ( процесс.exe - SID -1 / 0 )
PROC-EXIST? proc-handle >R
tokenhandle TOKEN_QUERY R> OpenProcessToken
IF
   tmpvar 0 0 TokenUser tokenhandle @ GetTokenInformation DROP
   GetLastError ERROR_INSUFFICIENT_BUFFER =
   IF
   tmpvar @ ALLOCATE THROW TokenInformation !
   tmpvar DUP @ TokenInformation @ TokenUser tokenhandle @ GetTokenInformation
      IF
         HERE TokenInformation @ @ ConvertSidToStringSidA
         IF
         HERE @ ASCIIZ> S" " S+ HERE @ LocalFree DROP
         TRUE
         ELSE FALSE
         THEN
      ELSE FALSE
      THEN
   ELSE FALSE
   THEN
   TokenInformation @ FREE THROW
   tokenhandle @ CloseHandle DROP
ELSE FALSE
THEN
prochandle @ CloseHandle DROP
;

:  EXE->USER ( процесс.exe - имя домен -1 / 0 )
PROC-EXIST? proc-handle >R
tokenhandle TOKEN_QUERY R> OpenProcessToken
IF
   tmpvar 0 0 TokenUser tokenhandle @ GetTokenInformation DROP
   GetLastError ERROR_INSUFFICIENT_BUFFER =
   IF
   tmpvar @ ALLOCATE THROW TokenInformation !
   tmpvar DUP @ TokenInformation @ TokenUser tokenhandle @ GetTokenInformation
      IF
         255 DUP tmpvar ! tmpvar1 !
         HERE tmpvar1 rdn tmpvar uName TokenInformation @ @ 0 LookupAccountSidA
         IF
            uName ASCIIZ>
            rdn ASCIIZ>
            TRUE
         ELSE FALSE
         THEN
      ELSE FALSE
      THEN
   ELSE FALSE
   THEN

TokenInformation @ FREE THROW
tokenhandle @ CloseHandle DROP
ELSE FALSE
THEN
prochandle @ CloseHandle DROP
;

%>



#( sid
NoActive
Action:
S" excel.exe" EXE->USER
IF
S" /"  S+ 2SWAP S+ MsgBox
THEN

S" excel.exe" EXE->SID
IF
 MsgBox
THEN
)#
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Узнать SID по PID и кое-что еще (winapi)

Postby AlikasS » Fri, 12 Feb 2010, 19:26

интересно из известного SID получить -- name или FALSE
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Узнать SID по PID и кое-что еще (winapi)

Postby polly5315 » Mon, 15 Feb 2010, 13:32

Здравствуйте снова. Поковырялся, посмотрел на ваш код и с горем пополам сделал вот это. Возможно, вы увидите здесь много ошибок (я новичок в форте), но оно выдает мне номер сессии, тот самый, который видно в диспетчере задач. Оцените?
Code: Select all
<%
WINAPI: OpenProcessToken       advapi32.dll
WINAPI: GetTokenInformation    advapi32.dll

1024 CONSTANT PROCESS_QUERY_INFORMATION \ 0x0400
8    CONSTANT TOKEN_QUERY               \ 0x0008
\ 122  CONSTANT ERROR_INSUFFICIENT_BUFFER
12   CONSTANT TokenSessionId \ TOKEN_INFORMATION_CLASS Enumeration

VARIABLE prochandle
VARIABLE tokenhandle
VARIABLE TokenInformation
VARIABLE TokenInfLength
VARIABLE My

: proc-handle ( pid -- )
    TRUE PROCESS_QUERY_INFORMATION OpenProcess prochandle !
;

: PID->SID ( PID -- SID -1/0 )
    proc-handle
    tokenhandle TOKEN_QUERY prochandle @ OpenProcessToken
    IF
        4 TokenInfLength !
            TokenInfLength @ ALLOCATE THROW TokenInformation !
            TokenInfLength DUP @ TokenInformation @ TokenSessionId tokenhandle @ GetTokenInformation DROP
        tokenhandle @ CloseHandle DROP
        TokenInformation @ @ TRUE
    ELSE
        FALSE
    THEN
    prochandle @ CloseHandle DROP
;
%>

#( sid
NoActive
Action:
    S" mspaint.exe" PROC-EXIST? PID->SID
    IF
        My !
        MSG: "Процесс mspaint.exe запущен в сессии %My @%"
    THEN
)#
Теперь буду делать остальной функционал (так как сессию поймали за SID, хочется мочь делать с ней разные вещи и узнавать подробности о ней).
polly5315
 
Posts: 13
Joined: Fri, 29 Jan 2010, 14:01

Re: Узнать SID по PID и кое-что еще (winapi)

Postby polly5315 » Mon, 15 Feb 2010, 13:57

Возможно, я невено выразился: под словом "SID" я всегда имел ввиду Session Identifer, а не Security Identifer
polly5315
 
Posts: 13
Joined: Fri, 29 Jan 2010, 14:01

Re: Узнать SID по PID и кое-что еще (winapi)

Postby VoidVolker » Mon, 15 Feb 2010, 16:40

Стоит использовать либо пользовательские либо локальные переменные: т.к. глобальные переменные не позволят использовать этот код в нескольких потоках одновременно.
Code: Select all
( PID -- SID -1/0 )

Не самое лучшее решение. Вот такт будет оптимальнее и удобнее:
Code: Select all
( PID -- SID | 0 )
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Узнать SID по PID и кое-что еще (winapi)

Postby polly5315 » Wed, 17 Feb 2010, 09:45

Здравствуйте снова. Покопал PlatformSDK Documentation и нашел более короткие пути. Взгляните, пожалуйста:
Code: Select all
<%
WINAPI: WTSLogoffSession     wtsapi32.dll
WINAPI: WTSDisconnectSession wtsapi32.dll
WINAPI: WTSOpenServerA       wtsapi32.dll
WINAPI: WTSCloseServer       wtsapi32.dll
WINAPI: ProcessIdToSessionId wtsapi32.dll

VARIABLE My

: PID->SID ( pid -- session-id -1/0 )
    { pid \ session-id -- }
    AT session-id pid ProcessIdToSessionId
    IF
        session-id
        TRUE
    ELSE
        FALSE
    THEN
;

: LOGOFF-SESSION ( session-id srv-name -- -1/0 )
    { session-id srv-name \ srv-handle -- }
    srv-name WTSOpenServerA TO srv-handle
    srv-handle 0 = NOT
    IF
        TRUE session-id srv-handle WTSLogoffSession
        IF \ Потому что функция скорее всего возвращает 1/0, а не -1/0
            TRUE
        ELSE
            FALSE
        THEN
        \ Хоть функция и VOID, все же она возвращает единицу, которую надо дропнуть.
        srv-handle WTSCloseServer DROP
    THEN
;

: DISCONNECT-SESSION ( session-id srv-name -- -1/0 )
    { session-id srv-name \ srv-handle -- }
    srv-name WTSOpenServerA TO srv-handle
    srv-handle 0 = NOT
    IF
        TRUE session-id srv-handle WTSDisconnectSession
        IF \ Потому что функция скорее всего возвращает 1/0, а не -1/0
            TRUE
        ELSE
            FALSE
        THEN
        \ Хоть функция и VOID, все же она возвращает единицу, которую надо дропнуть.
        srv-handle WTSCloseServer DROP
    THEN
;
%>

#( sid
WatchProc: "calc.exe"
Action:
    WATCH-PROC-ID PID->SID
    IF
        My !
        MSG: "Процесс calc.exe запущен в сессии %My @%"
    THEN

    WATCH-PROC-ID PID->SID
    IF
        \ Здесь: Имя сервера - вставить имя сервера, на котором хотим закрыть/отсоединить сессию
        Z" <Имя сервера>" DISCONNECT-SESSION
        IF
            MSG: "Разъединение сессии прошло успешно."
        ELSE
            MSG: "Разъединение сессии не удалось."
        THEN
    THEN
)#
Насчет добычи имени пользователя и всего такого еще поищу функций.
Вопрос: продолжать ли постить здесь эти варианты кода или это никому не нужно?
polly5315
 
Posts: 13
Joined: Fri, 29 Jan 2010, 14:01

Re: Узнать SID по PID и кое-что еще (winapi)

Postby AlikasS » Wed, 17 Feb 2010, 10:12

polly5315 wrote:...
Вопрос: продолжать ли постить здесь эти варианты кода или это никому не нужно?

продолжай. интересно. а применение каждый свое найдет (возможно не сейчас, но позже...)
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Узнать SID по PID и кое-что еще (winapi)

Postby polly5315 » Wed, 17 Feb 2010, 10:17

У меня-то задача несложная:
Чтобы когда люди свои программы в терминалах закрывают, сессии чтоб висеть не оставались, а то потом обратно в прогу зайти не могут (на экране пусто).
Чтобы когда люди удивительным образом делают себе дисконнект (пока не выяснили, как), а проги остаются висеть, чтобы к ночным бэкапам это безобразие закрыть.
Ну и так далее и тому подобное. Полезно.
polly5315
 
Posts: 13
Joined: Fri, 29 Jan 2010, 14:01

Re: Узнать SID по PID и кое-что еще (winapi)

Postby VoidVolker » Wed, 17 Feb 2010, 11:37

Code: Select all
IF \ Потому что функция скорее всего возвращает 1/0, а не -1/0
            TRUE
        ELSE
            FALSE
        THEN

Абсолютно бессмысленная фраза - IF THEN ELSE тут совершенно не нужны.
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Узнать SID по PID и кое-что еще (winapi)

Postby Ilya » Wed, 17 Feb 2010, 12:14

VoidVolker wrote:
Code: Select all
IF \ Потому что функция скорее всего возвращает 1/0, а не -1/0
            TRUE
        ELSE
            FALSE
        THEN

Абсолютно бессмысленная фраза - IF THEN ELSE тут совершенно не нужны.

Подтверждаю. В С - TRUE = 1, а не -1 или отличное от 0 как в СПФ-е.
Ilya
 
Posts: 443
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Узнать SID по PID и кое-что еще (winapi)

Postby AlikasS » Thu, 18 Feb 2010, 15:54

VoidVolker wrote:
Code: Select all
IF \ Потому что функция скорее всего возвращает 1/0, а не -1/0
            TRUE
        ELSE
            FALSE
        THEN

Абсолютно бессмысленная фраза - IF THEN ELSE тут совершенно не нужны.

зато красиво
TRUE - все 32 бита установлены в 1(двоичную)
FALSE - .... 0
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Узнать SID по PID и кое-что еще (winapi)

Postby AlikasS » Thu, 18 Feb 2010, 16:18

кстати у меня накопилось несколько решений для
действий по известному PID (кроме тех что в этой теме)
Suspend_Process
Resume_Process
GetProcessCmdLine
AttachDllToProcess

надо бы их в плагин оформить
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Next

Return to nnCron forum (Russian)

Who is online

Users browsing this forum: Exabot [Bot] and 3 guests