为什么 NULL 在使用动态内存而不是静态内存时终止 sha256 哈希崩溃?

Why does NULL terminating a sha256 hash crash when using dynamic memory but not static memory?

我正在使用 openssl 的 libcrypto 库尝试创建任意输入缓冲区的 sha256 散列,但是当我 null 终止散列缓冲区以使其成为 C 字符串时它会崩溃,但仅当使用从 malloc 但当我使用静态分配的内存时就不会像本例中那样:generate sha256 with openssl and C++。我正在像示例一样分配 65 个字节,如正在打印的 length 值所示。那么为什么在使用动态内存而不是静态内存时 null 终止缓冲区崩溃?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>

static int sha256(char *in, char **out)
{
    int rtrn, i;
    SHA256_CTX sha256;
    unsigned char hash[SHA256_DIGEST_LENGTH];

    rtrn = SHA256_Init(&sha256);
    if(rtrn < 0)
    {
        printf("Sha Init Error\n");
        return -1;
    }

    rtrn = SHA256_Update(&sha256, in, strlen(in));
    if(rtrn < 0)
    {
        printf("Sha Update Error\n");
        return -1;
    }

    rtrn = SHA256_Final(hash, &sha256);
    if(rtrn < 0)
    {
        printf("Sha Final Error\n");
        return -1;
    }

    *out = malloc((SHA256_DIGEST_LENGTH * 2) + 1);
    if(*out == NULL)
    {
        printf("Can't allocate output buf\n");
        return -1;
    }

    for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        sprintf(*out + (i * 2), "%02x", hash[i]);
    }

    printf("Length: %d\n", (SHA256_DIGEST_LENGTH * 2) + 1);

    *out[64] = '[=10=]';

    return 0;
}

int main(void)
{
    int rtrn;
    char *input = "3r98h932hr934hor";
    char *output;

    rtrn = sha256(input, &output);
    if(rtrn < 0)
    {
        printf("Sha256\n");
        return -1;
    }

    printf("%s\n", output);

    return 0;
}

我怀疑这是因为你不是这个意思:

*out[64] = '[=10=]';

而是:

(*out)[64] = '[=11=]';

数组下标([])比C中的间接(*)运算符higher precedence,所以你写的相当于:

*(out[64]) = '[=12=]';

这将破坏堆栈上的随机区域(char ** 所在的区域)。