随笔

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  2 随笔 :: 0 文章 :: 0 评论 :: 0 Trackbacks
     MS中的内存管理以进程为单位,每个进程都有4G的空间,从操作系统原理可得逻辑地址到物理地址之间是以CR3做选择子,与逻辑地址的高十位相加得到页目录的地址,在以次高十位做索引,从页目录中得到页表的地址,在加上12位偏移量就可得到物理地址.
      但在WINDOWS中,每个进程的页目录项总是被映射在0xC0000000到0xC03FFFFF的逻辑地址中,因此,如果在用户层的当前进程地址空间中求已知地址的页表项将变得简单,只需从0XC0000000开始以高十位作为索引移动到对应的页目录项,在以次10位为索引就可以找到页表项的地址,有了这个,我们就可以修改这一些的控制信息,比如把只读改为可写,绕过COPY ON WRITE机制等等..当然以上之所以方便都是以逻辑地址为操作单位的.
上面的公式整理一下就可得:
假设地址为VA

PPTE=0xC000000 + (VA>>22)*PAGE_SIZE + (VA&0x003FFFFF) >>12
         =(VA >> 10) & 0xFFFFFFFC + 0xC0000000
         =   (VA >> 12) << 2 +0xC0000000
因此我们可以直接定义一个宏,从而在我们要修改我们要访问的页属性时更加方便
#define GET_PTE(VA)    ((VA >> 12 ) * 4 +0xC0000000)
当我们要将自己的代码插入别人的地址时,仅仅需要 *(PUCHAR)(GET_PTE(VA)+3) |= 2 就可以把该页的ReadOnly去掉
posted on 2008-04-16 14:10 A-Yu 阅读(471) 评论(0)  编辑 收藏 引用 所属分类: 底层开发

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理