一般来说,我知道一个进程无法写入具有不允许写入的保护的内存(在其地址空间中)。但是什么检查进程是否可以做到这一点?是否有任何汇编指令通过操作系统?它是如何工作的?
3 回答
在大多数现代 CPU(Intel x86,大多数 ARM 版本)中,是 CPU 本身进行检查。CPU 在其中一个寄存器中存储数据结构的地址,该地址指定存储器的布局(“页表”)——具体来说,哪些地址是可读的,哪些是可写的,哪些是可执行的。CPU 中的每个内存访问操作都会根据页表进行检查。
当程序尝试对相应页表条目不允许的内存位置执行某些操作时,CPU 会生成异常(中断),并且操作系统会获得控制权。进一步的操作取决于操作系统。一种常见情况涉及操作系统显示错误消息并终止有故障的程序。不过,不一定。例如,页面交换(将内存写入磁盘上的页面文件并在需要时回读)通过相同的机制实现。
页表由操作系统维护,并且(通常)对用户代码不可见。操作系统中的相关部分取决于硬件。
页表,它们包含当前执行进程的内存空间的所有信息。当您尝试通过写入来访问只读内存或访问不属于您的内存时,处理器无法找到映射(或看到您无法写入)并向操作系统发出页面错误. 然后操作系统决定它是否是写入页面上的副本,您访问的页面是否完全属于您但尚未映射,或者您是否只是访问了坏空间并相应地处理它(通常会以段错误杀死进程如果您访问不良空间)。
当硬件支持这一点时,通常在描述分配的内存块的信息中会有一个位,指示是否可以执行该内存块。
在 Intel 处理器上,这称为 NX(从不执行)位,而 AMD 称为 XD(禁用执行)位。
NX 位特指页表中64 位条目的第63 位(即最高有效位)。如果该位设置为 0,则可以从该页面执行代码;如果设置为 1,则无法从该页面执行代码,并且假定存在于该页面的任何内容都是数据。
http://en.wikipedia.org/wiki/NX_bit
该位由操作系统在将可执行代码加载到内存后设置。它只能由特权代码(例如操作系统或驱动程序)设置。
也可以看看: