内存错误 - C 中的简单 XOR 加密

Memory error - Simple XOR encryption in C

我在以下列格式打印十六进制时遇到一些内存问题:\xAA\xAB\xDC 使用我的加密例程。

我做了一些修改,使用 snprintf()strcat() 试图修复输出并且它在一定程度上起作用。

这是我最初开始使用的功能,可能比我修改后的版本更好。

char *encrypt(char key, const char *a) {
    char *output = malloc(strlen(a)+1);
    bzero(output, strlen(a)+1);
    strcpy(output, a);
    char *tmp = output;
    int i;
    for (i = 0; tmp[i] != 0; i++) {
        tmp[i] = key ^ tmp[i];
    }
    return output;
}

我目前的进度如下:

char *encrypt(char key, const char *a) 
{
    char buf[256];
    char *tmp = a;
    int i;
    int *k;

    for (i = 0; tmp[i] != 0; i++)
    {
        char temp[10];
        k = key ^ tmp[i];
        snprintf(temp, sizeof(temp), "\x%s", k);
        strcat(buf, temp);
    }
    return buf;
}

int main(int argc, char **argv)
{
    if (argv[1] == NULL){
        printf("Usage: %s <string>\n", argv[0]);
    }
    else printf("Encrypted string: %s\n", encrypt(0xEB, argv[1]));
    return 0;
}

如果有人能为我指出正确的方向来解决内存问题,如果可以改进代码,我将不胜感激。

主要问题,在您的代码中,buf 是函数 encrypt() 的局部问题。所以你可能不会 return 函数中的数组。函数完成后,数组将不复存在,returned 地址将无效。如果调用者使用 returned 值,它将调用 undefined behavior.

您需要将 buf 定义为指针,并在使用结束后使用 malloc() or family. Also, you need to free() 内存分配动态内存。

也就是说,

  • 您已将 k 定义为指针,但未为其分配内存。
  • k = key ^ tmp[i];好像没有意义,可能你的意思是*k = key ^ tmp[i];
  • %s 需要指向 char 数组 (null-terminated) 的指针作为参数。从这一点来看,snprintf(temp, sizeof(temp), "\x%s", k); 看起来也是错误的。您需要的是 snprintf(temp, sizeof(temp), "\x%d", *k); 来打印 int 值。

而不是:

int *k;
k = key ^ tmp[i];
snprintf(temp, sizeof(temp), "\x%s", k);

使用这个:

unsigned char k;
k = key ^ tmp[i];
snprintf(temp, sizeof temp, "\x%02X", k);

请注意,您还需要对 buf 进行其他更改。首先你永远不会初始化它,所以你正在附加到垃圾。而且你永远不会检查你没有溢出它。

您还尝试从函数中 return this,但是,由于它是局部变量,因此当函数 returns.

时它不再存在

有关如何从函数中获取 freshly-written 字符串的一些建议,请参阅 this thread。您可以像第一次尝试一样使用 malloc(256)(并记得在 snprintf 调用中用分配的长度替换 sizeof buf)。


对于密钥和消息,使用 unsigned char 而不是 char 会更可靠。问题的一个示例是,在 x86 或 x64 上,char 的范围是 -128127,因此当您提供 0xEB(即 235)时是一个 out-of-range 赋值,它不是 well-defined。

但是在常见的系统上,您可以使用 char,因为它们倾向于通过使用 2 的补码和截断多余的位来定义 out-of-range 赋值,这在您的情况下有效。