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

时间:2016-01-16 21:07:44

标签: c arrays pointers printf return-value

我在使用以下格式打印十六进制时遇到了一些内存问题:\ 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;
}

如果有人能指出我如何解决内存问题的正确方向,如果代码可以改进,我会非常感激。

2 个答案:

答案 0 :(得分:3)

代码中的主要问题buf是函数encrypt()的本地问题。所以你可能不会从函数返回数组。函数完成后,数组将不再存在,返回的地址将无效。如果返回的值在调用者中使用,则它将调用undefined behavior

您需要将buf定义为指针,并使用malloc()或系列分配动态内存。此外,一旦使用结束,您需要free()内存。

那就是说,

  • 您已将k定义为指针但未向其分配内存。
  • k = key ^ tmp[i];似乎没有意义,也许你的意思是*k = key ^ tmp[i];
  • %s期望指向char数组(以null结尾)作为参数。从那时起,snprintf(temp, sizeof(temp), "\\x%s", k);看起来也是错误的。您需要snprintf(temp, sizeof(temp), "\\x%d", *k);来打印int值。

答案 1 :(得分:0)

而不是:

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进行其他更改。首先你永远不会初始化它,所以你附加垃圾。你永远不会检查你是否没有溢出它。

此外,您尝试从函数返回此函数,但由于它是局部变量,因此在函数返回时它将不再存在。

有关如何从函数中获取新写入字符串的一些建议,请参阅this thread。您可以使用malloc(256)与第一次尝试相同(并记住在sizeof buf调用中使用mallocated长度替换snprintf

对密钥和邮件使用unsigned char而不是char会更加健壮。问题的一个示例是,在x86或x64上,char的范围为-128127,因此当您提供0xEB(即235)时是一个超出范围的任务,没有明确定义。

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