繁体   English   中英

recv覆盖一个字符[]

[英]recv overwrite a char[]

我正在尝试制作一些客户端服务器脚本,就像我过去所做的其他脚本一样。
但是在这个我有一个问题。 如果我发布代码并将其输出给我,那会更好。
码:

#include <mysql.h> //not important now
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

//constant definition
#define SERVER_PORT 2121
#define LINESIZE 21

//global var definition
char victim_ip[LINESIZE], file_write[LINESIZE], hacker_ip[LINESIZE];

//function
void leggi (int); //not use now for debugging purpose
//void scriviDB (); //not important now

main () {

int sock, client_len, fd;

struct sockaddr_in server, client;

// transport end point
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  perror("system call socket fail");
  exit(1);
}

server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("10.10.10.1");
server.sin_port = htons(SERVER_PORT);

// binding address at transport end point
if (bind(sock, (struct sockaddr *)&server, sizeof server) == -1) {
  perror("system call bind fail");
  exit(1);
}

//fprintf(stderr, "Server open: listening.\n");
listen(sock, 5);

/* managae client connection */
while (1) {
  client_len = sizeof(client);
  if ((fd = accept(sock, (struct sockaddr *)&client, &client_len)) < 0) 
     { perror("accepting connection"); exit(1);  }

  strcpy(hacker_ip, inet_ntoa(client.sin_addr));
  printf("1 %s\n", hacker_ip); //debugging purpose
  //leggi(fd);

//////////////////////////
//receive client 
  recv(fd, victim_ip, LINESIZE, 0);
  victim_ip[sizeof(victim_ip)] = '\0';
  printf("2 %s\n", hacker_ip); //debugging purpose
  recv(fd, file_write, LINESIZE, 0);
  file_write[sizeof(file_write)] = '\0';
  printf("3 %s\n", hacker_ip); //debugging purpose
  printf("%s@%s for %s\n", file_write, victim_ip, hacker_ip);

  //send to client
  send(fd, hacker_ip, 40, 0); //now is hacker_ip for debug

/////////////////////////

  close(fd);

}//end while

exit(0);
} //end main

客户端发送字符串:./send -i 10.10.10.4 -f filename.ext
因此脚本将在服务器上发送-i(IP)和-f(FILE)。
这是我的输出服务器端:

1 10.10.10.6
2 10.10.10.6
3
filename.ext@10.10.10.4用于

如您所见,printf(3)和printf(ip,file,ip)失败。
我不知道如何在何处,但有人覆盖了我的hacker_ip字符串。
谢谢你的帮助! :)

TCP提供流,而不是数据包。 因此,不能保证通过1 send()调用发送的数据需要1 recv()调用才能接收。 它可能需要几个recv()调用才能接收一个send()调用发送的内容,或者可能需要1个recv()调用来接收多个send()调用发送的内容-必须以某种方式处理。

特别是,您应该检查recv()的返回值以了解收到了多少字节,这可能只是一个开始,因此您至少不会在字符串中打印垃圾。

ssize_t bytes = recv(fd, victim_ip, LINESIZE, 0);
 if(bytes == 0) {
   //remote closed the connection, handle it
 } else if (bytes < 0) {
    //handle error
 } else {
   victim_ip[bytes] = '\0';
   printf("%s\n", victim_ip); 
}

您应该更正以下行:

victim_ip[sizeof(victim_ip)] = '\0';

file_write[sizeof(file_write)] = '\0';

这是覆盖hacker_ip字符串的代码。

它在数组末尾(sizeof(file_write) == LINE_SIZE)之后写入零。 如果要写入零看门狗,则应将array的维数设置为另外一个char,如file_write[LINE_SIZE+1]

这除外,它应该起作用。 对于像此处这样的非常小的数据块(21字节),不太可能将数据包拆分(标准以太网帧约为1400字节)。 但是,如果您进行了多次发送,则肯定会将它们合并在同一数据包中。

看到发送者代码会很麻烦。 您是否每次都发送完整的缓冲区? (应该查看您的recv())。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM