本论坛为只读模式,仅供查阅,不能注册新用户,不能发帖/回帖,有问题可发邮件 xikug.xp (^) gmail.com
查看: 8398|回复: 31

内核Pipe [复制链接]

Rank: 2

发表于 2011-11-8 13:20:02 |显示全部楼层
如题。。。。本来想用pipe做驱动和应用层通信的,后来发现。。。pipe这东西,在内核没有具体的导出函数可用,于是在某人的大力协助下逆向了下ring3那一系列pipe相关的函数的实现。。。遂成此文。

代码未经测试。。。不过应该没啥大问题。
  1. NTSTATUS ZwCreateNamedPipeFile (
  2.                                         OUT PHANDLE phPipeHandle,
  3.                                         IN ULONG ulDesiredAccess,
  4.                                         IN POBJECT_ATTRIBUTES pObjAttr,
  5.                                         OUT PIO_STATUS_BLOCK pIoStatus,
  6.                                         IN ULONG ulShareAccess,
  7.                                         IN ULONG ulCreateDisposition,
  8.                                         IN ULONG ulCreateOptions,
  9.                                         IN BOOLEAN bIsMsgType,
  10.                                         IN BOOLEAN bIsMsgMode,
  11.                                         IN BOOLEAN bIsNonBlocking,
  12.                                         IN ULONG ulMaximumInstances,
  13.                                         IN ULONG ulInBufSize,
  14.                                         IN ULONG ulOutBufSize,
  15.                                         IN PLARGE_INTEGER pliDefaultTimeout OPTIONAL )  
  16. {   
  17.         NAMED_PIPE_CREATE_PARAMETERS NamedPipeParms={0};

  18.         NTSTATUS NtStatus={0};
  19.         __try   
  20.         {   
  21.                 if ( pliDefaultTimeout )
  22.                 {
  23.                         NamedPipeParms.TimeoutSpecified = TRUE;

  24.                         NamedPipeParms.DefaultTimeout.QuadPart = pliDefaultTimeout->QuadPart;
  25.                 }
  26.                 else
  27.                 {   
  28.                         NamedPipeParms.TimeoutSpecified = FALSE;
  29.                 }

  30.                 NamedPipeParms.NamedPipeType = bIsMsgType;

  31.                 NamedPipeParms.ReadMode = bIsMsgMode;

  32.                 NamedPipeParms.CompletionMode = bIsNonBlocking;

  33.                 NamedPipeParms.MaximumInstances = ulMaximumInstances;

  34.                 NamedPipeParms.InboundQuota = ulInBufSize;

  35.                 NamedPipeParms.OutboundQuota = ulOutBufSize;

  36.                 NtStatus = IoCreateFile(
  37.                         phPipeHandle,
  38.                         ulDesiredAccess,
  39.                         pObjAttr,
  40.                         pIoStatus,
  41.                         NULL,
  42.                         0,
  43.                         ulShareAccess,
  44.                         ulCreateDisposition,
  45.                         ulCreateOptions,
  46.                         NULL,
  47.                         0,
  48.                         CreateFileTypeNamedPipe,
  49.                         &NamedPipeParms,
  50.                         0   
  51.                         );

  52.                 return NtStatus;
  53. }   
  54. __except (EXCEPTION_EXECUTE_HANDLER)   
  55. {
  56.         KdPrint (("ZwCreateNamedPipeFile: Exception occured.\n"));
  57.         return GetExceptionCode();   
  58. }
  59. }   


  60. NTSTATUS __stdcall ZwCreateNamedPipe(PWCHAR pwszPipeName,
  61.                                                                          ULONG ulMaxInBufSize,
  62.                                                                          ULONG ulMaxOutBufSize,
  63.                                                                          ULONG ulMaxClientCount,
  64.                                                                          LARGE_INTEGER liTimeOut,
  65.                                                                          PHANDLE phPipe)
  66. {
  67.         NTSTATUS NtStatus=STATUS_SUCCESS;

  68.         HANDLE hPipe=NULL;

  69.         UNICODE_STRING uniPipeName={0};

  70.         OBJECT_ATTRIBUTES ObjAttr={0};

  71.         IO_STATUS_BLOCK IoStatus={0};

  72.         RtlInitUnicodeString(&uniPipeName,pwszPipeName);

  73.         InitializeObjectAttributes(&ObjAttr,&uniPipeName,OBJ_CASE_INSENSITIVE,NULL,NULL);

  74.         NtStatus=ZwCreateNamedPipeFile(&hPipe,
  75.                 FILE_ANY_ACCESS,
  76.                 &ObjAttr,
  77.                 &IoStatus,
  78.                 FILE_SHARE_READ | FILE_SHARE_WRITE,
  79.                 FILE_CREATE,
  80.                 PIPE_ACCESS_DUPLEX,
  81.                 FILE_PIPE_MESSAGE_TYPE,
  82.                 FILE_PIPE_MESSAGE_MODE,
  83.                 FILE_PIPE_QUEUE_OPERATION,//blocking mode
  84.                 ulMaxClientCount,
  85.                 ulMaxInBufSize,
  86.                 ulMaxOutBufSize,
  87.                 &liTimeOut);

  88.         if (NT_SUCCESS(NtStatus))
  89.         {
  90.                 *phPipe=hPipe;
  91.         }else
  92.         {
  93.                 *phPipe=NULL;
  94.         }

  95.         return NtStatus;
  96. }

  97. NTSTATUS __stdcall ZwConnectNamedPipe(HANDLE hPipe)
  98. {
  99.         NTSTATUS NtStatus=STATUS_SUCCESS;

  100.         IO_STATUS_BLOCK IoStatus={0};

  101.         NtStatus=ZwFsControlFile(hPipe,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_LISTEN,NULL,0,NULL,0);

  102.         return NtStatus;
  103. }

  104. NTSTATUS __stdcall ZwDisconnectNamedPipe(HANDLE hPipe)
  105. {
  106.         NTSTATUS NtStatus=STATUS_SUCCESS;

  107.         IO_STATUS_BLOCK IoStatus={0};

  108.         NtStatus=ZwFsControlFile(hPipe,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_DISCONNECT,NULL,0,NULL,0);

  109.         return NtStatus;
  110. }


  111. NTSTATUS __stdcall ZwSetNamedPipeState(HANDLE hPipe,ULONG ulMode)
  112. {
  113.         NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;

  114.         ULONG    aBuf[2]={0};

  115.         IO_STATUS_BLOCK IoStatus={0};

  116.         do
  117.         {
  118.                 if ((0xFFFFFFFC & ulMode)==0)
  119.                 {
  120.                         break;
  121.                 }

  122.                 aBuf[0]=((ulMode>>1) & 1);

  123.                 aBuf[1]=(ulMode & 1);

  124.                 NtStatus=ZwSetInformationFile(hPipe, &IoStatus, aBuf, sizeof(aBuf), FilePipeInformation);
  125.         } while (FALSE);

  126.         return NtStatus;
  127. }


  128. NTSTATUS __stdcall ZwWaitNamedPipe(PUNICODE_STRING puniPipeName,LARGE_INTEGER liTimeOut)
  129. {
  130.         NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;

  131.         IO_STATUS_BLOCK IoStatus={0};

  132.         HANDLE hParent=NULL;

  133.         OBJECT_ATTRIBUTES Oa={0};

  134.         WCHAR  aTmpBuf[512]={0};

  135.         PWAIT_PIPE_PARAM pWaitPipeParam=(PWAIT_PIPE_PARAM)aTmpBuf;

  136.         INT   iShortNameOffset=wcslen(L"\\\\.\\pipe\\")*sizeof(WCHAR);

  137.         UNICODE_STRING uniPipeParentName={0};

  138.         do
  139.         {
  140.                 if (!puniPipeName || puniPipeName->Length<iShortNameOffset)
  141.                 {
  142.                         NtStatus=STATUS_OBJECT_NAME_NOT_FOUND;

  143.                         break;
  144.                 }
  145.                 RtlInitUnicodeString(&uniPipeParentName,L"\\DosDevices\\pipe\\");

  146.                 InitializeObjectAttributes(&Oa,&uniPipeParentName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);

  147.                 NtStatus=ZwOpenFile(&hParent,0x100080,&Oa,&IoStatus,FILE_SHARE_WRITE | FILE_SHARE_READ,32);

  148.                 if (!NT_SUCCESS(NtStatus))
  149.                 {
  150.                         break;
  151.                 }

  152.                 pWaitPipeParam->liTimeOutvalue=liTimeOut.QuadPart;

  153.                 pWaitPipeParam->bUsTimeoutValue=TRUE;

  154.                 *((USHORT*)(&pWaitPipeParam->ulPipeNameLen))=puniPipeName->Length-iShortNameOffset;

  155.                 RtlCopyMemory((PVOID)((ULONG_PTR)pWaitPipeParam+sizeof(WAIT_PIPE_PARAM)),&puniPipeName->Buffer[iShortNameOffset/sizeof(WCHAR)],pWaitPipeParam->ulPipeNameLen);

  156.                 NtStatus=ZwFsControlFile(hParent,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_WAIT,&pWaitPipeParam,14+pWaitPipeParam->ulPipeNameLen,NULL,0);

  157.         } while (FALSE);

  158.         if (hParent)
  159.         {
  160.                 ZwClose(hParent);
  161.         }

  162.         return NtStatus;
  163. }
