Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Пайпы в kernel mode  (Прочитано 5983 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Detsel
Гость
« : 02-06-2005 12:45 » 

Возможно ли организовать в драйвере клиентскую часть для работы с пайпом. Интересно, сработает ли ZwCreateFile для \\\\.\\pipe\\PipeName Спасибо
Записан
dachny
Гость
« Ответ #1 : 03-06-2005 04:50 » 

Прошу прощения за длинный пост

How can I create named pipe in the kernel-mode (NtCreateNamedPipeFile/ZwCreateNamedPipeFile is not exported by ntoskrnl.exe)?

A: There are several ways to do this:

You can call the service through the service index in the Service Descriptor Table (SDT) using INT2E, like ntdll.dll does.
   .text:77F883D6 public ZwCreateNamedPipeFile
   .text:77F883D6 ZwCreateNamedPipeFile proc near
   .text:77F883D6
   .text:77F883D6 arg_0 = byte ptr 4
   .text:77F883D6
   .text:77F883D6 mov eax, 26h ; NtCreateNamedPipeFile
   .text:77F883DB lea edx, [esp+arg_0]
   .text:77F883DF int 2Eh ; DOS 2+ internal - EXECUTE COMMAND
   .text:77F883DF ; DS:SI -> counted CR-terminated command string
   .text:77F883E1 retn 38h
   .text:77F883E1 ZwCreateNamedPipeFile endp
 
You can use the index of NtCreateNamedPipeFile in SDT to obtain service address from SDT (address of SDT is exported by ntoskrnl.exe under KeServiceDescriptorTable name) and then call the service routine in ntoskrnl.exe.
Both previously described approaches are universal in that sense that you can do the same for the calling any non-exported service from ntoskrnl.exe. The only disadvantage of them is that you need to know service index in SDT, which is the subject of changes between Windows versions (or even service packs). You can extract this index dynamically from ntdll.dll image to resolve this problem. However, I suppose it's a bit overwork. One more approach to create named pipe in the kernel-mode is to use IoCreateFile routine. The following code works just like NtCreateNamedPipeFile:

NTSTATUS  NtCreateNamedPipeFile (
            OUT PHANDLE FileHandle,
            IN ULONG DesiredAccess,
         IN POBJECT_ATTRIBUTES ObjectAttributes,
         OUT PIO_STATUS_BLOCK IoStatusBlock,
         IN ULONG ShareAccess,
         IN ULONG CreateDisposition,
         IN ULONG CreateOptions,
         IN ULONG NamedPipeType,
         IN ULONG ReadMode,
         IN ULONG CompletionMode,
         IN ULONG MaximumInstances,
         IN ULONG InboundQuota,
         IN ULONG OutboundQuota,
         IN PLARGE_INTEGER DefaultTimeout OPTIONAL
         ) 
{   
   NAMED_PIPE_CREATE_PARAMETERS NamedPipeParms;
   NTSTATUS Status;
   __try   
   {   
      if ( DefaultTimeout )
      {
            NamedPipeParms.TimeoutSpecified = TRUE;
            NamedPipeParms.DefaultTimeout.QuadPart = DefaultTimeout->QuadPart;
      }
      else
      {   
         NamedPipeParms.TimeoutSpecified = FALSE;
      }
       
      NamedPipeParms.NamedPipeType = NamedPipeType;
      NamedPipeParms.ReadMode = ReadMode;
      NamedPipeParms.CompletionMode = CompletionMode;
      NamedPipeParms.MaximumInstances = MaximumInstances;
      NamedPipeParms.InboundQuota = InboundQuota;
      NamedPipeParms.OutboundQuota = OutboundQuota;
      Status = IoCreateFile (
                  FileHandle,
               DesiredAccess,
               ObjectAttributes,
               IoStatusBlock,
               NULL,
               0,
               ShareAccess,
               CreateDisposition,
               CreateOptions,
               NULL,
               0,
               CreateFileTypeNamedPipe,
               &NamedPipeParms,
               0   
               );

      return Status;
   }   
   __except (EXCEPTION_EXECUTE_HANDLER)   
   {
      KdPrint (("NtCreateNamedPipeFile: Exception occured.\n"));
      return STATUS_UNSUCCESSFUL;   
   }
}   
The routine can be called as the following:

#define NAMED_PIPE_NAME L"\\??\\pipe\\PipeClient"
...
// Some code skipped
...
   RtlInitUnicodeString ( &namedPipe, NAMED_PIPE_NAME );
   InitializeObjectAttributes (
      &attr,
       &namedPipe,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
       NULL,
       NULL
       );
    nTimeOut.QuadPart = -1000;
 
// Create Named Pipe
   ntStatus = NtCreateNamedPipeFile (
         &g_hNamedPipeHandle,
          FILE_ANY_ACCESS,
         &attr,
         &ioStatusBlock,
         FILE_SHARE_READ | FILE_SHARE_WRITE,
         FILE_CREATE,
         0,
         FILE_PIPE_BYTE_STREAM_TYPE,
         FILE_PIPE_BYTE_STREAM_MODE,
          FILE_PIPE_QUEUE_OPERATION,
         1,
         0,
         0,
         &nTimeOut
         );

   if (NT_SUCCESS (ntStatus))
   {
      KdPrint (("Pipe created succesfully\n"));
   }
Please pay attention to two important notes:

nTimeOut, this parameter is declared as OPTIONAL but at least on my Windows 2000 SP2 box it's required.
When creating named pipe I've specified OBJ_KERNEL_HANDLE attribute. This allows to use named pipe handle in the arbitrary process context in the kernel (if not specified the handle is valid only in the context of creator process). The only problem is that OBJ_KERNEL_HANDLE was introduced Windows 2000 and it does not work in NT 4.0, where the best choice is to create named pipe in the context of System process.

original здесь http://www.ntkernel.com/w&p.php?id=17
« Последнее редактирование: 19-12-2007 21:18 от Алексей1153++ » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines