Можно ли в драйвере получить имя юзера?
От: Crag  
Дата: 20.11.03 10:04
Оценка:
Есть IRP. По нему получаем процесс.
С процессом жестко связано имя пользователя.
Есть ли способ получить это имя? Если нет, то, может быть есть какие-либо обходные пути?
Заранее спасибо...
Re: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 20.11.03 10:45
Оценка: 28 (4)
Здравствуйте, Crag, Вы писали:

C>Есть IRP. По нему получаем процесс.

C>С процессом жестко связано имя пользователя.
C>Есть ли способ получить это имя? Если нет, то, может быть есть какие-либо обходные пути?
C>Заранее спасибо...

можно получить SID пользователя:


ULONG 
KQueryPrimarySidByProcess (
   IN void* pSid, 
   IN ULONG dwSidLength,
   IN PEPROCESS pEProcess
   )
{
  if (
      pEProcess == NULL ||
      KeGetCurrentIrql() != PASSIVE_LEVEL
     )
    return 0;

  ULONG    dwSidLengthReal = 0;
  HANDLE   hToken = NULL;
  NTSTATUS NtStatus;

  void* pToken = PsReferencePrimaryToken(pEProcess);
  if (pToken != NULL)
  {
    NtStatus = ObOpenObjectByPointer(pToken, 0, 0, TOKEN_QUERY, 0, KernelMode, &hToken);
    if (NT_SUCCESS(NtStatus)) 
    {
      ULONG dwSizeOfToken = 0;
      NtStatus = ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &dwSizeOfToken);
      if (NtStatus == STATUS_BUFFER_TOO_SMALL)
      {
        PTOKEN_USER pTokenUser = (PTOKEN_USER) new char[dwSizeOfToken];
        if (pTokenUser != NULL)
        {
          NtStatus = ZwQueryInformationToken(hToken, TokenUser, pTokenUser, dwSizeOfToken, &dwSizeOfToken);
          if (NT_SUCCESS(NtStatus)) 
          {
            if (RtlValidSid(pTokenUser->User.Sid) == TRUE)
            {
              dwSidLengthReal = RtlLengthSid(pTokenUser->User.Sid);
              if (dwSidLengthReal != 0 && dwSidLengthReal <= dwSidLength && pSid != NULL)
              {
                RtlCopySid(dwSidLengthReal, pSid, pTokenUser->User.Sid);
              }
            }
          }
          delete[] (char*) pTokenUser;
        }
      }
      ZwClose(hToken);
    }

    ObDereferenceObject(pToken);
  }
    
  return dwSidLengthReal;
}


cb.
Re[2]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 20.11.03 11:02
Оценка:
добавлю про ZwQueryInformationToken скажу что несмотря на ее объявление в IFS Kit XP SP1 как

This routine is available on Microsoft® Windows® XP and later.

она вполне рабочая и на NT4, т.к. TOKEN_INFORMATION_CLASS объявлен в NT4 NTIFS.H
... << RSDN@Home 1.1.0 stable >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[3]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 20.11.03 11:24
Оценка: 14 (4)
кстати, по теме вот:
Q35 How do I retrieve the "user name" for the user performing a given operation?

V>добавлю про ZwQueryInformationToken скажу что несмотря на ее объявление в IFS Kit XP SP1 как

V>

V>This routine is available on Microsoft® Windows® XP and later.

V>она вполне рабочая и на NT4, т.к. TOKEN_INFORMATION_CLASS объявлен в NT4 NTIFS.H
... << RSDN@Home 1.1.0 stable >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[2]: Можно ли в драйвере получить имя юзера?
От: Аноним  
Дата: 17.12.03 09:37
Оценка:
как получить pEProcess ?
Re[3]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 17.12.03 10:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>как получить pEProcess ?


например так


NTKERNELAPI
PEPROCESS
IoThreadToProcess (
    IN PETHREAD Thread
);


IoThreadToProcess (pIrp->Tail.Overlay.Thread)


или так



NTKERNELAPI
PEPROCESS
IoGetCurrentProcess(
    VOID
    );



cb.
Re[4]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 08:27
Оценка:
Сделал всё как написано в этой конфе, получил следующие результаты :
1) SID получается очень странного вида -> S-1-142894079-28-13107200-4284711944-842925246-500 (EXPLORER.EXE)
в то время как SID пользователя залогиненного на компе имеет вид -> S-1-5-21-1801674531-1957994488-842925246-500

2) получаемый таким образом SID разный, в зависимости от запущенного процесса, более того он разный даже для одного и того процесса но запущенного дважды ... S-1-1218668031-28-13107200-4284851016-842925246-500 (TOTALCMD.EXE)
S-1-142894079-28-13107200-4284711944-842925246-500 (TOTALCMD.EXE)