复制代码

Rank: 2

发表于 2011-11-8 13:24:45 |显示全部楼层
再补充几个结构体和宏定义
  1. #pragma pack(push,1)

  2. typedef struct _WAIT_PIPE_PARAM
  3. {
  4.         __int64 liTimeOutvalue;
  5.         ULONG   ulPipeNameLen;
  6.         USHORT  bUsTimeoutValue;
  7. }WAIT_PIPE_PARAM,*PWAIT_PIPE_PARAM;

  8. typedef struct _NAMED_PIPE_CREATE_PARAMETERS
  9. {
  10.         ULONG32      NamedPipeType;
  11.         ULONG32      ReadMode;
  12.         ULONG32      CompletionMode;
  13.         ULONG32      MaximumInstances;
  14.         ULONG32      InboundQuota;
  15.         ULONG32      OutboundQuota;
  16.         LARGE_INTEGER DefaultTimeout;
  17.         UINT8        TimeoutSpecified;
  18.         UINT8        _PADDING0_[0x7];
  19. }NAMED_PIPE_CREATE_PARAMETERS, *PNAMED_PIPE_CREATE_PARAMETERS;

  20. #pragma pack(pop)

  21. #define WAIT_FORVER (0x8000000000000000)

  22. #define PIPE_ACCESS_DUPLEX (3)
