Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么以下代码容易受到堆溢出攻击_C_Malloc_Heap_Buffer Overflow - Fatal编程技术网

C 为什么以下代码容易受到堆溢出攻击

C 为什么以下代码容易受到堆溢出攻击,c,malloc,heap,buffer-overflow,C,Malloc,Heap,Buffer Overflow,我是网络安全新手,我试图理解为什么以下代码容易受到堆溢出攻击 struct data { char name[128]; }; struct fp { int (*fp)(); }; void printName() { printf("Printing function...\n"); } int main(int argc, char **argv) { struct data *d; struct fp *f; d = malloc(sizeof(struct data));

我是网络安全新手,我试图理解为什么以下代码容易受到堆溢出攻击

struct data {
 char name[128];
};
struct fp {
 int (*fp)();
};
void printName() {
 printf("Printing function...\n");
}
int main(int argc, char **argv) {
 struct data *d;
 struct fp *f;
 d = malloc(sizeof(struct data));
 f = malloc(sizeof(struct fp));
 f->fp = printName;
 read(stdin,d->name,256);

 f->fp();
}
这是因为
读取(stdin,d->name,256)
,因为它在
结构数据中读取的
字符名
超过了分配的缓冲区大小
128

任何帮助都会很好

A与A类似,只是攻击者不会覆盖堆栈中的值,而是践踏堆中的数据

请注意,在代码中有两个动态分配的值:

d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
因此
d
现在保存堆中128字节内存块的地址,而
f
保存8字节(假设为64位机器)内存块的地址。从理论上讲,这两个地址可能相距甚远,但由于它们都相对较小,操作系统很可能分配了一大块连续内存,并为您提供了相邻的指针

因此,一旦运行
f->fp=printName,您的堆看起来像这样:

注意:每行8字节宽

然后,代码到达该行

f->fp();

这是使用存储在
f
中的地址进行的函数调用。计算机进入内存位置
f
并检索存储在那里的值,该值现在是攻击者恶意代码的地址。既然我们把它称为函数,那么机器现在跳转到那个地址,并开始执行存储在那里的代码,现在你手上有一个可爱的攻击向量。< / P>是的,它允许分配更多的空间。但我认为这是缓冲区溢出而不是堆溢出,尽管我被告知这与指针本身有关。但是,伙计,我非常困惑,而且我对C和一般计算都是新手:(:(
read(stdin,d->name,256);
看起来是错误的。确定要在这里使用
stdin
read(int-fd,void*buf,size\u-t-count)
?(启用所有编译器警告)谢谢您的详细解释,先生!很快,什么是
f->fp()
意思是什么?什么是
fp()
甚至是某种函数调用?箭头操作符(
->
)是“解除引用和访问”。
f
是指向
结构fp
的指针,因此
f->fp
相当于
(*f).fp
,即获取位于内存位置
f
struct fp
,并访问其名为
fp
的成员。
fp
成员是指向函数的指针,因此将
()
在调用它指向的函数之后。更一般地说,在C语言中,函数名被视为指向这些函数的指针。因此
someFunc()
只是将
someFunc
作为指向函数的指针加载,然后执行它,就像
f->fp()
正在加载
f->fp
并执行它。就像您可以存储指向数据的指针一样,您可以存储指向函数的指针,这实际上与按名称调用函数是一样的。我明白了,它现在开始有意义了。所以本质上,在
读取中出现了缓冲区溢出(stdin,d->name,256)
因此,一些内存内容泄漏到相邻的结构中。然后,当指针
f
解除对结构
fp
的引用时,他们可以将其指向堆中的另一个函数??我感谢您迄今为止的帮助-如果您能提供一个图表,那将是非常好的,先生。上帝保佑,先生!!准确地说!我本来想在答案中加入一个图表,但最初决定不这样做。如果对你有帮助的话,我现在会回去编辑答案,包括一些。
     |  0xbadc0de  |
     +-------------+
f -> |  0xbadc0de  |
     +-------------+
     |     ...     |
     |  0xbadc0de  |
     |  0xbadc0de  |
d -> |  0xbadc0de  |
     +-------------+
     |             |
f->fp();