3) как видно из п.1. некоторые части SID-ов всё же совпадают, следовательно можно предположить что это не SID пользователя, а например SID процесса, который запущен данным пользователем и следовательно унаследовал от него часть SID-а.

4) когда пытаюсь получить пользователя по SID-у из драйвера с помощью LookUpAccountSID() -> пользователь не находится.

P.S. прошу строго не судить, это только лишь мои догадки
Re[5]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 11.02.04 09:21
Оценка:
Здравствуйте, Canavaro, Вы писали:

хотелось бы уточнить некоторые детали:

в каком именно месте были получены эти данные? это был обработчик IRP-а (если да, то какого именно), или это перехватчик какой-либо ф-ии ядра (например ZwCreateFile)?

какая ОС (nt4/2k/xp/2k3, может быть terminal edition и эти данные получены из терминальной сессии)?

cb.
Re[5]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 11.02.04 09:46
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Сделал всё как написано в этой конфе, получил следующие результаты :

C>1) SID получается очень странного вида -> S-1-142894079-28-13107200-4284711944-842925246-500 (EXPLORER.EXE)
что тут странного? well-known user Administrator но из домена

интересно разве что почему он не начинается с S-1-5-xxxx,
что у вас выступает в качестве NT Authority?

C>в то время как SID пользователя залогиненного на компе имеет вид -> S-1-5-21-1801674531-1957994488-842925246-500

well-known user Administrator но локальный

но что значит EXPLORER.EXE? процесс не имеет SID, процесс имеет user token с owner который имеет SID
Вы имеете ввиду что этот процесс запущен из сессии пользователя с SID указанным выше

C>2) получаемый таким образом SID разный, в зависимости от запущенного процесса, более того он разный даже для одного и того процесса но запущенного дважды ... S-1-1218668031-28-13107200-4284851016-842925246-500 (TOTALCMD.EXE)

C>S-1-142894079-28-13107200-4284711944-842925246-500 (TOTALCMD.EXE)
вопрос, каким-то образом Вы логинитесь (интерактивно, терминал, гостевой\null сеанс)?
ибо вид SID не самый обычный (предположу что это гостевой аккаунт для какой-то сетевой сессии, соотв 2 разных).

опишите рабочее окружение (ОС, какие domain controllers, пользуете ли Вы terminal sessions в своих экспериментах) и конкретные действия

C>3) как видно из п.1. некоторые части SID-ов всё же совпадают, следовательно можно предположить что это не SID пользователя, а например SID процесса, который запущен данным пользователем и следовательно унаследовал от него часть SID-а.

еще раз, у процесса SID нет. есть токен. у токена есть owner который как раз уже имеет SID. Токен наследуется при порождении нового процесса по умолчанию если нет каких-то ограничений или своих приседаний по этому поводу.

Именно поэтому winlogon после обычной авторизации пользователя создает для него сесиию (интерактивную), конструирует токен для этого пользователя и запускает с ним процесс оболочки (обычно explorer.exe) и соотв затем все программы запускаемые из этого explorer унаследуют копию токена родителя.

Если же как-то по иному порождаются процессы, например через CreateProcessAsUserW то им соотв можно сконструировать другой токен, с другим SID (для другого user соотв!). Но если у Вас каждый раз разные SID — это неспроста, это же вся система NT security просто попирается — winlogon запустил нам оболочку в сессии чтоб мы не вышли за пределы, а процессы новые вдруг под левым пользователем порождаются?

про похожесть: разные сессии имеют LogonID типа S-1-5-5-X-Y, где X и Y просто старшая и младшая части адреса в памяти, соотв часто есть совпадения хотя бы по старшей части. Если разобраться почему у Вас не S-1-5 начало (что вполне допустимо просто реже встречается), то в остальном Вы получили похожие на правду LogonID что и дает такое странное поведение.

надо разбираться — возможно просто неправильно получен SID в ядре, может быть это LogonID у Вас?
попробуйте с помощью разных программ в user mode получить то же самое для своих процессов — чей SID с ними ассоциирован через токен?

C>4) когда пытаюсь получить пользователя по SID-у из драйвера с помощью LookUpAccountSID() -> пользователь не находится.

код ошибки где?

C>P.S. прошу строго не судить, это только лишь мои догадки

очень интересно получить информацию чтобы попытаться воспроизвести у себя
... << RSDN@Home 1.1.3 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[6]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 10:08
Оценка:
Здравствуйте, _cb_, Вы писали:

__>Здравствуйте, Canavaro, Вы писали:


__>хотелось бы уточнить некоторые детали:


__>в каком именно месте были получены эти данные? это был обработчик IRP-а (если да, то какого именно)


всё это я делаю в фильтре FS, по стандартной технологии атачусь к файловым системам и ко мне сыпятся IRP-ы предназначенные для них

