前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >x86分页复习之10-10-12分页

x86分页复习之10-10-12分页

作者头像
IBinary
发布2020-11-11 16:16:57
1K0
发布2020-11-11 16:16:57
举报
文章被收录于专栏:逆向技术

目录

x86保护模式 10 - 10 - 12分页模式

一丶x86 10 - 10 -12分页

1.简介

之前有说过x86保护模式下的分页.这里为了复习再说一遍,在这里可能为了简单介绍会遗漏些许.所以贴出之前的保护模式分页机制资料

https://cloud.tencent.com/developer/article/1998771

https://cloud.tencent.com/developer/article/1998773

https://cloud.tencent.com/developer/article/1998786 内存读

2.x86分页之线性地址

​ CPU提供了段的机制来进行内存保护,而我们学习保护模式的本质也是学习windows如何保护内存的. 微软没有使用段的机制

而是直接使用的页的机制.

例如:

代码语言:javascript
复制
0x00401000  mov eax,[0x12345678]

在虚拟地址执行汇编指令的时候本质是去GDT表中查段描述符表.然后从段描述符表中取出 段.base + 上偏移来进行定位内存的.

在讲解段之前已经说过了.但是我们知道操作系统在x32下.就没有使用段了.设置段.base都是0.

所以段.base(0) + 偏移就是线性地址.

而x32下内存保护模式就是先把逻辑地址(俗称虚拟地址)转为线性地址再去查表.

其实如果你学过C语言或者其它高级语言那么下面说的就很清楚了. 其实保护模式的本质就是查表. 也就是数组来保存地址的.

一个数组中保存了另一个数组的首地址. 另一个数组的首地址就保存了物理地址. 只不过有些许属性而已.

3.x86分页之寻址简介

上面说了.我们需要的数据都会在内存中.而且是查表得来的.所以在windows内核中有一个寄存器保存的是我们的物理地址.

这个寄存器就是CR3寄存器.而每个进程都有一个物理地址.也称为DirBase 这个DirBase是记录的每个进程的物理地址起始地址的.

看下图:

通过CR3查询页目录表(也就是我所说的第一个数组) 然后数组中记录着另一个数组的起始地址(页表) 页表中记录着就是物理页所在的内存了.

每个页表是4kb大小(4096个字节) 也有的是4MB大小.如果判断是4MB的大小,这个就要等到后面学的属性位了.

在这里我们先按照4kb 10-10-12分页来进行讲解.后面会把双机调试的配置图贴出.便于自己的私下调试.

二丶x86下10-10-12分页寻址实战

2.1 地址转化为索引

既然要看虚拟内存所在的物理页在哪里,那么第一步就是将虚拟内存(逻辑地址)转为线性地址. 但是我也说过了x32下没有使用段.所以虚拟内存就是线程地址了.

转换之后按照10-10-12来进行分位. 10-10-12的意思就是一个线性地址有32bit(位) 我们按照 10-10-12来将这个32bit位进行分组,然后转为10进制.高位10个二进制代表查询页目录表的索引. 第二个10位代表查询页表的索引.

例如:

步骤

数值

说明

1.确定要看的逻辑地址(线性地址)

0x00401000

我们要看的线性地址在物理页中哪里保存

2.线性地址转换为对应二进制位

00000000010000000001000000000000

第二步就是转为32位bit.然后下一步我们就分组

3.二进制按照10-10-12分组

0000000001 0000000001 000000000000

这个是分组后的数值

4.二进制分组转为索引

1 1 0

确定了页目录表是在第一项 页表也是第一项

所以有时候大家调试程序多的时候对0x00401000很熟悉.而内核中PDE PTE也是第一项.

2.2 10-10-12内存寻址实战

​ 既然明白了原理,那么我们就可以看任一进程中的线性地址所在的物理页了. 当然也可以进行更改. (后面会说)

首先我们要把起始地址拿到手. 我们的CR3寄存器记录的是物理地址,但是这个物理地址不是我们要查看的进程内的.当然每个进程当使用的时候,CR3都会切换为这个进程的CR3(物理地址起始位置)这里我们先不说如何切换.直接使用进程中的物理地址.

首先VC6.0写了个程序,调用VirtualAlloc申请一块内存.然后内存中填写为HelloWorld 而且地址也输出了.

那么我们就要看这个地址在物理内存哪里进行存放.

我们的进程名是1.exe

windbg使用 !process 0 0 来查找我们的进程

确认了我们的物理地址是 0x19b87000 下一步就是将我们要看的虚拟地址进行索引转化

0x3a0000 转化出来的索引为: PDE(页目录表) 0 PTE(页表)3A0

利用windbg的物理内存查看命令进行查看. 查看的时候记住 PDE PTE中的低12位为属性位.如有有值我们不用管.暂时填充为0进行查询.

当PTE查询之后,别忘了加上原来你要查看的虚拟地址的12位. 也就是我们所说的 10-10-12 10-10当索引 12当数值

最终查询出了HelloWord所在的地方.

明白了其原理我们则可以编写代码来实现自己的内存读函数了.

这里说下思路:

1.内核中遍历进程,或者ring3传入进程到内核.

2.内核中通过进程Pid找出对应的EPROCES结构 (PsLookupProcessByProcessId)

3.通过EPROCESS结构找到其DirBase的偏移.获取其偏移位置的DirBase的物理地址

4.通过10-10-12分页的模式,拆分传入的你想查看的这个进程的任一虚拟地址.

5.通过上述实际操作的原理,进行自己读取内存.

三丶winxp x86下10-10-12分双击调试设置

修改bootini进行设置即可.

代码语言:javascript
复制
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="10-10-12" /execute=optin /fastdetect /debug /debugport=com1 /baudrate=115200

其实主要就是 将noexecute 修改为 execute 并且添加了调试端口. 这里设置的是com1

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-11-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • x86保护模式 10 - 10 - 12分页模式
    • 一丶x86 10 - 10 -12分页
      • 1.简介
      • 2.x86分页之线性地址
      • 3.x86分页之寻址简介
    • 二丶x86下10-10-12分页寻址实战
      • 2.1 地址转化为索引
      • 2.2 10-10-12内存寻址实战
    • 三丶winxp x86下10-10-12分双击调试设置
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档