一个远程系统控制台的小工具

 

    因为工作需要很多的远程管理,一些现有的工具已经不能满足实际要求。所以就 有了制作一个小型远程控制台的想法。

   其实,它的工作原理很简单。主要有两部分组成,一个是对Cmd.exe 的标准输入和输出的重定向,另外有一个TCP连接来把本机的信息发送给远程的主机。

   以为手上有两个能实现上述功能的开源代码,所以我的工作就是把它们揉在一起。但要求是Socket和ReStdInOut必须分离,Socket要不能使用MFC(为了方便把逻辑移植到Linux或者和.Net连接),服务段程序必须是控制台(为了把它最终变成一个NT服务)。

    Socket类是一个在网上找到的一轻量级WinSocket封装,因为觉得它写的比我原来自己的封装要好,而且最终要的是它已经尽可能使用的是标准C++库(用的是Std::String,不是MFC::CString),给以后的移植方便了不少。

  参考 C++ Socket Class for Windows

  该类使用非常的方便

A simple Client

The following simple client connects to www.google.ch and get its front-website.
#include  " Socket.h "

#include 
< iostream >

using   namespace  std;

int  main()  {

  
try {
    SocketClient s(
"www.google.com"80);

    s.SendLine(
"GET / HTTP/1.0");
    s.SendLine(
"Host: www.google.com");
    s.SendLine(
"");

    
while (1{
      
string l = s.ReceiveLine();
      
if (l.empty()) break;
      cout 
<< l;
      cout.flush();
    }


  }
 
  
catch (const char* s) {
    cerr 
<< s << endl;
  }
 
  
catch (String s) {
    cerr 
<< s << endl;
  }
 
  
catch (...) {
    cerr 
<< "unhandled exception ";
  }


  
return 0;
}

A simple echo Server

The following simple Server opens a port on 2000 and waits for incoming connections. Each connection is answered with the same line as was written (echoed).

 

/* 
   EchoServer.cpp

   Copyright (C) 2002-2004 René Nyffenegger

   This source code is provided 'as-is', without any express or implied
   warranty. In no event will the author be held liable for any damages
   arising from the use of this software.

   Permission is granted to anyone to use this software for any purpose,
   including commercial applications, and to alter it and redistribute it
   freely, subject to the following restrictions:

   1. The origin of this source code must not be misrepresented; you must not
      claim that you wrote the original source code. If you use this source code
      in a product, an acknowledgment in the product documentation would be
      appreciated but is not required.

   2. Altered source versions must be plainly marked as such, and must not be
      misrepresented as being the original source code.

   3. This notice may not be removed or altered from any source distribution.

   René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/



#include 
" Socket.h "
#include 
< process.h >
#include 
< string >

unsigned __stdcall Answer(
void *  a)  {
  Socket
* s = (Socket*) a;

  
while (1{
    std::
string r = s->ReceiveLine();
    
if (r.empty()) break;
    s
->SendLine(r);
  }


  delete s;

  
return 0;
}


int  main( int  argc,  char *  argv[])  {
  SocketServer 
in(2000,5);

  
while (1{
    Socket
* s=in.Accept();

    unsigned ret;
    _beginthreadex(
0,0,Answer,(void*) s,0,&ret);
  }

 
  
return 0;
}

标准输入输入的重定向 用了一个CodeProjet 的项目

QuickWin - Turn a console application into a Windows program

项目里的CRedirect类个人感觉非常好用,只需从他继承一个自己的类,并且重写4个虚函数

virtual   void  OnChildStarted(LPCSTR lpszCmdLine);
virtual   void  OnChildStdOutWrite(LPCSTR lpszOutput);
virtual   void  OnChildStdErrWrite(LPCSTR lpszOutput);
virtual   void  OnChildTerminate();

就轻松实现了标准输入输出的重定向。

其实核心技术都不是我自己写的,但是得益于开源的力量,在了解了他们的源码有我觉得完全可能把它们结合成一个新的应用。

我的方法是

 1、Server初始化一个TCP Listener,等待客户端接入。

2、客户端接入服务段。

3、服务段连接客户端后,开启一个cmd.exe的进程,并重导向它的标准输入、输出和错误流。(这里可以改进一下,使用API:CreateProcessWithLogonW或API:CreateProcessWithTokenW,是cmd.exe跑在制定的用户下,因为如果当前进程是NT服务的话,默认在System帐户下,我问需要找到当前的登陆用户,用它的进程跑Cmd.exe

4、 用ReDir类的WriteStdIn和StdOut事件,反复输入和到处从Socket.ReandLine和Socket.SendLine的内容,以实现远程控制台的目的.

5、当客户端用Exit结束cmd.exe时,服务段关闭连接自动退出。[你也改为继续等待下个连接]

界面:(因为用的是Visual Studio 2005制作,运行需要MFC8的RunTime DLL)

先启动服务程序:

接着使用 Telnet localhost 2000 连接服务,会得到一下状态

你就可以向使用自己的本地控制台一样操作那台机器了。

连续两次exit指令 关闭连接、退出服务。

下载源码

注意:我故意没有隐藏打开的cmd.exe进程,可以开源码里OpenChildProcess了第二个参数为0就可隐藏了。

整个制作时间:3小时。(开源真好:))

问题:没有过滤掉输出重复的命令

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值