本文以实例形式讲述了Delphi下木马的文件传输方法的实现过程,具体步骤如下:
服务器端代码:unit ServerFrm;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls,WinSock;type TfrmMain = class(TForm)Panel1: TPanel;Label1: TLabel;edtPort: TEdit;Panel2: TPanel;stabar: TStatusBar;SaveDialog: TSaveDialog;btnListen: TButton;btnReceive: TButton;btnStop: TButton;btnExit: TButton;procedure FormCreate(Sender: TObject);procedure btnExitClick(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure btnListenClick(Sender: TObject);procedure btnReceiveClick(Sender: TObject);procedure btnStopClick(Sender: TObject); private{ Private declarations } public{ Public declarations }StopTrans:Boolean; //是否停止传送开关InTrans:Boolean; //表示正在接收文件Server:TSocket; //定义服务器端的socket句柄//自定义过程接收文件procedure RecvFile(FileName:String); end;var frmMain: TfrmMain;const BlockLen=1024*4;implementation{$R *.dfm}procedure tfrmmain.RecvFile(FileName:String);var Ftrans:file of Byte; Recelen:Integer; Blockbuf:array[0..BlockLen-1] of Byte; RecvSocket:TSocket; ra:Sockaddr_in; ra_len:integer;begin ra_len:=sizeof(ra); Recvsocket:=accept(server,@ra,@ra_len); assignFile(Ftrans,filename); rewrite(ftrans); stoptrans:=false; intrans:=true; recelen:=recv(recvsocket,Blockbuf,BlockLen,0); while (recelen>0) and (not StopTrans) do beginBlockWrite(Ftrans,Blockbuf[0],BlockLen);application.ProcessMessages;recelen:=recv(recvsocket,Blockbuf,Blocklen,0);if stoptrans thenbegin CloseFile(Ftrans); CloseSocket(RecvSocket); InTrans:=False; MessageBox(Handle,"停止传输!","提示",MB_OK); EXIT;END; END; //关闭文件,接收的SOCKET CloseFile(Ftrans); Closesocket(recvsocket); InTrans:=False; if (Recelen=SOCKET_ERROR) thenmessagebox(handle,"传输异常终止!","提示",MB_OK) ELSEMESSAGEBOX(HANDLE,"客户端已经关闭连接1,文件可能已经传送完毕了!","提示",MB_OK);end; procedure TfrmMain.FormCreate(Sender: TObject);var aWSAData:TWSAData;begin if WSAStartup($0101,aWSAData)<>0 thenraise Exception.Create("不能启动WinSock动态链接库"); messageBox(Handle,aWSAdata.szDescription ,"WinSock动态链接库版本",mb_ok);end;procedure TfrmMain.btnExitClick(Sender: TObject);begin Close;end;procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);begin if InTrans thenif MessageBox(handle,"正在接收文件,停止吗?","提示",MB_YESNO)=IDNO then abort; IF SERVER<>INVALID_SOCKET THEN CLOSESOCKET(SERVER);//释放winsock动态链接库所创建的资源 if WSACleanup<>0 thenmessagebox(handle,"清除Winsock动态链接库错误!","提示",MB_OK) ELSEmessagebox(handle,"清除Winsock动态链接库成功!","提示",MB_OK);end;procedure TfrmMain.btnListenClick(Sender: TObject);var ca:SOCKADDR_IN;begin //创建服务器端SOCKET Server:=Socket(PF_INET,SOCK_STREAM,IPPROTO_IP); IF server=invalid_socket then beginstabar.SimpleText :="创建接收SOCKET错误1";exit; end; //绑定服务器端SOCKET ca.sin_family :=PF_INET; CA.sin_port :=htons(strtoint(trim(edtPort.Text ))); ca.sin_addr.S_addr :=INADDR_ANY; if bind(server,ca,sizeof(ca))=socket_error then beginstabar.SimpleText :="绑定socket错误,请更改接收端口";closeSocket(server);exit; end elsestabar.SimpleText :="绑定接收端socket成功!"; //开始监听 listen(server,5); btnlisten.Enabled :=False; btnstop.Enabled :=true;end;procedure TfrmMain.btnReceiveClick(Sender: TObject);begin if (server=INVALID_SOCKET) THEN BEGINMESSAGEBOX(HANDLE,"还没有进行监听,请先进行监听!","提示",MB_OK);EXIT; END; IF SaveDialog.Execute THENRECVFILE(SaveDialog.FileName );end;procedure TfrmMain.btnStopClick(Sender: TObject);begin STOPTRANS:=TRUE; IF SERVER<>INVALID_SOCKET THEN cLOSESOCKET(SERVER); //此处需要说明 server:=INVALID_SOCKET; bTNSTOP.Enabled :=fALSE; BTNlISTEN.Enabled :=TRUE;end;end.
客户端代码: unit ClientFrm;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls,WinSock;type TfrmMain = class(TForm)opendfile: TOpenDialog;Label1: TLabel;edtIP: TEdit;Label2: TLabel;edtPort: TEdit;StatusBar: TStatusBar;btnConnect: TButton;btnSend: TButton;btnStop: TButton;btnExit: TButton;ProgressBar: TProgressBar;procedure FormCreate(Sender: TObject);procedure btnExitClick(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure btnConnectClick(Sender: TObject);procedure btnSendClick(Sender: TObject);procedure btnStopClick(Sender: TObject); private{ Private declarations } Client:TSocket; public{ Public declarations }StopTrans:Boolean; //是否停止发送的开发InTrans:Boolean;//表示是否正在传送文件procedure TransFile(FileName:String); //传递文件的过程 end; const BlockLen=1024*4; //每次发送的最大数据量var frmMain: TfrmMain;implementation{$R *.dfm}procedure TfrmMain.TransFile(FileName:String); //传递文件的过程var Ftrans:file of Byte; Flen:integer; BlockNum,RemainLen:integer; BlockBuf:array[0..BlockLen-1] of Byte; i:integer; SendLen:Integer;begin assignFile(Ftrans,filename); reset(Ftrans); Flen:=FileSize(Ftrans); BlockNum:=Flen div BlockLen; progressBar.Max :=1+BlockNum; RemainLen:=Flen mod BlockLen; StopTrans:=False; InTrans:=True; SendLen:=1; for i:=0 to BlockNum-1 do beginif (StopTrans) or (SendLen<=0) then Break;BlockRead(Ftrans,Blockbuf[0],BlockLen);SendLen:=Send(Client,Blockbuf,BlockLen,0);ProgressBar.Position :=i;Application.processMessages; end; if StopTrans then beginCloseFile(Ftrans);InTrans:=False;StatusBar.SimpleText :="";MessageBox(Handle,"停止传输!","提示",mb_ok);progressbar.Position :=0;exit; end; if (SendLen<=0) then beginCloseFile(Ftrans);InTrans:=False;StatusBar.SimpleText :="";messagebox(handle,"传出异常终止!","提示",MB_OK);progressBar.Position :=0;exit; end; if remainLen>0 then beginBlockRead(Ftrans,BlockBuf[0],RemainLen);SendLen:=send(client,BlockBuf,Remainlen,0);if (sendLen<=0) thenbegin closeFile(Ftrans); InTrans:=False; StatusBar.SimpleText :=""; messagebox(handle,"传输异常终止!","提示",mb_ok); progressBar.Position :=0; exit;end; end; progressBar.Position :=ProgressBar.Max ; CloseFile(Ftrans); InTrans:=False; StatusBar.SimpleText :=""; messagebox(handle,"传输完成!","提示",mb_ok); progressbar.Position :=0;end;procedure TfrmMain.FormCreate(Sender: TObject);var aWSAData:TWSAData;begin if WSAStartup($0101,aWSAData)<>0 thenraise Exception.Create("不能启动WinSock动态链接库"); messageBox(Handle,aWSAdata.szDescription ,"WinSock动态链接库版本",mb_ok);end;procedure TfrmMain.btnExitClick(Sender: TObject);begin Close;end;procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);begin if InTrans thenif MessageBox(handle,"正在传输文件,停止吗?","提示",MB_YESNO)=IDNO then abort;//释放winsock动态链接库所创建的资源if WSACleanup<>0 then messagebox(handle,"清除Winsock动态链接库错误!","提示",MB_OK)ELSE messagebox(handle,"清除Winsock动态链接库成功!","提示",MB_OK);CloseSocket(Client);end;procedure TfrmMain.btnConnectClick(Sender: TObject);var ca:SOCKADDR_IN; hostaddr:u_long;begin Client:=Socket(PF_INET,SOCK_STREAM,IPPROTO_IP); IF CLIENT=INVALID_SOCKET THEN BEGINStatusBar.SimpleText :="为连接远程服务器端创建COSKET错误!";exit; end; ca.sin_family :=PF_INET; CA.sin_port :=HTONS(STRTOINT(TRIM(EDTpORT.Text ))); HOSTADDR:=INET_ADDR(PCHAR(TRIM(EDTIP.Text ))); //判断IP是否合法 if (hostaddr= -1) then beginStatusBar.SimpleText :="主机IP地址:"+trim(edtip.Text )+"错误";exit; end elseca.sin_addr.S_addr :=hostaddr; //连接服务器 if connect(Client,ca,sizeof(ca))<>0 then beginStatusBar.SimpleText :="连接服务器端SOCKET错误!";exit; end elseStatusBar.SimpleText :="连接远程SOCKET成功!";end;procedure TfrmMain.btnSendClick(Sender: TObject);begin if (opendfile.Execute ) and (FileExists(opendfile.FileName )) thentransFile(opendfile.FileName );end;procedure TfrmMain.btnStopClick(Sender: TObject);begin Stoptrans:=True;end;end.