delphi 中的 Netcat 之类的监听程序不会发回命令
Netcat like listening program in delphi does not send back commands
我有一个 delphi 使用 winsock 监听端口 8080 的程序
这是到目前为止的代码:
program Project1;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
WinSock;
var
WSAData: TWSAData;
ServerSocket,ClientSocket: TSocket;
ServerAddr, ClientAddr: TSockAddr;
ClientAddrSize,Status,ret: Integer;
Buffer1,buffer2: array[0..1024] of Char;
begin
writeln('started..');
WSAStartup(01,WSAData);
ServerSocket:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
ServerAddr.sin_family:=AF_INET;
ServerAddr.sin_port:=htons(8080);
ServerAddr.sin_addr.S_addr:=INADDR_ANY;
bind(ServerSocket,ServerAddr,SizeOf(ServerAddr));
listen(ServerSocket,10);
ClientAddrSize:=SizeOf(ClientAddr);
ClientSocket:=accept(ServerSocket,@ClientAddr,@ClientAddrSize);
if ClientSocket <> INVALID_SOCKET then
begin
while True do
begin
ret:=recv(ClientSocket,Buffer2,SizeOf(Buffer2),0);
Writeln(Buffer2);
Readln(Input, Buffer1);
ret:=send(ClientSocket,Buffer1,SizeOf(Buffer1),0);
end;
end;
end.
正如您从此处的屏幕截图中所见:
我打开 netcat 并使用 "nc 127.0.0.1 8080 -e cmd.exe" 连接到我的程序
打开远程命令 shell.
我的程序得到了你通常在打开命令提示符时看到的第一行,但后来我无法执行像 "dir" 这样的命令,即使我在
之后发送命令
Readln(Input, Buffer1);
有什么想法吗?
编辑:如您所见,"dir" 命令写在 "C:\>" 下面
我需要像 netcat 那样做,也许我需要为命令创建一个管道。
到目前为止这还不是绝对正确的,因为出于某种原因它会回显第一个命令,而其余的则需要两次输入才能执行。
program Project1;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
WinSock,
uSockFunc in 'uSockFunc.pas';
var
WSAData: TWSAData;
ServerSocket,ClientSocket: TSocket;
ServerAddr, ClientAddr: TSockAddr;
ClientAddrSize: Integer;
Buffer1, buffer2 : string;
begin
writeln('started..');
WSAStartup(1,WSAData);
ServerSocket:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
ServerAddr.sin_family:=AF_INET;
ServerAddr.sin_port:=htons(8080);
ServerAddr.sin_addr.S_addr:=INADDR_ANY;
bind(ServerSocket,ServerAddr,SizeOf(ServerAddr));
listen(ServerSocket,10);
ClientAddrSize:=SizeOf(ClientAddr);
ClientSocket:=accept(ServerSocket,@ClientAddr,@ClientAddrSize);
if ClientSocket <> INVALID_SOCKET then
begin
while True do
begin
Buffer2 := RecvLn(ClientSocket, #$A);
Writeln(Buffer2);
Buffer2 := '';
Readln(Input, Buffer1);
SendString(ClientSocket, Buffer1 + #13#10);
Buffer1 := '';
end;
end;
end.
我还使用了这个不是我的单位的 "SendString" 和 "RecvLn" 功能:
unit uSockFunc;
interface
uses windows, winsock;
const
EOL = #13#10;
function Connect(address : String; port : Integer) : Integer;
procedure Disconnect(sinsock : TSocket);
function SendBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
function SendString(s : TSocket; str : String) : Integer;
function RecvLn(s : TSocket; Delim: String = EOL): String;
function RecvLen(s : TSocket) : Integer;
function RecvBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
implementation
function Connect(address : String; port : Integer) : Integer;
var
sinsock : TSocket;
SockAddrIn : TSockAddrIn;
hostent : PHostEnt;
begin
sinsock := Winsock.socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
SockAddrIn.sin_family := AF_INET;
SockAddrIn.sin_port := htons(Port);
SockAddrIn.sin_addr.s_addr := inet_addr(pchar(address));
if SockAddrIn.sin_addr.s_addr = INADDR_NONE then
begin
HostEnt := gethostbyname(pchar(Address));
if HostEnt = nil then
begin
result := SOCKET_ERROR;
Exit;
end;
SockAddrIn.sin_addr.s_addr := Longint(PLongint(HostEnt^.h_addr_list^)^);
end; //CHANGE MADE
if Winsock.Connect(sinSock, SockAddrIn, SizeOf(SockAddrIn)) = SOCKET_ERROR Then
result := SOCKET_ERROR
else
result := sinsock;
end;
function SendBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
begin
Result := send(s, Buffer, Len, 0);
end;
function SendString(s : TSocket; str : String) : Integer;
begin
result := SendBuf(s, str[1],Length(str));
end;
function RecvLn(s : TSocket; Delim: String = EOL): String;
const
BUFFER_SIZE = 255;
var
Buffer: String;
I, L: Cardinal;
begin
Result := '';
I := 1;
L := 1;
SetLength(Buffer, BUFFER_SIZE);
while (L <= Cardinal(Length(Delim))) do
begin
if recv(s, Buffer[I], 1, 0) < 1 then Exit;
///
if Buffer[I] = Delim[L] then
Inc(L)
else
L := 1;
Inc(I);
if I > BUFFER_SIZE then
begin
Result := Result + Buffer;
I := 1;
end;
end;
Result := Result + Copy(Buffer, 0, I - L);
end;
function RecvLen(s : TSocket) : Integer;
begin
if ioctlsocket(s, FIONREAD, Longint(Result)) = SOCKET_ERROR then
begin
Result := SOCKET_ERROR;
end;
end;
function RecvBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
begin
Result := recv(s, Buffer, Len, 0);
if (Result = SOCKET_ERROR) and (WSAGetLastError = WSAEWOULDBLOCK) then
begin
Result := 0;
end;
end;
procedure Disconnect(sinsock : TSocket);
begin
closesocket(sinsock);
end;
end.
我有一个 delphi 使用 winsock 监听端口 8080 的程序 这是到目前为止的代码:
program Project1;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
WinSock;
var
WSAData: TWSAData;
ServerSocket,ClientSocket: TSocket;
ServerAddr, ClientAddr: TSockAddr;
ClientAddrSize,Status,ret: Integer;
Buffer1,buffer2: array[0..1024] of Char;
begin
writeln('started..');
WSAStartup(01,WSAData);
ServerSocket:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
ServerAddr.sin_family:=AF_INET;
ServerAddr.sin_port:=htons(8080);
ServerAddr.sin_addr.S_addr:=INADDR_ANY;
bind(ServerSocket,ServerAddr,SizeOf(ServerAddr));
listen(ServerSocket,10);
ClientAddrSize:=SizeOf(ClientAddr);
ClientSocket:=accept(ServerSocket,@ClientAddr,@ClientAddrSize);
if ClientSocket <> INVALID_SOCKET then
begin
while True do
begin
ret:=recv(ClientSocket,Buffer2,SizeOf(Buffer2),0);
Writeln(Buffer2);
Readln(Input, Buffer1);
ret:=send(ClientSocket,Buffer1,SizeOf(Buffer1),0);
end;
end;
end.
正如您从此处的屏幕截图中所见:
我打开 netcat 并使用 "nc 127.0.0.1 8080 -e cmd.exe" 连接到我的程序 打开远程命令 shell.
我的程序得到了你通常在打开命令提示符时看到的第一行,但后来我无法执行像 "dir" 这样的命令,即使我在
之后发送命令Readln(Input, Buffer1);
有什么想法吗?
编辑:如您所见,"dir" 命令写在 "C:\>" 下面 我需要像 netcat 那样做,也许我需要为命令创建一个管道。
到目前为止这还不是绝对正确的,因为出于某种原因它会回显第一个命令,而其余的则需要两次输入才能执行。
program Project1;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
WinSock,
uSockFunc in 'uSockFunc.pas';
var
WSAData: TWSAData;
ServerSocket,ClientSocket: TSocket;
ServerAddr, ClientAddr: TSockAddr;
ClientAddrSize: Integer;
Buffer1, buffer2 : string;
begin
writeln('started..');
WSAStartup(1,WSAData);
ServerSocket:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
ServerAddr.sin_family:=AF_INET;
ServerAddr.sin_port:=htons(8080);
ServerAddr.sin_addr.S_addr:=INADDR_ANY;
bind(ServerSocket,ServerAddr,SizeOf(ServerAddr));
listen(ServerSocket,10);
ClientAddrSize:=SizeOf(ClientAddr);
ClientSocket:=accept(ServerSocket,@ClientAddr,@ClientAddrSize);
if ClientSocket <> INVALID_SOCKET then
begin
while True do
begin
Buffer2 := RecvLn(ClientSocket, #$A);
Writeln(Buffer2);
Buffer2 := '';
Readln(Input, Buffer1);
SendString(ClientSocket, Buffer1 + #13#10);
Buffer1 := '';
end;
end;
end.
我还使用了这个不是我的单位的 "SendString" 和 "RecvLn" 功能:
unit uSockFunc;
interface
uses windows, winsock;
const
EOL = #13#10;
function Connect(address : String; port : Integer) : Integer;
procedure Disconnect(sinsock : TSocket);
function SendBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
function SendString(s : TSocket; str : String) : Integer;
function RecvLn(s : TSocket; Delim: String = EOL): String;
function RecvLen(s : TSocket) : Integer;
function RecvBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
implementation
function Connect(address : String; port : Integer) : Integer;
var
sinsock : TSocket;
SockAddrIn : TSockAddrIn;
hostent : PHostEnt;
begin
sinsock := Winsock.socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
SockAddrIn.sin_family := AF_INET;
SockAddrIn.sin_port := htons(Port);
SockAddrIn.sin_addr.s_addr := inet_addr(pchar(address));
if SockAddrIn.sin_addr.s_addr = INADDR_NONE then
begin
HostEnt := gethostbyname(pchar(Address));
if HostEnt = nil then
begin
result := SOCKET_ERROR;
Exit;
end;
SockAddrIn.sin_addr.s_addr := Longint(PLongint(HostEnt^.h_addr_list^)^);
end; //CHANGE MADE
if Winsock.Connect(sinSock, SockAddrIn, SizeOf(SockAddrIn)) = SOCKET_ERROR Then
result := SOCKET_ERROR
else
result := sinsock;
end;
function SendBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
begin
Result := send(s, Buffer, Len, 0);
end;
function SendString(s : TSocket; str : String) : Integer;
begin
result := SendBuf(s, str[1],Length(str));
end;
function RecvLn(s : TSocket; Delim: String = EOL): String;
const
BUFFER_SIZE = 255;
var
Buffer: String;
I, L: Cardinal;
begin
Result := '';
I := 1;
L := 1;
SetLength(Buffer, BUFFER_SIZE);
while (L <= Cardinal(Length(Delim))) do
begin
if recv(s, Buffer[I], 1, 0) < 1 then Exit;
///
if Buffer[I] = Delim[L] then
Inc(L)
else
L := 1;
Inc(I);
if I > BUFFER_SIZE then
begin
Result := Result + Buffer;
I := 1;
end;
end;
Result := Result + Copy(Buffer, 0, I - L);
end;
function RecvLen(s : TSocket) : Integer;
begin
if ioctlsocket(s, FIONREAD, Longint(Result)) = SOCKET_ERROR then
begin
Result := SOCKET_ERROR;
end;
end;
function RecvBuf(s : TSocket; var Buffer; Len : Integer) : Integer;
begin
Result := recv(s, Buffer, Len, 0);
if (Result = SOCKET_ERROR) and (WSAGetLastError = WSAEWOULDBLOCK) then
begin
Result := 0;
end;
end;
procedure Disconnect(sinsock : TSocket);
begin
closesocket(sinsock);
end;
end.