复制代码

Rank: 5Rank: 5

发表于 2011-11-8 13:59:49 |显示全部楼层
擦~

Rank: 2

发表于 2011-11-8 17:34:52 |显示全部楼层
pipe实现底层其实也是file system模型,所以。。。

Rank: 1

发表于 2011-11-8 19:00:17 |显示全部楼层

Rank: 2

发表于 2011-11-8 19:51:02 |显示全部楼层
wrk.

Rank: 1

发表于 2011-11-9 16:32:10 |显示全部楼层
太棒了.正想看看

Rank: 1

发表于 2011-11-9 17:42:18 |显示全部楼层
友情路过帮顶

Rank: 2

发表于 2011-11-9 17:48:29 |显示全部楼层
sad_llll 发表于 2011-11-9 17:42
友情路过帮顶

貌似我们很熟啊。。。。

Rank: 1

发表于 2011-11-11 03:55:03 |显示全部楼层
ddddddddddd

Rank: 1

发表于 2011-11-11 17:01:32 |显示全部楼层
哇哈哈

Rank: 3Rank: 3

发表于 2011-11-11 19:19:42 |显示全部楼层
好强
来学习下哈。。。

Rank: 1

发表于 2011-11-12 09:14:42 |显示全部楼层
回个帖子顶一下,顺便看看偶有几分了

Rank: 1

发表于 2011-11-12 15:09:07 |显示全部楼层
学习了,顶一下!!!

Rank: 1

发表于 2011-12-26 12:41:34 |显示全部楼层
LZ,很厉害啊,我现在正想做这个,能否留个联系方式请教一下?

kernel pipe

Rank: 1

发表于 2011-12-26 16:26:01 |显示全部楼层
请教一下,创建管道返回0xC000000D,查了一下说是:STATUS_INVALID_PARAMETER

参数不对?请教LZ了

Rank: 1

发表于 2011-12-26 21:22:04 |显示全部楼层
这个,其实也不需要非得在内核中创建,比较简单点的办法可以这样:

用户层创建Named pipe,然后传给驱动,驱动ObReferenceObjectByHandle,ObOpenObjectByPointer,然后按照应用层的操作方法,操作就好了(即使有些函数在应用层没有,比如Server端的某些函数,这个自己按照我上面代码的实现处理就好了,客户端的,这个完全就是File相关的读写函数,在内核使用不存在任何问题)

Rank: 1

发表于 2011-12-26 21:24:47 |显示全部楼层
如果不考虑兼容性问题
直接分析ntdll中的NtCreateNamedPipe,找出相应函数的index,直接在内核中以index为基础调用ssdt中的函数指针就好了,因为严格来说,named pipe并不是说在内核中没有实现。。。。仅仅是没有导出而已

Rank: 1

发表于 2011-12-27 09:56:13 |显示全部楼层
其实,我是想通过应用层跟踪,来看看内核的函数调用,参数传递什么的

我是打算做一个虚拟串口转pipe,用来连windbg进行调试的,

如果有什么好的建议,能否加下我QQ,我发消息给你

Rank: 1

发表于 2011-12-30 01:26:40 |显示全部楼层
驱动和应用程序通信的话,我感觉FltMgr实现的那套框架是非常不错的。
您需要登录后才可以回帖 登录 | 立即加入

Archiver|手机版|第8个男人 - 论坛为只读模式,仅供查阅

GMT+8, 2019-7-17 07:29 , Processed in 0.037325 second(s), 8 queries .

Design by pvo.cn

© 2011 Pvo Inc.

回顶部