一個遠程系統控制檯的小工具

 

    因爲工作需要很多的遠程管理,一些現有的工具已經不能滿足實際要求。所以就 有了製作一個小型遠程控制檯的想法。

   其實,它的工作原理很簡單。主要有兩部分組成,一個是對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 [email protected]
*/



#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小時。(開源真好:))

問題:沒有過濾掉輸出重複的命令

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章