__>какая ОС (nt4/2k/xp/2k3, может быть terminal edition и эти данные получены из терминальной сессии)?


ОС — Win2k Server c Terminal Services, данные получались как локально так и из терминальной сессии.
Re[6]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 10:43
Оценка:
Здравствуйте, Valerio, Вы писали:

C>>Сделал всё как написано в этой конфе, получил следующие результаты :

C>>1) SID получается очень странного вида -> S-1-142894079-28-13107200-4284711944-842925246-500 (EXPLORER.EXE)
V>что тут странного? well-known user Administrator но из домена

V>интересно разве что почему он не начинается с S-1-5-xxxx,

вот в этом то всё и дело ....
V>что у вас выступает в качестве NT Authority?

C>>в то время как SID пользователя залогиненного на компе имеет вид -> S-1-5-21-1801674531-1957994488-842925246-500

V>well-known user Administrator но локальный

V>но что значит EXPLORER.EXE? процесс не имеет SID, процесс имеет user token с owner который имеет SID

V>Вы имеете ввиду что этот процесс запущен из сессии пользователя с SID указанным выше
совершенно верно ! насчёт SID процесса было просто предположение

C>>2) получаемый таким образом SID разный, в зависимости от запущенного процесса, более того он разный даже для одного и того процесса но запущенного дважды ... S-1-1218668031-28-13107200-4284851016-842925246-500 (TOTALCMD.EXE)

C>>S-1-142894079-28-13107200-4284711944-842925246-500 (TOTALCMD.EXE)
V>вопрос, каким-то образом Вы логинитесь (интерактивно, терминал, гостевой\null сеанс)?

логинился как локально так и через терминальную сессию, результаты практически не отличаются

V>ибо вид SID не самый обычный (предположу что это гостевой аккаунт для какой-то сетевой сессии, соотв 2 разных).


V>опишите рабочее окружение (ОС, какие domain controllers, пользуете ли Вы terminal sessions в своих экспериментах) и конкретные действия


ОС — Win2k Server c Terminal Services, не контроллер домена, SID пытаюсь получить в фильтре FS

C>>3) как видно из п.1. некоторые части SID-ов всё же совпадают, следовательно можно предположить что это не SID пользователя, а например SID процесса, который запущен данным пользователем и следовательно унаследовал от него часть SID-а.

V>еще раз, у процесса SID нет. есть токен. у токена есть owner который как раз уже имеет SID. Токен наследуется при порождении нового процесса по умолчанию если нет каких-то ограничений или своих приседаний по этому поводу.

V>Именно поэтому winlogon после обычной авторизации пользователя создает для него сесиию (интерактивную), конструирует токен для этого пользователя и запускает с ним процесс оболочки (обычно explorer.exe) и соотв затем все программы запускаемые из этого explorer унаследуют копию токена родителя.


V>Если же как-то по иному порождаются процессы, например через CreateProcessAsUserW то им соотв можно сконструировать другой токен, с другим SID (для другого user соотв!). Но если у Вас каждый раз разные SID — это неспроста, это же вся система NT security просто попирается — winlogon запустил нам оболочку в сессии чтоб мы не вышли за пределы, а процессы новые вдруг под левым пользователем порождаются?


V>про похожесть: разные сессии имеют LogonID типа S-1-5-5-X-Y, где X и Y просто старшая и младшая части адреса в памяти, соотв часто есть совпадения хотя бы по старшей части. Если разобраться почему у Вас не S-1-5 начало (что вполне допустимо просто реже встречается), то в остальном Вы получили похожие на правду LogonID что и дает такое странное поведение.


V>надо разбираться — возможно просто неправильно получен SID в ядре, может быть это LogonID у Вас?

V>попробуйте с помощью разных программ в user mode получить то же самое для своих процессов — чей SID с ними ассоциирован через токен?

попробую конечно, но думаю всё будет работать нормально ...

C>>4) когда пытаюсь получить пользователя по SID-у из драйвера с помощью LookUpAccountSID() -> пользователь не находится.

V>код ошибки где?

0x00000057 The parametr is incorrect.

C>>P.S. прошу строго не судить, это только лишь мои догадки

V>очень интересно получить информацию чтобы попытаться воспроизвести у себя
Re[7]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 11.02.04 12:00
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>всё это я делаю в фильтре FS, по стандартной технологии атачусь к файловым системам и ко мне сыпятся IRP-ы предназначенные для них


все-таки — в обработчике какого irp Вы получили эти данные? IRP_MJ_CREATE? или это собирательная информация из разных irp-ов?

cb
Re[8]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 12:59
Оценка:
Здравствуйте, _cb_, Вы писали:

__>Здравствуйте, Canavaro, Вы писали:


C>>всё это я делаю в фильтре FS, по стандартной технологии атачусь к файловым системам и ко мне сыпятся IRP-ы предназначенные для них


