windows进程间通信系列 第三篇 匿名管道与命名管道

剪贴板的话只能实现本机上进程之间的通信,而邮槽的话虽然是可以实现跨网络之间的进程的通信,但麻烦的是邮槽的服务端只能接收数据,邮槽的客户端只能发送数据,太悲剧了,而对于匿名管道的话,其也只能实现本机上进程之间的通信,你要是能够实现本机进程间的通信也就算了,关键是它还只用来实现本地的父子进程之间的通信,也太局限了吧?而这里介绍的这个命名管道的话,就和他们有些不同了,在功能上也就显得强大很多了,至少其可以实现跨网络之间的进程的通信,同时其客户端既可以接收数据也可以发送数据,服务端也是既可以接收数据,又可以发送数据的。

管道(pipe)是用于进程间通信的共享内存区域。创建管道的进程称为管道服务器,而连接到这个管道的进程称为管道客户端。一个进程向管道写入信息,而另外一个进程从管道读取信息。

管道是一种进程间,确切的说应该是线程间的通信方法。顾名思义。管道是一个有两端的对象。进程可以从这个对象的一个端口写数据,从另一个端口读数据。管道其实也是一种共享内存,只是更加规范。

管道有两种类型:匿名管道和命名管道。匿名管道是单向的,也就是说数据只能从写句柄写入,从读句柄读出。

异步管道是基于字符和半双工的(即单向),一般用于程序输入输出的重定向;命名管道则强大地多,它们是面向消息和全双工的,同时还允许网络通信,用于创建客户端/服务器系统。

(1)异步管道

前面已经说到过,异步管道的缺陷:只能够在父子进程之间通信,而且是半双工的,server与client不能同时发送数据。

创建匿名管道的函数式CreatePipe,创建一个匿名管道,并从中得到读写管道的句柄。

函数的原型为:

BOOL WINAPI CreatePipe( _Out_PHANDLE hReadPipe, _Out_PHANDLE hWritePipe, _In_opt_LPSECURITY_ATTRIBUTES lpPipeAttributes, _In_DWORD nSize);
参数说明:

  • hReadPipe[out]
    返回一个可用于读管道数据的文件句柄
  • hWritePipe[out]
    返回一个可用于写管道数据的文件句柄
  • lpPipeAttributes[in, optional]
    传入一个 SECURITY_ATTRIBUTES结构的指针,该结构用于决定该函数返回的句柄是否可被子进程继承。如果传NULL,则返回的句柄是不可继承的。
    该结构的 lpSecurityDescriptor成员用于设定管道的安全属性,如果传NULL,那么该管道将获得一个默认的安全属性,该属性与创建该管道的用户账户权限ACLs的安全令牌(token)相同。
  • nSize[in]
    管道的缓冲区大小。但是这仅仅只是一个理想值,系统根据这个值创建大小相近的缓冲区。如果传入0 ,那么系统将使用一个默认的缓冲区大小。

说明:匿名管道不允许异步操作,所以如在一个管道中写入数据,且缓冲区已满,那么除非另一个进程从管道中读出数据,从而腾出了缓冲区的空间,否则写入函数不会返回


关于匿名管道的一个应用:重定向。

这个例子是这样的:后门程序需要调用目标机器上的CDM,后门程序发送命令给cmd.exe程序,由cmd.exe程序把结果返回给我们的后门程序。这里就有两个问题了:

(1)cmd程序的默认输出在cmd窗口,那么如何把输出传给后门程序呢?

(2)后门程序的输入如何传给cmd程序呢?

解决方法:后门程序创建cmd进程,即cmd程序是后门程序的子进程,这样的话我们可以方便把需要的命令直接传给子进程,让其执行即可,这样第二个问题就解决了。cmd执行后的结果如何传给其父进程(后门程序)?这里我们需要使用一个重定向来处理,把cmd程序的输出重定位到后门程序。

又是子进程与父进程的关系,又是重定向,那么我们顺其自然使用管道了,这里使用匿名管道。

从图中可以看到,创建了两个管道,因为匿名管道是单向的,所以必须使用两个管道,要不然没法通信。

cmd程序把执行结果写入到管道1中,并从管道2中读出后门发过来的命令;后门程序从管道1中读出cmd程序的执行结果,把命令写入到管道2中。

每一个管道都有一个读句柄和一个写句柄,就是通过这两个句柄来进行数据读写从而来实现通信的。


创建子进程我们知道,可以使用CreateProcess函数,重定位我们需要使用进程创建过程中的一个参数STARTUPINFO,这个参数就是实现重定向的关键。

其原型为:

typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值