VC 模拟CMD 匿名管道
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h> int Call(char Cmd[])
{
SECURITY_ATTRIBUTES sa;
HANDLE Hread,Hwrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&Hread,&Hwrite,&sa,0))
{
printf("Create Pipe in error\r\n");
return 0;
} STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = Hwrite;
si.hStdOutput = Hwrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
memset(&pi,0,sizeof(PROCESS_INFORMATION));
char cmdline[1024 ] = "cmd /c";
strcat(cmdline,Cmd);
if (!CreateProcessA(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
printf("Create process error\r\n");
return 0;
} CloseHandle(Hwrite); char buff[1024] = {0};
//char cres[MAX_PATH] = {0};
DWORD bytesread;
while (true)
{
if (ReadFile(Hread,buff,1024,&bytesread,NULL) == NULL)
{
break;
} int ilen = strlen(buff);
for (int i =0;i<ilen;i++)
{
if (buff[i] == '\n' || buff[i] == '\r')
{
buff[i] = '\0';
}
}
printf(buff);
}
CloseHandle(Hread);
//sprintf() return 0;
} int _tmain(int argc, _TCHAR* argv[])
{
char* Cmd = argv[1];
Call(Cmd);
return 0;
} 使用管道CREATEPIPE,来进行进程间的相互通信,然后在进行数据的读取。 什么是管道,管道就是一种通信机制,也就是内存共享,一个进程向管道写入数据后,由另外一个管道读出。 匿名管道是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。
匿名管道由CreatePipe()函数创建,该函数在创建匿名管道的同时返回两个句柄:管道读句柄和管道写句
柄。CreatePipe()的函数原型为:
BOOL CreatePipe(
PHANDLE hReadPipe, // 指向读句柄的指针
PHANDLE hWritePipe, &nb sp; // 指向写句柄的指针
LPSECURITY_ATTRIBUTES lpPipeAttributes, // 指向安全属性的指针
DWORD nSize // 管道大小
);
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
在调用CreatePipe()函数时,如果管道服务器将lpPipeAttributes 指向的SECURITY_ATTRIBUTES数据结构的数据成员bInheritHandle设置为TRUE,那么CreatePipe()创建的管道读、写句柄将会被继承。
在用WriteFile()函数向管道写入数据时,只有在向管道写完指定字节的数据后或是在有错误发生时函数才会返回。如管道缓冲已满而数据还没有写完,WriteFile()将要等到另一进程对管道中数据读取以释放出更多可用空间后才能够返回。管道服务器在调用CreatePipe()创建管道时以参数nSize对管道的缓冲大小作了设定。
匿名管道并不支持异步读、写操作,这也就意味着不能在匿名管道中使用ReadFileEx()和WriteFileEx(),而且ReadFile()和WriteFile()中的lpOverLapped参数也将被忽略。匿名管道将在读、写句柄都被关闭后退出,也可以在进程中调用CloseHandle()函数来关闭此句柄。
程序具体实现过程:
(1) 初始化安全属性的指针 //创建匿名管道前期,就得初始化安全属性的指针。
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = TRUE;
(2) 创建匿名管道 //开始创建匿名管道
HANDLE hReadPipe1,hWritePipe1;
CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0);
(3) 创建cmd进程
BOOL CreateProcess(
LPCTSTR lpApplicationName, //可执行模块的字符串
LPTSTR lpCommandLine, //执行的命令行字符串
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles, //新进程是否从调用进程处继承了句柄
DWORD dwCreationFlags, //标志
LPVOID lpEnvironment, //新进程的环境块
LPCTSTR lpCurrentDirectory, //子进程的工作路径
LPSTARTUPINFO lpStartupInfo, //决定新进程的主窗体如何显示
LPPROCESS_INFORMATION lpProcessInformation //接收新进程的识别信息
);
在创建进程前,先初始化两个结构体:LPSTARTUPINFO 和LPPROCESS_INFORMATION
STARTUPINFO结构用于指定新进程的主窗口特性,应用程序必须将cb初始化为sizeof(STARTUPINFO)
STARTF_USESHOWWINDOW使用wShowWindow成员:wShowWindow用于设定如果子应用程序初次调用的ShowWindows将SW_SHOWDEFAULT作为nCmdShow参数传递时,该应用程序的第一个重叠窗口应该如何出现。
STARTF_USESTDHANDLES使用hstdInput、hstdOutput和hstdError成员:HANDLE hStdInput用于设定供控制台输入和输出用的缓存的句柄。按照默认设置,hstdInput 用于标识键盘缓存,hstdOutput和hstdError用于标识控制台窗口的缓存。
STARTUPINFO si;
memset(&si,0,sizeof(si));
GetStartupInfo(&si); //该函数返回进程在启动时被指定的STARTUPINFO 结构
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdOutput = si.hStdError = hWritePipe1;
PROCESS_INFORMATION pInfo;
memset(&pInfo,0,sizeof(PROCESS_INFORMATION));
创建进程
char szCmd[MAXLENGTH] = "cmd.exe /c";
//接收远程传入的进程执行参数
int dwSize = ((RatProto*)szRecvCmd)->RatLen - sizeof(RatProto);
strncat(szCmd,szRecvCmd+sizeof(RatProto),dwSize);
CreateProcessA(NULL,szCmd,NULL,NULL,1,0,NULL,NULL,&si,&pInfo);
(3) 通过管道通信,得到进程执行结果
memset(szCmd,0,MAXLENGTH);
int dwRead;
//判断管道内是否有传入数据
int nRet = PeekNamedPipe(hReadPipe1,szCmd,MAXLENGTH,(LPDWORD)&dwRead,NULL,NULL);
for (int i=0;i<5&&dwRead==0;i++)
{
Sleep(100);
nRet = PeekNamedPipe(hReadPipe1,szCmd,MAXLENGTH,(LPDWORD)&dwRead,NULL,NULL);
}
if (dwRead)
{
nRet = ReadFile(hReadPipe1,szCmd,dwRead,(LPDWORD)&dwRead,0);
if (!nRet)
{
sprintf(szCmd,"%s","CMD COMMAND EXCUTE ERROR!");
}
}
(4) 将执行结果传给客户端
.......
VC 模拟CMD 匿名管道的更多相关文章
- 匿名管道读取CMD回显信息
之前用了很坑爹的做法去读取了cmd命令的回显信息,现在发现了用匿名管道的实现方法,由于楼主没有学过Windows核心编程,找了一个代码来凑数 存下来以后研究 #include <windows. ...
- 通过匿名管道获取CMD运行结果
#include <iostream> #include <string> #include <Windows.h> using namespace std; /* ...
- Windows下 C++ 实现匿名管道的读写操作
由于刚弄C++没多久,部分还不熟练,最近又由于开发需求要求实现与其他程序进行通信,瞬间就感觉想到了匿名通信.于是自己查阅了一下资料,实现了一个可读可写的匿名管道: 源代码大部分都有注释: Pipe.h ...
- 使用匿名管道在进程间通信 (System.IO.Pipes使用)(转)
原文地址:http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html 管道的用途是在同一台机器上的进程之间通信,也 ...
- C语言通过匿名管道实现反弹式CMDShell
#pragma comment(lib,"ws2_32.lib") #ifdef _MSC_VER #pragma comment( linker, "/subsyste ...
- Windows进程通信之一看就懂的匿名管道通信
目录 进程通信之一看就懂的匿名管道通信 一丶匿名管道 1.1何为匿名管道 1.2创建匿名管道需要注意的事项 1.3 创建匿名管道需要的步骤 1.4代码例子 1.5代码运行截图 进程通信之一看就懂的匿名 ...
- 进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道
管道 Linux环境进程间通信(一) https://www.ibm.com/developerworks/cn/linux/l-ipc/part1/index.html 管道及有名管道 郑彦兴200 ...
- Linux学习笔记(12)-进程间通信|匿名管道
Linux的进程间通信有几种方式,包括,管道,信号,信号灯,共享内存,消息队列和套接字等-- 现在一个个的开始学习! ----------------------------------------- ...
- Linux进程间通信(三):匿名管道 popen()、pclose()、pipe()、close()、dup()、dup2()
在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值.这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据. 一.什 ...
随机推荐
- Python2.6升级Python2.7
Python2.6升级2.7 由于Centos6系列自带的python版本为2.6.6,然而有很多应用需要依赖于python2.7来实现,所以有了这个升级的需求.升级原理很简单,无非就是下载.编译.安 ...
- Android UI开发第二十七篇——实现左右划出菜单
年前就想写左右滑动菜单,苦于没有时间,一直拖到现在,这篇代码实现参考了网上流行的SlidingMenu,使用的FrameLayout布局,不是扩展的HorizontalScrollView. 程序中自 ...
- 巨蟒python全栈开发django4:url反向解析图解&&模板渲染2
注意:前端有aaa变量,后端没有aaa变量,存在p标签,但是显示不出来 有p标签,我们可以指定默认值,在没有其他内容的时候 过滤器有60多种,有点多,用到的时候再记和查 结果: 显示是acd 看长度 ...
- 防sql注入之参数绑定 SQL Injection Attacks and Defense
http://php.net/manual/zh/pdo.prepared-statements.php 预处理语句与存储过程 很多更成熟的数据库都支持预处理语句的概念.什么是预处理语句?可以把它看作 ...
- 笔画宽度变化(C++和matlab算法)
最近一直在看工作方面的书籍,把论文的事情搁置了,之前承诺的贴代码的事一直拖.现在把代码整理发上来,只有核心部分的,都不是我写的,我是网上整理下载的,matlab代码的效果比较差. 全部文件网盘下载地址 ...
- 从1到N中1的个数
示例1,2...9,10,11中有四个1 int getNumber(int n) { int count = 0; int factor = 1; int low = 0; int cur = 0; ...
- 佳能相机操作 EDSDK 教程 C# 版本
http://blog.csdn.net/zajin/article/details/17021339 介绍 佳能EOS数码SDK是一个 可以用来远程控制其数码单反相机相当强大的SDK.不幸的是 ...
- Python操作SQLAlchemy
Mysql环境: MySQL 一.概述什么是数据库 ? 答:数据的仓库,如:在ATM的示例中我们创建了一个 db 目录,称其为数据库 什么是 MySQL.Oracle.SQLite.Access.MS ...
- 使用Axure生成网站结构图
使用Axure设计的各网站(产品)页面,生成网站(产品)结构图.这个对于了解网站整体结构很有帮助. 需要把它生成对应结构的网站结构图. 第一步:在“主页”上面新建一个和“主页”平级的页面,命名为“网站 ...
- linux 定时任务未执行php脚本
1,对于无法执行php文件,首先你应该考虑的问题是是否php代码有错误,你可以先检查一下你的php代码,或者可以在linux上面执行一下这个文件,看是否能够执行成功:如果成功了,就说明是crontab ...