__>все-таки — в обработчике какого irp Вы получили эти данные? IRP_MJ_CREATE? или это собирательная информация из разных irp-ов?


ну наприммер IRP_MJ_READ
Re[9]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 11.02.04 13:05
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Здравствуйте, _cb_, Вы писали:


__>>Здравствуйте, Canavaro, Вы писали:


C>>>всё это я делаю в фильтре FS, по стандартной технологии атачусь к файловым системам и ко мне сыпятся IRP-ы предназначенные для них


__>>все-таки — в обработчике какого irp Вы получили эти данные? IRP_MJ_CREATE? или это собирательная информация из разных irp-ов?


C>ну наприммер IRP_MJ_READ


случайно не в CompletionRoutine?

cb.
Re[10]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 13:11
Оценка:
Здравствуйте, _cb_, Вы писали:

__>случайно не в CompletionRoutine?


нет

ещё попробовал на XP Professional, тоже самое
Re[11]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 11.02.04 13:42
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>ещё попробовал на XP Professional, тоже самое


на сколько я помню все проверки безопасности рекомендуется делать на irp_mj_create, а потом если Вам нужно знать какой пользователь посылает read, write и прочие запросы необходимо реализовать свой кеш открытых объектов. т.е на irp_mj_create получаете всю необходимую инфу и сохраняете ее в map-е где в качестве ключа используется file_object & fs_context, и при получении запросов ищете эту инфу в этом мапе...
возможно что описанное Вами поведение это нормальная жизнь оси...

cb.
Re[12]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 14:06
Оценка:
Здравствуйте, _cb_,

а вы сами то пробовали так делать как написали ?
если да, то какие у вас получались SID-ы ?
Re[6]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 14:12
Оценка:
Здравствуйте, Valerio, Вы писали:

V>надо разбираться — возможно просто неправильно получен SID в ядре, может быть это LogonID у Вас?

V>попробуйте с помощью разных программ в user mode получить то же самое для своих процессов — чей SID с ними ассоциирован через токен?

попробовал и получил совершено нормальный well-known Administartor SID S-1-5-21-1801674531-1957994488-842925246-500
Re[13]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 11.02.04 14:24
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Здравствуйте, _cb_,


C>а вы сами то пробовали так делать как написали ?

C>если да, то какие у вас получались SID-ы ?

пробовал... с cидами проблем не было если удавалось поймать irp_mj_create. т.е. я получал сид залогиненного пользователя.

cb.
Re[14]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 14:34
Оценка:
Здравствуйте, _cb_, Вы писали:

__>пробовал... с cидами проблем не было если удавалось поймать irp_mj_create. т.е. я получал сид залогиненного пользователя.


я тоже попробовал ловить на IRP_MJ_CREATE -> никакой разницы
Re[15]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 11.02.04 14:40
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>я тоже попробовал ловить на IRP_MJ_CREATE -> никакой разницы


возможно где-то Вы ошиблись...
можете попробовать еще один способ

http://www.rsdn.ru/Forum/Message.aspx?mid=525306&amp;only=1
Автор: _cb_
Дата: 30.01.04



NTKERNELAPI
NTSTATUS
SeQueryInformationToken (
    IN PACCESS_TOKEN Token,
    IN TOKEN_INFORMATION_CLASS TokenInformationClass,
    OUT PVOID *TokenInformation
    );



в данный момент я пользуюсь именно им.. на irp_create получаю сид — запоминаю его в своем map-e, а потом использую по необходимости...

cb.
Re[7]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 11.02.04 15:22
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Здравствуйте, Valerio, Вы писали:


V>>надо разбираться — возможно просто неправильно получен SID в ядре, может быть это LogonID у Вас?

V>>попробуйте с помощью разных программ в user mode получить то же самое для своих процессов — чей SID с ними ассоциирован через токен?

C>попробовал и получил совершено нормальный well-known Administartor SID S-1-5-21-1801674531-1957994488-842925246-500

значит ошибка у Вас

плюс прислушайтесь к _cb_: вытягивайте SID только в CREATE
во-вторых он правильно спросил в completion или нет Вы вытягиваете инфу: если в стеке есть хитрый драйвер вроде одной из версии NAV, то он может запросто переключить контекст на свой поток и Вы получите SID немного не тот... но в любом случае не такой странный, ИМХО
... << RSDN@Home 1.1.3 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[16]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 11.02.04 16:20
Оценка:
Здравствуйте, _cb_, Вы писали:

__>можете попробовать еще один способ


__>http://www.rsdn.ru/Forum/Message.aspx?mid=525306&amp;only=1
Автор: _cb_
Дата: 30.01.04



__>
__>NTKERNELAPI
__>NTSTATUS
__>SeQueryInformationToken (
__>    IN PACCESS_TOKEN Token,
__>    IN TOKEN_INFORMATION_CLASS TokenInformationClass,
__>    OUT PVOID *TokenInformation
__>    );
__>



