个人 企业
用户名:
密码:
 
企业服务   安全学院   安全资讯
安全动态  |  前沿技术  |  黑客防范安全漏洞防毒杀毒编程技术安全案例 |  电子政务产品推荐网管技术安全采购产品测评在线代理OICQ
检测评估安全学院软件下载互动交流安全沙龙应急咨询技术认证安全人才技术社区嘉宾聊天安全调查
  资讯 频道 技术    

一分钟注册享受免费网站安全评估

新闻热点

美国谋划夺取全球“制网权”
攻击指定IP地址及端口的黑客病毒
“黑客”三天侵吞21万获刑11年
微软浏览器IE7被发现存在两个漏洞
黑客入侵万达广场网站 提醒修复漏洞

软件热点
完美卸载V2007 完整版
防黑菜鸟必学系列视频教程
c语言视频教学30讲第14讲
黑客攻防绝招之三十六计
redhatlinux9安装的全程录像
IIS6最佳安全性实战
   
 
什么是虚拟地址
时间:2006-11-17 16:09:42 作者:sec120.com  出处:陈十三哥
一. 地址的本质    
           
前言:
本文旨在加强理解,实际情况并非如此。这是简化版。
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,也就是是否映射。

 

评论 | 收藏 | | 打印 | 关闭

相关新闻链接
     
关于Sec120 | 服务产品 | 联系我们 | 招贤纳才 | 广告服务 | 网站律师 | 网站地图 | 我要投稿

 

互联安全网  粤ICP备06118359 Copyright 1999-2009 All Right Reserved.