1.实现一代码
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<string.h>
std::string ExeCmd(std::string pszCmd)
{
// 创建匿名管道
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
HANDLE hRead, hWrite;
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
return " \n";
}
// 设置命令行进程启动信息(以隐藏方式启动命令并定位其输出到hWrite
STARTUPINFO si = { sizeof(STARTUPINFO) };
GetStartupInfo(&si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdError = hWrite;
si.hStdOutput = hWrite;
// 启动命令行
PROCESS_INFORMATION pi;
if (!CreateProcess(NULL, (LPSTR)pszCmd.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
return "Cannot create process.\n";
}
// 立即关闭hWrite
CloseHandle(hWrite);
// 读取命令行返回值
std::string strRetTmp;
char buff[1024] = { 0 };
DWORD dwRead = 0;
strRetTmp.clear();
while (ReadFile(hRead, buff, 1024, &dwRead, NULL)){
strRetTmp.append(buff);
memset(buff, 0, sizeof(buff));
}
CloseHandle(hRead);
return strRetTmp;
}
int main(int argc, char *argv[])
{
while (1)
{
char cmd_Str[1024];
memset(cmd_Str, 0, sizeof(cmd_Str));
printf("shell---->");
gets_s(cmd_Str, sizeof(cmd_Str) - 1);
std::string retStr = ExeCmd(cmd_Str);
printf("%s\n", retStr.c_str());
}
return 0;
}
2.实现二代码
//RemoteShell.h
#pragma once
#include <iostream>
#include <windows.h>
#include<thread>
using namespace std;
class CPipe
{
private:
HANDLE hpiperead = NULL;
HANDLE hpipewrite = NULL;
HANDLE hpiperead2 = NULL;
HANDLE hpipewrite2 = NULL;
HANDLE hProHandle = NULL;
HANDLE hThrLoop = NULL;
HANDLE hThrisLoop = NULL;
SECURITY_ATTRIBUTES ai;
PROCESS_INFORMATION pi;
STARTUPINFOA si;
BOOL pipe = false;
INT status = 1; // 0 = 异常 1 = 正常 -1 = 错误 、
string errorString;
public:
void loop();
void isloop();
const BOOL isPipeOff() const;
const INT getStatus() const;
const string & getError() const;
const BOOL sendCommand(const char *);
void setPipeOn(const BOOL);
void setStatus(const INT, const char*);
void setStatus(const INT);
CPipe(char * str);
~CPipe();
};
//RemoteShell.cpp
#include"RemoteShell.h"
DWORD __stdcall ThrPipeThreadRead(void *www)
{
CPipe * pipe = (CPipe *)www;
pipe->loop();
return 0;
//创建内核对象使用完之后一定记得关闭,有可能会产生内存泄露
}
DWORD __stdcall WaitPipe(void *www)
{
CPipe * pipe = (CPipe *)www;
pipe->isloop();
return 0;
}
CPipe::CPipe(char * com)
{
ai.nLength = sizeof(SECURITY_ATTRIBUTES);
ai.bInheritHandle = true;
ai.lpSecurityDescriptor = NULL;
if (!CreatePipe(&hpiperead, &hpipewrite, &ai, 0)) //创建读入管道
{
this->setStatus(-1, "[0x01]Read 流创建失效");
return;
}
if (!CreatePipe(&hpiperead2, &hpipewrite2, &ai, 0)) //创建读入管道
{
this->setStatus(-1, "[0x02]Write 流创建失效");
return;
}
GetStartupInfoA(&si); //获取当前进程的STARTUPINFO
si.cb = sizeof(STARTUPINFO);
si.hStdError = hpipewrite;
si.hStdOutput = hpipewrite;
si.hStdInput = hpiperead2;
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!(CreateProcessA(NULL, com, NULL, NULL, true, NULL, NULL, NULL, &si, &pi))) //创建隐藏的CMD进程
{
this->setStatus(-1, "[0x03] CreateProcess函数执行出错");
return;
}
DWORD dwThread = FALSE;
hThrLoop = CreateThread(NULL, 0, ThrPipeThreadRead, this, 0, &dwThread);//chuangjian
if (hThrLoop == false) {
this->setStatus(-1, "[0x11] 线程创建失败 CreateThread LOOP 失败");
return;
}
hThrLoop = CreateThread(NULL, 0, WaitPipe, this, 0, &dwThread);//chuangjian
if (hThrLoop == false) {
this->setStatus(-1, "[0x12] 线程创建失败 CreateThread ISLOOP失败");
return;
}
}
CPipe::~CPipe()
{
//创建内核对象使用完之后一定记得关闭,有可能会产生内存泄露
this->setPipeOn(false);
this->setStatus(-1);
CloseHandle(hThrisLoop);
CloseHandle(hThrLoop);
CloseHandle(hpipewrite);
CloseHandle(hpiperead);
CloseHandle(hpiperead2);
CloseHandle(hpipewrite2);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
const INT CPipe::getStatus() const
{
return this->status;
}
const string & CPipe::getError() const
{
return this->errorString;
}
const BOOL CPipe::isPipeOff() const
{
return pipe;
}
void CPipe::setPipeOn(const BOOL bools)
{
this->pipe = bools;
}
void CPipe::setStatus(const INT status, const char * info)
{
this->errorString = info; //你说会不会有更好的赋值方法?
this->status = status;
}
void CPipe::setStatus(const INT status = 1)
{
this->status = status;
}
const BOOL CPipe::sendCommand(const char * com) //执行命令
{
DWORD dwWrite = 0;
char www[1024];
memset(www, 0, sizeof(www));
strcpy_s(www, com);
strcat_s(www, "\r\n");
return WriteFile(hpipewrite2, www, strlen(www), &dwWrite, NULL);
//0x001C7796 处有未经处理的异常(在 ConsoleApplication2.exe 中): 0xC0000005: 读取位置 0x0000000C 时发生访问冲突。
}
void CPipe::loop() {
char outbuff[4096]; //输出缓冲
DWORD byteread;
this->setPipeOn(true);
while (true)
{
memset(outbuff, '\0', 4096);
if (ReadFile(this->hpiperead, outbuff, 4095, &byteread, NULL) == NULL)
{
this->setPipeOn(false);
break;
}
printf("%s", outbuff);
memset(outbuff, '\0', 4096);
}
this->setPipeOn(false);
std::cout << "Pipe Stoped!" << endl;
}
void CPipe::isloop()
{
DWORD dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
while (dwRet == WAIT_TIMEOUT)
{
dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
}
if (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED)
{
this->setPipeOn(false);
std::cout << "[END] Pipe Stoped!" << endl;
}
}
//main.cpp
#include"RemoteShell.h"
using namespace std;
void read();
void Loop();
CPipe * pipe;
int Luncher()
{
thread t1(read);
thread t2(Loop);
pipe = new CPipe((char *)"cmd.exe");
t1.join();
t2.join();
return 0;
}
void read() {
while (true) {
char str[200];
memset(str, 0, sizeof(str));
gets_s(str);
pipe->sendCommand(str);
}
}
void Loop() {
while (true)
{
Sleep(1000);
if (pipe->getStatus() == -11)
{
cout << " ERROR " << endl;
return;
}
}
}
int main(int argc, char *argv[])
{
Luncher();
return 0;
}