__>в данный момент я пользуюсь именно им.. на irp_create получаю сид — запоминаю его в своем map-e, а потом использую по необходимости...


огромное спасибо, так вроде пока работает !
Re[12]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 12.02.04 09:14
Оценка:
Здравствуйте, _cb_, Вы писали:

__>на сколько я помню все проверки безопасности рекомендуется делать на irp_mj_create, а потом если Вам нужно знать какой пользователь посылает read, write и прочие запросы необходимо реализовать свой кеш открытых объектов. т.е на irp_mj_create получаете всю необходимую инфу и сохраняете ее в map-е где в качестве ключа используется file_object & fs_context, и при получении запросов ищете эту инфу в этом мапе...


если можно, то расскажите пожалуйста поподробнее про этот механизм, хотя бы в сторону каких функций копать.
Заранее спасибо!
Re[13]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 12.02.04 09:46
Оценка:
Здравствуйте, Canavaro, Вы писали:

__>>на сколько я помню все проверки безопасности рекомендуется делать на irp_mj_create, а потом если Вам нужно знать какой пользователь посылает read, write и прочие запросы необходимо реализовать свой кеш открытых объектов. т.е на irp_mj_create получаете всю необходимую инфу и сохраняете ее в map-е где в качестве ключа используется file_object & fs_context, и при получении запросов ищете эту инфу в этом мапе...


C>если можно, то расскажите пожалуйста поподробнее про этот механизм, хотя бы в сторону каких функций копать.

C>Заранее спасибо!

рассказать про что именно?

— про механизм создания кеша открытых объектов?
— или про то как правильно помещать в кеш объекты и когда их оттуда удалять?

по поводу второго пункта — есть ссылка на osr

http://www.osr.com/ntinsider/2002/tracking/tracking.htm

про первый пункт — здесь Вы ограничены только своей изобретательностью:
Вам надо так или иначе сохранять свои данные и ассоциировать их с каким-то ключем. ключ вы однозначно получаете из самого irp-а (в данном случае в качестве ключа используется указатель на FileObject и указатель на FsContext), после получения ключа Вы просто ищете в своем кеше данные которые с этим ключем ассоциированы.
в stl есть готовая реализация подобной структуры — map. однако использование stl при разработки драйверов затруднено (хотя и возможно), поэтому скорее всего Вам придется придумать свой способ хранения этой информации...


cb.
Re[14]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 17.02.04 08:19
Оценка:
Здравствуйте, _cb_, Вы писали:

__>Вам надо так или иначе сохранять свои данные и ассоциировать их с каким-то ключем. ключ вы однозначно получаете из самого irp-а (в данном случае в качестве ключа используется указатель на FileObject и указатель на FsContext), после получения ключа Вы просто ищете в своем кеше данные которые с этим ключем ассоциированы.


странно как то получается, но у меня на IRP_MJ_CREATE PtrCurrentStackLocation->FileObject->FsContext равно нулю ...
Re[15]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 17.02.04 08:50
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Здравствуйте, _cb_, Вы писали:


__>>Вам надо так или иначе сохранять свои данные и ассоциировать их с каким-то ключем. ключ вы однозначно получаете из самого irp-а (в данном случае в качестве ключа используется указатель на FileObject и указатель на FsContext), после получения ключа Вы просто ищете в своем кеше данные которые с этим ключем ассоциированы.


C>странно как то получается, но у меня на IRP_MJ_CREATE PtrCurrentStackLocation->FileObject->FsContext равно нулю ...


В какой момент? до исполнения IRP_MJ_CREATE?
если до — то это правильно, потому что FsContext заполняется драйвером файловой системы в случае успешного открытия файла...

cb.
Re[16]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 17.02.04 09:47
Оценка:
Здравствуйте, _cb_, Вы писали:

__>В какой момент? до исполнения IRP_MJ_CREATE?

__>если до — то это правильно, потому что FsContext заполняется драйвером файловой системы в случае успешного открытия файла...

точно ДО !!!
Заранее прошу прощения за вероятно глупый вопрос, но как мне после того как я слепил IRP и послал его дальше драйверу файловой системы [IoCallDriver(PtrTargetDeviceObject, Irp)] получить FsContext ?

PtrCurrentStackLocation = IoGetCurrentIrpStackLocation(PtrTargetDeviceObject->CurrentIrp);
context = PtrCurrentStackLocation->FileObject->FsContext;


или можно по другому, более правильно ?
Re[17]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 17.02.04 10:11
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>точно ДО !!!

C>Заранее прошу прощения за вероятно глупый вопрос, но как мне после того как я слепил IRP и послал его дальше драйверу файловой системы [IoCallDriver(PtrTargetDeviceObject, Irp)] получить FsContext ?

