Прошу прощения за длинный пост
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