首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

请教“数据执行保护DEP”是怎么阻止缓冲区溢出的

2012-01-26 
请问“数据执行保护DEP”是如何阻止缓冲区溢出的?在网上查了一些资料,下面是两段摘录的内容:

请问“数据执行保护DEP”是如何阻止缓冲区溢出的?
在网上查了一些资料,下面是两段摘录的内容:
=============================================================================================
  在栈溢出程序例子中,我们看到,恶意代码是被存放在栈(stack)上的。类似的,如果是一个堆(heap)溢出的安全漏洞,恶意代码是被存放在堆上。无论堆还是栈,都是数据页面。在数据页面上,通常情况下,是不应该执行代码的。
  在AMD64位CPU上,在页面表(page table)中的页面信息加了一个特殊的位,NX位(No eXecute)。
如果NX位为0,这个页面上可以执行指令。
如果NX位为1,这个页面上不允许执行指令。如果试图执行指令的话,就会产生异常。
  Intel在它的CPU上也提供了类似的支持,称为XD 位( eXecute Disable),其原理和AMD的NX是完全一样的。
  操作系统对DEP的支持,就是将系统或应用程序的数据页面,标注上NX位。这样,一旦由于堆栈缓存溢出的安全漏洞,导致恶意代码试图在数据页面上运行,CPU就会产生异常,导致程序终止,而不是去执行恶意指令。
=============================================================================================
  现代计算机被设计成能够理解人们头脑中的高级语言. 在使用高级语言构造程序时最重要的技术是过程(procedure)和函数(function). 从这一点来看, 一个过程调用可以象跳转(jump)命令那样改变程序的控制流程, 但是与跳转不同的是, 当工作完成时,函数把控制权返回给调用之后的语句或指令. 这种高级抽象实现起来要靠堆栈的帮助.
  堆栈也用于给函数中使用的局部变量动态分配空间, 同样给函数传递参数和函数返回值也要用到堆栈.
=============================================================================================


我的疑惑是:
1、堆栈中有数据data,也有代码code,操作系统怎么能简单的将整个堆栈标志为“不可执行”呢?
2、在栈溢出的情形中,假设一段包含了恶意代码的数据覆盖了正常的返回代码,操作系统怎样能判断并标志栈中(被覆盖后的)返回地址为不可执行?
3、难道是说操作系统并非简单的将整个堆栈标志为“不可执行”,而是在压栈前,对每一项数据进行标志,比如压入一个函数参数,它的地址就是映射到数据页,如果压入函数返回地址,它的地址就被映射到代码页?但XD/NX标志都是针对内存页设置的,操作系统并没有把程序中的数据和代码按区别的内存页存放吧?

[解决办法]
我想出来一些需要运行时动态生成code的程序,其他的不会需要在栈里面放指令
[解决办法]
堆栈中有数据data,也有代码code
你从哪里知道的
[解决办法]
后知后觉的人看了介绍,感觉像exe和com的区别。

[解决办法]
堆栈也用于给函数中使用的局部变量动态分配空间, 同样给函数传递参数和函数返回值也要用到堆栈

这些都是data,而不是用于执行的code
[解决办法]
没错,一般程序是不会在堆栈里放code的。
像比如执行函数或中断,call、int、ret等指令都是将地址信息保存在堆栈里,但是这些都是data,并不是被执行的。C语言传递函数也无需再里面放可执行的东西。比如到函数返回,直接执行ret指令(注意这指令在程序的代码里的,而非堆栈),它直接按照需要将地址读到CS:IP里。返回以后,清除堆栈也只是简单的SP寄存器操作罢了,没有任何需要执行堆栈内代码的必要。
所以系统只需要简单的把堆栈所在的内存页面设置为NX不可执行就OK了。至于那些特殊的程序,比如加密的程序,要么根据需要修改代码,要么可以要求用户关闭DEP,当然这个需要修改BOOT.INI并重新启动才行。

热点排行