C>
C>PtrCurrentStackLocation = IoGetCurrentIrpStackLocation(PtrTargetDeviceObject->CurrentIrp);
C>context = PtrCurrentStackLocation->FileObject->FsContext;
C>


C>или можно по другому, более правильно ?


после вызова IoCallDriver IRP скорее всего станет невалидным, потому что IRP_MJ_CREATE выполняется синхронно.
поэтому видимо проще запомнить указатель на FILE_OBJECT, а после вызова драйвера файловой системы и успешного открытия файла проверить поле FsContext.

cb.
Re[18]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 18.02.04 08:39
Оценка:
Здравствуйте, _cb_, Вы писали:

__>после вызова IoCallDriver IRP скорее всего станет невалидным, потому что IRP_MJ_CREATE выполняется синхронно.

__>поэтому видимо проще запомнить указатель на FILE_OBJECT, а после вызова драйвера файловой системы и успешного открытия файла проверить поле FsContext.

так работает, но есть одно "НО":
в качестве ключа как вы и говорили у меня выступает :

DWORD pr_key = (DWORD)FileObject & (DWORD)FileObject;

но при получении IRP_MJ_CREATE для одного и того же объекта файловой системы, одним и тем же процессом от имени одного и того же пользователя значение pr_key разное ... прочём разные получаются значения (DWORD)FileObjectа, а FsContext не меняется ... Может ли это означать что в такой маленький промежуток времени какой прошёл между обращениями, этот объет мог быть закрыт и открыт заново ?
Re[19]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 18.02.04 08:53
Оценка: 4 (1)
Здравствуйте, Canavaro, Вы писали:

C>Здравствуйте, _cb_, Вы писали:


C>так работает, но есть одно "НО":

C>в качестве ключа как вы и говорили у меня выступает :

C>DWORD pr_key = (DWORD)FileObject & (DWORD)FileObject;


здесь видимо имеется ввиду ((DWORD)FileObject & (DWORD)FsContext)?
сорри что ввел в заблуждение... я не имел ввиду буквально операцию AND.
я имел ввиду что в Вашем хранилище должен быть быть учет обоих ключей (FileObject и FsContext). дело в том что некоторые FileObject создаются системой без посылки IRP_MJ_CREATE. такие FO ссылаются на реально открытый объект посредством FsContext, который совпадает с FsContext-ом реально открытого объекта. поэтому поиск в кеше можно делать как по FileObject так и по FsContext. но это всего лишь один из вариантов реализации кеша. Вы можете придумать свой.

я уже давал ссылку на статью в osr — где описываются алгоритмы построения кеша открытых объектов, там это сделано более грамотно чем я могу это изложить...

http://www.osr.com/ntinsider/2002/tracking/tracking.htm


C>но при получении IRP_MJ_CREATE для одного и того же объекта файловой системы, одним и тем же процессом от имени одного и того же пользователя значение pr_key разное ... прочём разные получаются значения (DWORD)FileObjectа, а FsContext не меняется ... Может ли это означать что в такой маленький промежуток времени какой прошёл между обращениями, этот объет мог быть закрыт и открыт заново ?


а вот этот пункт мне не очень понятен. раз Вы получили IRP_MJ_CREATE то это означает что происходит повторное открытие объекта. а вот должен ли при этом открытии поменяться FsContext видимо зависит от реализации FSD. возможно что для одного объекта файловой системы при повторном открытии не создается новый fs context, хотя мне лично это кажется маловероятным.
к сожалению тут я ничем помочь не могу — надо исследовать, я с этим не сталкивался.

cb.
Re[20]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 19.02.04 05:40
Оценка:
__>я уже давал ссылку на статью в osr — где описываются алгоритмы построения кеша открытых объектов, там это сделано более грамотно чем я могу это изложить...

__>http://www.osr.com/ntinsider/2002/tracking/tracking.htm

мои 5 копеек, там есть псевдокод и была опечатка в конце статьи ставящяя все с ног на голову, be ready

C>>но при получении IRP_MJ_CREATE для одного и того же объекта файловой системы, одним и тем же процессом от имени одного и того же пользователя значение pr_key разное ... прочём разные получаются значения (DWORD)FileObjectа, а FsContext не меняется ... Может ли это означать что в такой маленький промежуток времени какой прошёл между обращениями, этот объет мог быть закрыт и открыт заново ?


__>а вот этот пункт мне не очень понятен. раз Вы получили IRP_MJ_CREATE то это означает что происходит повторное открытие объекта. а вот должен ли при этом открытии поменяться FsContext видимо зависит от реализации FSD. возможно что для одного объекта файловой системы при повторном открытии не создается новый fs context, хотя мне лично это кажется маловероятным.

