C++ 奇怪的 memcpy 行为

标签 c++ winsock memcpy

<分区>

对于 CTF,我试图构建一个易受简单缓冲区溢出攻击的 WinSock 应用程序,但是我遇到了一个,至少对我来说,memcpy 的非常奇怪的行为。 Visual Studio 中的所有安全措施均已禁用。

char recvbuf[1024];
char sendbuf[300];
int recvbuflen=1024;
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
memcpy(sendbuf, recvbuf, recvbuflen);
if (iResult > 0) {
    printf("Bytes received: %d\n", iResult);

    // Echo the buffer back to the sender
    iSendResult = send(ClientSocket, sendbuf,sizeof(sendbuf) , 0);

    .........

正如您从上面的代码片段中看到的,这是一个非常简单的应用程序,它只回复接收到的字节。现在我有两个关于 memcpy 行为的问题:

  1. 为什么这不会触发缓冲区溢出?在我看来,我正在尝试将一个 1024 个字符长的缓冲区复制到一个 300 个字符长的缓冲区。当尝试使用 char* 进行相同操作时,它确实会触发缓冲区溢出。

  2. iSendResult = send(ClientSocket, sendbuf,sizeof(sendbuf) , 0); 当我将大小更改为 iResult(这是接收到的字节总数)时,应用程序确实正确地回答了所有接收到的字符,但我选择了要发送的 sendbuf,它只有 300 个字符长,他从哪里得到剩余的字符(某种临时缓冲区?)

所以这是我不确定如何解释的两种行为。 如果有人能阐明这一点,那就太好了。

最好的问候!

最佳答案

您正在溢出缓冲区。 您希望发生什么? 缓冲区溢出是一种未定义行为的情况。在像这样的非常简单的程序中,未定义的行为习惯于正常工作。这就是未定义行为如此阴险的原因。

当您的程序运行时,它会将 300 个字节写入 sendbuf,并将剩余字节写入内存中 sendbuf 之后的任何内容。我的猜测是 recvbuflen 包含字节 300 到 304。如果你在 sendbuf 之后添加一个新变量 char unused[1024] = {0} 你通过检查 memcpy 之后的内容,或许能够看到字节被写入的位置。

关于C++ 奇怪的 memcpy 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40152409/

相关文章:

c - 提高通用交换的性能

c++ - 为什么在引用文字时必须使用 const 引用

c++ - 读取整个文件并通过套接字发送

c - 从 windows xp 中的 addrinfo 结构获取 ipv6 地址

c - WinSock - UDP 广播监听器

c++ - 将结构复制(使用赋值)到 union 内的结构导致段错误

c++ - memcpy 写入类型为 ‘class uint256’ 的对象

c++ - std::throw_with_nested() 在内存不足的情况下调用 std::terminate()

c++ - 将字符串 vector 保存到磁盘不起作用

c++ - 检查几个组合框的索引是否唯一