简体   繁体   English

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

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

I'm using openssl's libcrypto library to try and create a sha256 hash of a arbitrary input buffer, however when I null terminate the hash buffer to make it a C string it crashes but only when using dynamic memory returned from malloc but not when I use statically allocated memory like in this example: generate sha256 with openssl and C++ . 我正在使用openssl的libcrypto库来尝试创建一个任意输入缓冲区的sha256哈希值,但是当我将null终止哈希缓冲区以使其成为一个C字符串时它会崩溃,但只有在使用从malloc返回的动态内存时才会崩溃但不是在我使用时静态分配内存,如本例所示: 使用openssl和C ++生成sha256 I'm allocating 65 bytes just like the example, as shown by the length value being printed. 我正在分配65个字节,就像示例一样,正如打印的length值所示。 So why does null terminating the buffer crash when using dynamic memory as opposed to static memory? 那么为什么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] = '\0';

    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;
}

I suspect this is because you did not mean: 我怀疑这是因为你不是故意的:

*out[64] = '\0';

but rather: 反而:

(*out)[64] = '\0';

Array subscripting ( [] ) has higher precedence than the indirection ( * ) operator in C, so what you wrote is the equivalent to: 数组下标( [] )的优先级高于C中的间接( * )运算符,因此您编写的内容相当于:

*(out[64]) = '\0';

which will be corrupting a random area on the stack (where the char ** lives). 这会破坏堆栈上的随机区域( char **所在的区域)。

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

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