sockets - delphi中netcat之类的监听程序不回传命令

标签 sockets delphi winsock remote-access netcat

我有一个使用 winsock 监听 8080 端口的 delphi 程序 这是到目前为止的代码:

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($0101,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.

正如您从此处的屏幕截图中所见: enter image description here

我打开 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($101,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.

关于sockets - delphi中netcat之类的监听程序不回传命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28217461/

相关文章:

java - UDP 组播是正确的选择吗?

java - 通过 UDP 的视频文件数据包——增量读取和流式传输

xml - Delphi 和 XML CDATA

c - 如何在 Windows 中退出阻塞的 recv()?

c++ - 使用套接字一次发送整个数据

c - 为什么 select() 调用会超时?在常见场景中它的合理值是多少?

sql-server - 在 SQL Server 中创建 USER 生成错误 : SUBQUERY RETURNED MORE THAN 1 VALUE

C++ Builder DBGrid 在 xlsx 文件中导出到 Excel

delphi - GetMem 用于一个 PChar 变量更改其他 PChar 变量的内容

python - 使用不是 2 的幂的 bufsize 调用 socket.recv 的实际影响是什么?