地址的本质

前言:
本文旨在加强理解,实际情况并非如此。这是简化版。

1. 基本概念
虚拟地址=逻辑地址=[段选择子]:[线形地址],利用段选择子找到描述符,描述符有字段表示段的基
地址(在Win32中都是0,所以线形地址就是真正地址)还有字段表示段属性,实际上起到保护作用。
事实上,在Win32中,其他地址已经不重要了。关键还是线形地址。
我们在程序中使用的都是线形地址,我们完全可以忘记虚拟内存的概念,认为每个进程确实具有4G的
物理内存,OS和CPU屏蔽了这个细节。不考虑它,也不会影响病毒的编写。程序在执行时,cpu会将我们
使用的地址(可能是硬编码或寄存器)转换为物理地址。

2. 虚拟内存原理
但是,喜欢探索本质的人还是想了解细节,下面形象的解释一下:
1)硬件时钟中断,转中断处理程序,程序进行一些必要工作后,取出调度程序的pcb(进程控制块),
设置寄存器数值,调度进程得到运行,按照某中算法选择一个进程P执行。cpu切换为P的环境。
与寻址关系最密切的是eip和CR3.
CR3的内容是物理地址,这在寻址过程中是很特殊的,因为Win32在保护模式下,感觉上都是虚拟地址,
但是,如果真的都是虚拟地址,可就真的没办法定位到物理内存了。
cpu对以上发生的事一无所知,只是根据eip的值一条一条的执行。
此时访问的地址就是P的4G空间,执行P的指令。
如何实现的呢?关键是页表。
2)映射的本质
内存通过主板连接到cpu,之间有一个MMU部件(Memory Management Unit),cpu执行时,把eip高20
位作为一个索引,再将[index+CR3]的作为高20位,eip的低12位作为低12位组合在一起,形成新的32
位地址,这就是物理地址.
把页表想象成一个数组,个数为2^20(1M),大小为4M,页表当然存储在物理内存中,CR3就是数组首地址。
数组的每一项为一个DWORD,双字的前20位表示一个物理页面。形象地:
 
页号(0~19) ...页属性 保留(30) 提交(31)
CR3 --> 00100 rw 1 1
01001 r 1 0
01010 0 0 0
00111 0 0 0
...
10011 0 0 0

这表明,物理内存的第4个物理页面提交,第9个保留.
每个进程都含有这样一个页表,其中的页号可能一样,就是对应相同的物理页面,比如内存映射文件。
此时一个进程修改的数据,其他进程访问时也会改变。每个进程都有4G的内存可以使用,只是很多页面
没有提交而已,这就是每个进程有4G的原理。
再来想象,当我们使用VirtualAlloc请求4k内存时。
VirtualAlloc(0,4*1024,PAGE_READWRITE,MEM_RESERVE or MEM_COMMIT)
函数内部搜索页表,找到第一个空闲页,这里是01010h,根据参数设置相应项,如果没有MEM_COMMIT,
则‘保留’设为1,‘提交’为0,就是这个原理。
那么,VirtualFree就不言而喻了。
在看看MapViewOfFile,就是把文件从硬盘读到物理内存页面M中,比如M=00111h,这一项在页表中的
索引等于3,再加上页内偏移000h,返回00003000h (pMapping=00003000h),以后用这个值访问这块内
存,如何访问,则会访问到00111h这个物理页面,前面已经说了,自己可以分析一遍。
那么UnmapViewOfFile的作用相反了。
所谓映射,简单的说,就是将页表项的保留和提交设置为1而已。
解除映射则置0。
解除后,再使用pMapping(线形地址)访问内存时,找到页表相应项,发现此页面没有保留,就会发生
内存错误。 值得注意的是,即使使用MapViewOfFile,页表中‘提交’字段也未必是1,只是作了保留
标志,其他函数请求内存时就不会重复分配了,真正访问这个页面时再产生页错误而真正分配物理页。

3. 应用
自删除程序就是一个典型例子。
为什么要在堆栈中执行,而不是直接在代码段写呢。因为如果这样写,那么执行UnmapViewOfFile后,
页表相应项(保留)置0,下一条指令就会发生内存错误。可是,如果把代码放在堆栈中,exe映射虽然解
除,但堆栈对应的页表项仍在,所以可以继续执行,当然,也可以动态分配内存,将删除代码拷贝其中来
执行,原理一样了,归根结底,就看页表的保留位是否是1,也就是是否映射。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值