__>к сожалению тут я ничем помочь не могу — надо исследовать, я с этим не сталкивался.
с одного FCB (FsContext) свисает много FileObject. Например 2 экземпляра одного файла дадут Вам такое дело. Такое поведение FsContext действительно забота писателя FSD, но сейчас оно гарантируется для локальных FSD, поставляемых с ОС. Сетевые FSD (редиректоры) этого уже не гарантируют хотя LanMan redirector пока соответствует.

__>cb.
... << RSDN@Home 1.1.3 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[18]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 25.02.04 14:58
Оценка:
Здравствуйте, _cb_, Вы писали:


__>после вызова IoCallDriver IRP скорее всего станет невалидным, потому что IRP_MJ_CREATE выполняется синхронно.

__>поэтому видимо проще запомнить указатель на FILE_OBJECT, а после вызова драйвера файловой системы и успешного открытия файла проверить поле FsContext.

но тогда получается, что после проверки имени файла и DesiredAccess я не смогу зарубить IRP_MJ_CREATE ...
или можно ещё каким способом узнать имя файла, ведь перед посылкой запроса на открытие к драйверу файловой системы где-то должно храниться имя открываемого объкта ...
Re[19]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 25.02.04 17:47
Оценка:
Здравствуйте, Canavaro, Вы писали:

__>>после вызова IoCallDriver IRP скорее всего станет невалидным, потому что IRP_MJ_CREATE выполняется синхронно.

__>>поэтому видимо проще запомнить указатель на FILE_OBJECT, а после вызова драйвера файловой системы и успешного открытия файла проверить поле FsContext.

C>но тогда получается, что после проверки имени файла и DesiredAccess я не смогу зарубить IRP_MJ_CREATE ...

C>или можно ещё каким способом узнать имя файла, ведь перед посылкой запроса на открытие к драйверу файловой системы где-то должно храниться имя открываемого объкта ...


вот здесь описано как сделать cancel irp_mj_create

http://www.osronline.com/article.cfm?id=17#Q6

про получение имени до выполнения открытия объекта могу сказать, что это достаточно сложная процедура, плюс не дающая 100% гарантии получения верного результата. я бы не рекомендовал Вам идти этим путем. если Вы все же решите попробовать этот вариант, то напишите мне по почте — я вышлю Вам код, который я использовал для этого, или посмотрите ранние версии ifskit_2k\src\filesys\filter\filespy, там есть пример получения имени до выполнения irp_mj_create.

cb.
Re[20]: Можно ли в драйвере получить имя юзера?
От: Аноним  
Дата: 26.02.04 07:37
Оценка:
Здравствуйте, _cb_, Вы писали:

__>вот здесь описано как сделать cancel irp_mj_create


__>http://www.osronline.com/article.cfm?id=17#Q6


понятно ...

__>про получение имени до выполнения открытия объекта могу сказать, что это достаточно сложная процедура, плюс не дающая 100% гарантии получения верного результата. я бы не рекомендовал Вам идти этим путем. если Вы все же решите попробовать этот вариант, то напишите мне по почте — я вышлю Вам код, который я использовал для этого,


послал письмо, жду ответа ...

и ещё, читал в этом форуме что если в pIrpStack->Parameters.Create.Options установлен флаг FILE_OPEN_BY_FILE_ID, то файл открывается по FILE_ID и его как то можно преобразовать в имя файла ...
Re[21]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 26.02.04 08:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>послал письмо, жду ответа ...


ок.

А>и ещё, читал в этом форуме что если в pIrpStack->Parameters.Create.Options установлен флаг FILE_OPEN_BY_FILE_ID, то файл открывается по FILE_ID и его как то можно преобразовать в имя файла ...


я слышал что у файла теоретически может не быть символического имени — есть только ID. реально я с таким не сталкивался. а преобразования как такового нет — можно получить информацию о файле, там и можно увидеть его символическое имя.

cb.
Re[20]: Можно ли в драйвере получить имя юзера?
От: Аноним  
Дата: 26.02.04 11:57
Оценка:
Здравствуйте, _cb_, Вы писали:

__>вот здесь описано как сделать cancel irp_mj_create


__>http://www.osronline.com/article.cfm?id=17#Q6


я так понял что IoCancelFileOpen() нужно использовать в CREATE CompletionRoutine, но опять тот же вопрос — к этому времени я буду знать имя файла ? Ведь наскока я понимаю управление ещё не вернётся в мой Dispatcher ...
Спрошу проще: можно ли при помощи IoCancelFileOpen() реализовать схему :

IoCallDriver(...);
if (!Check(FileObj->FileName))
{
CancelCreate();
return STATUS_UNSUCCESSFUL;
}
Re[21]: Можно ли в драйвере получить имя юзера?
От: _cb_  
Дата: 26.02.04 12:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>я так понял что IoCancelFileOpen() нужно использовать в CREATE CompletionRoutine, но опять тот же вопрос — к этому времени я буду знать имя файла ? Ведь наскока я понимаю управление ещё не вернётся в мой Dispatcher ...


