我有以下简单的代码来测试strncpy-ing overflow:
int main() {
char *test = "hellooo";
char **str_arr;
str_arr = malloc(sizeof(char*));
// allocate 5 bytes
str_arr[0] = malloc(5);
printf("%s size is %lu\n", strncpy ( str_arr[0], test, sizeof(str_arr[0]) ), sizeof(str_arr[0]));
free(str_arr[0]);
free(str_arr);
}
打印
hellooo size is 8
我的问题是为什么打印“hellooo”而不是“hell”,因为我只分配了5个字节?如何分配打印“地狱”(使用空终止)?
答案 0 :(得分:1)
sizeof(str_arr[0])
是sizeof( char* )
,即指针的大小
此外,你需要6个字节用于"你好",1个额外用于空终止
答案 1 :(得分:1)
您正在查看缓冲区溢出。你分配了5个字节,但你推的次数超过5个
char *
不是真正的字符串类型,它只是char
地址,因此您可以尝试从那里访问超过5个字节,这正是您所做的:
你写了8个字节"hellooo"
,它是一个8字节的数组(NUL
终止的数组)。这种溢出通常会产生两种结果之一:
答案 2 :(得分:0)
sizeof(str_arr[0])
返回指针的大小,而不是您分配的字节数。 sizeof
是一个编译时构造,它不知道你在运行时分配了多少字节。
strncpy
中还存在一个很大的缺陷 - 如果字符串到达缓冲区的末尾,则不会得到空终止字符。你需要在复制后自己添加它。
strncpy(str_arr[0], test, 5);
str_arr[0][5] = 0;
答案 3 :(得分:0)
我希望这是正确的,但是因为:
char *test = "hellooo";
char **str_arr;
str_arr = malloc(sizeof(char*));
// allocate 5 bytes
str_arr[0] = malloc(5);
printf("%s size is %lu\n", strncpy ( str_arr[0], test, sizeof(str_arr[0])), sizeof(str_arr[0]));
就像是
test --> |h|e|l|l|o|o|o|\0|
^
|
str_arr---
和
printf("%s size is %lu\n", strncpy ( str_arr[0], test, sizeof(str_arr[0])), sizeof(str_arr[0]));
将打印到\0
,这意味着它将打印整个字符串。