内存错误 - 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
的范围是 -128
到 127
,因此当您提供 0xEB
(即 235
)时是一个 out-of-range 赋值,它不是 well-defined。
但是在常见的系统上,您可以使用 char
,因为它们倾向于通过使用 2 的补码和截断多余的位来定义 out-of-range 赋值,这在您的情况下有效。
我在以下列格式打印十六进制时遇到一些内存问题:\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
的范围是 -128
到 127
,因此当您提供 0xEB
(即 235
)时是一个 out-of-range 赋值,它不是 well-defined。
但是在常见的系统上,您可以使用 char
,因为它们倾向于通过使用 2 的补码和截断多余的位来定义 out-of-range 赋值,这在您的情况下有效。