имя можно получить и в completion routine. потому что irp_mj_create всегда выполняется на passive_level и является синхронной операцией.

А>Спрошу проще: можно ли при помощи IoCancelFileOpen() реализовать схему :


А>IoCallDriver(...);

А>if (!Check(FileObj->FileName))
А>{
А>CancelCreate();
А>return STATUS_UNSUCCESSFUL;
А>}

лично я IoCancelFileOpen не использовал поэтому точно не могу сказать где именно она должна вызываться. однако судя по документации описанный Вами сценарий вполне работоспособен, надо только не забыть изменить значение pIrp->IoStatus.Status на STATUS_UNSUCCESSFUL.

cb.
Re[22]: Можно ли в драйвере получить имя юзера?
От: Злость Россия  
Дата: 26.02.04 13:11
Оценка:
Здравствуйте, _cb_, Вы писали:

__>Здравствуйте, Аноним, Вы писали:


А>>я так понял что IoCancelFileOpen() нужно использовать в CREATE CompletionRoutine, но опять тот же вопрос — к этому времени я буду знать имя файла ? Ведь наскока я понимаю управление ещё не вернётся в мой Dispatcher ...


__>имя можно получить и в completion routine. потому что irp_mj_create всегда выполняется на passive_level и является синхронной операцией.


А>>Спрошу проще: можно ли при помощи IoCancelFileOpen() реализовать схему :


А>>IoCallDriver(...);

А>>if (!Check(FileObj->FileName))
А>>{
А>>CancelCreate();
А>>return STATUS_UNSUCCESSFUL;
А>>}

Не ясно как вы будете FileObj->FileName использовать после IoCallDriver — или FileObj->FileName эта ваша внутрення переменная и вы уже скопировали имя файла до вызова IoCallDriver ?

__>лично я IoCancelFileOpen не использовал поэтому точно не могу сказать где именно она должна вызываться. однако судя по документации описанный Вами сценарий вполне работоспособен, надо только не забыть изменить значение pIrp->IoStatus.Status на STATUS_UNSUCCESSFUL.


__>cb.
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Re[21]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 27.02.04 05:34
Оценка:
А>и ещё, читал в этом форуме что если в pIrpStack->Parameters.Create.Options установлен флаг FILE_OPEN_BY_FILE_ID, то файл открывается по FILE_ID и его как то можно преобразовать в имя файла ...
точно так же, как и в случае короткого имени например — выполнить подзапрос на получение имени файла
... << RSDN@Home 1.1.3 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[21]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 27.02.04 05:39
Оценка:
А>я так понял что IoCancelFileOpen() нужно использовать в CREATE CompletionRoutine, но опять тот же вопрос — к этому времени я буду знать имя файла ? Ведь наскока я понимаю управление ещё не вернётся в мой Dispatcher ...
Имя в Вашей completion Вы уже будете знать — CREATE синхронная операция.

до вызова IoCallDriver(...); Вы можете отменть запрос штатным методом — не вызывать IoCallDriver(...); и просто вернуть ошибку, поэтому IoCancelFileOpen реально нужен в completion и Ваша схема вполне рабочая (только обычно я возвращаю STATUS_ACCESS_DENIED). Часто без completion не обойтись ибо приходится открывать файл чтобы хотя бы его имя получить либо какую-то иную информацию из самого файла\о нем самом — не директория ли он например.

стоит отметить что IoCancelFileOpen это 2000 и выше, однако на NT4 реализация довольно тривиальна: это посылка синхронных CLEANUP & CLOSE, как и написано в статье от OSR.
... << RSDN@Home 1.1.3 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[22]: Можно ли в драйвере получить имя юзера?
От: Canavaro Россия  
Дата: 27.02.04 07:42
Оценка:
Здравствуйте, Valerio, Вы писали:

Всем спасибо, я сделал, всё работает :
Сохраняю pFileObj перед вызовом IoCallDriver();
На обратном пути от файловой системы в CompletoinRoutine получаю имя файла;
Там же, если надо, вызываю IoCancelFileOpen;
PtrIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
return STATUS_SUCCESS;

кстати какая разница между STATUS_UNSUCCESSFUL и STATUS_ACCESS_DENIED ?
Re[23]: Можно ли в драйвере получить имя юзера?
От: Valerio Россия linkedin.com/in/boronin
Дата: 27.02.04 08:51
Оценка:
C>кстати какая разница между STATUS_UNSUCCESSFUL и STATUS_ACCESS_DENIED ?
разница в семантическом смысле
просто чаще всего приложения готовы к обработке STATUS_ACCESS_DENIED чем абстрактного неуспеха
... << RSDN@Home 1.1.3 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.