从利用匿名管道实现可交互式远程超级终端cmd.exe说起
来源:互联网 发布:淘宝全年销售额 编辑:程序博客网 时间:2024/06/06 18:58
为了实现一个可交互式的远程cmd,我选用了匿名管道来实现cmd的重定向,通过把cmd.exe进程的输入输出重定位到管道的输入输出,可以实现主进程与cmd.exe的交互。具体实现重定位的技术是利用与创建进程的函数CreateProcess的一个参数STARTUPINFO来进行设置,这个参数可以用于设置进程的输入输出,默认的情况是系统的标准输入输出,修改后可以重定位到管道的输入输出。
因为匿名管道是单向的,为了实现主进程与子进程之间的交互,创建两个管道。
if (!CreatePipe(&hReadStdin, &hWriteStdin, &sa, 0))
{
return -1;
}
if (!CreatePipe(&hReadStdout, &hWriteStdout, &sa, 0))
{
return -1;
}
创建两个管道后再进行重定位操作:
// 关联cmd和管道
si.hStdError = hWriteStdin;
si.hStdOutput = hWriteStdin;
si.hStdInput = hReadStdout;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
可以看到通过重定位,把cmd.exe进程的输出以及错误的输出都定位到了Pipe1的写句柄hWriteStdin上,那么只要是cmd的输出都会直接写入到Pipe1中;而cmd的输入就定位到了Pipe2上的hReadStdout句柄上,这样,管道Pipe2中的数据会被cmd进程当做输入。这样的话,我们对管道的另一端进行写入和读取的话,就相当于直接对cmd进程进行传递命令和获取命令反馈的消息了。那么这样就实现了远程交互的cmd。
那么现在,重点就来了,有很多细节需要进行处理了。
我们如何知道管道中有数据可以进行读取?
在使用ReadFile读取管道数据的时候会出现阻塞的情况,这就是ReadFile这个函数的缺陷,在管道中没有数据的话那么它也一直处于阻塞状态并不会返回。要解决这个问题,网上很多前辈都说在读取之前关闭管道的写句柄,那么在ReadFile的时候就不会因为管道中没有数据而不返回,因为关闭写句柄后就相当于告诉系统管道在读取完最后的数据后就会关闭,那么Readfile后就不会阻塞了。但是这样的话就实现不了一个交互的cmd,因为没有保存写句柄,这样的话下次就不知往哪里写了。
找到的一种解决方法就是通过使用函数PeekNamedPipe来进行判断管道中的数据情况,这个函数可以返回管道中数据的字节数,进行的操作是拷贝管道中的数据,而不是Readfile这个函数的拷贝后清除的操作。
通过返回的数目,判断是否为0,为0就退出此次的接收。
// 从管道中取出数据
while (true)
{
// 获取管道中数据的大小
PeekNamedPipe(hReadStdin, szTmp, 1024, &dwRead, NULL, NULL);
if (0 == dwRead)
{
break;
}
ReadFile(hReadStdin, szTmp, 1024, &dwRead, NULL);
memcpy( szRecvPipeBuffer + dwSum , szTmp , dwRead ) ;
dwSum += dwRead ;
memset( szTmp , 0 , sizeof( szTmp ) ) ;
}
在实际的过程中又出现了一个问题,通过调试发现,在往管道中写入数据后,从管道中并没有取出数据,但是调试的结果是对的,运行确错误,我我就发现往管道写数据后使用Sleep(500)就就可以解决问题,这是因为,给cmd发送命令后假如不等待的话,cmd进程也没有准备好数据,而我们就直接从管道中去取数据,这样肯定是去取不出数据的。现在的疑问使用Sleep函数感觉有些不当。是不是还可以用其他的方式来解决呢?
还需要注意的问题就是:
(1)发送的命令需要加行‘"\r\n"这个,毕竟在cmd输入命令后是需要按enter的。
(2)最后cmd结束的时候如何CloseHandle这几个句柄呢?
最后列出帮我解决问题的几个重要链接:
http://www.cnblogs.com/boyxiao/archive/2011/01/02/1924188.html
http://www.myexception.cn/vc-mfc/850686.html
http://www.cnblogs.com/thankgoodness/articles/1762596.html
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365779%28v=vs.85%29.aspx
- 从利用匿名管道实现可交互式远程超级终端cmd.exe说起
- 利用匿名管道实现远程CMD
- 利用匿名管道实现远程CMD
- 利用匿名管道实现远程CMD(转)
- 利用匿名管道实现远程CMD(转)
- 利用匿名管道实现远程调用CMD
- 利用匿名管道实现远程CMD - ToBeroOTer的专栏 - CSDNBlog
- 利用匿名管道实现远程CMD---我的解读
- 利用匿名管道实现CMD回显
- 【匿名管道】重定向cmd.exe
- 匿名管道实现基于Socket的简单cmd后门
- 利用pscp实现从putty远程终端复制文件到本地windows操作系统
- Pipe,利用匿名管道实现进程间通信
- 利用匿名管道技术实现本地进程通信
- vc 利用无名管道 控制台程序实现cmd功能
- 匿名管道 c++实现
- 由最简单的一个例子说起,匿名用户可读可写的实现(LINUX)配置
- 远程登入开发板的几种方法(ssh,putty.exe,telnet,超级终端)
- 我所关注的一些博客
- Machine Learning-01_k近邻算法
- UILable转为UIImage的方法
- Openstack存储总结之:详解如何使用NFS作为Cinder的后端存储
- 移位运算符
- 从利用匿名管道实现可交互式远程超级终端cmd.exe说起
- 黑马程序员--OC--OC简介
- C++摘要——什么时候使用std::cout,什么时候用std::cerr
- DestroyWindow函数解析
- 关于协方差矩阵的概念及意义
- Linux学习笔记(六)terminal与vim配色
- Linux下一些很有用的Shell命令
- Android 源码解析之Launcher3之帮助提示的实现方案
- Java易错知识点(2) - 在读取Cookie时除了Key,Value是得不到其他信息的