C++ 奇怪的 memcpy 行为

C++ Strange memcpy behaviour

对于 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.