Note
  • Introduction
  • PWN
    • __libc_csu_init函数的通用gadget
    • _int_malloc源码分析
    • _IO_FILE利用思路总结
    • C++ 虚表分析
    • Fast_bin笔记
    • house_of_force
    • House_of_Roman
    • Linux_ShellCode
    • Return-to-dl-resolve原理及利用
    • Unlink利用原理
    • Unsorted_Bin_Attack
    • 获取libc方法
    • 利用main_arena泄露libc基址
    • 整数溢出
    • 重写.fini_array函数指针
    • Windows_SEH利用
  • Windows_Operating_System
    • Dll隐藏
    • Dll注入之远程线程注入
    • IAT_HOOK原理实现
    • Windows下通用ShellCode原理
    • 代码注入
    • inline_hook框架
    • 32位程序调用64位函数原理
    • 调试原理
    • Windows异常处理初探
    • Windows_SEH利用
  • Windows_Kernel
    • MSR_HOOK
    • SSDT_HOOK
  • Virus_Analysis
  • Program
    • Dll的生成与使用
  • Miscellaneous
    • ctf笔记
    • 常见算法特征总结
    • ELF文件笔记
  • Linux_Operating_System
    • 系统调用
    • 分页机制
    • 调试原理
    • linux无文件执行elf
    • egg hunter
    • 缺失的动态链接库
  • Linux_Kernel
    • KERNEL_PWN状态切换原理及KPTI绕过
  • IOT
    • IOT调试环境搭建
    • mips_arm汇编学习
    • Cisco RV160W系列路由器漏洞:从1day分析到0day挖掘
  • Symbolic_Execution
    • angr初探
    • angr_进阶
  • Fuzz
    • UAF_overflow_check
    • intel-pin
  • CVE
    • Cisco RV160W系列路由器漏洞:从1day分析到0day挖掘
  • Assembly
    • Junk_Code_Analysis
    • opcode
  • Andriod_Security
Powered by GitBook
On this page

Was this helpful?

  1. Linux_Operating_System

分页机制

Previous系统调用Next调试原理

Last updated 5 years ago

Was this helpful?

先说说最基本的未开启PAE时的10-10-12分页 (PDE为页表地址,PTE为物理页地址)

CR3存有页目录表的物理地址,页目录表有1024项,存有页表的物理地址,每张页表有1024项,存有物理页的地址。由于系统的内存通常都是按照4kb对齐,所以页目录表和页表中的地址的低12位都是保留位,另做他用。

但其实上面这种结构方式是错误的,正确的的结构方式是这样的:

其实页目录表(PDT)本不存在,是抽象出来的.

  • 页表被映射到了从0xC0000000到0xC03FFFFF的4M地址空间

  • 在这1024个表中有一张特殊的表:页目录表

  • 页目录被映射到了0xC0300000开始处的4K地址空间

所以我们就能根据线性地址计算所在物理页地址

访问页目录表的公式: 0xC0300000 + PDI*4

访问页表的公式: 0xC0000000 + PDI*4096 + PTI*4

(PDI为页目录表偏移是线性地址高10位,PTI为页表偏移是线性地址的高12-21位)

但本次实验环境 win7 x86 默认分页方式为 2-9-9-12分页,四页式。

根据 CR3 找到 Page Directory Pointer Table
根据一级索引在 Page Directory Pointer Table 中查询到 Page Directory
根据二级索引在 Page Directory 中查询到 Page Table
根据三级索引在 Page Table 中查询到普通 4KB 物理页
在物理页中查找第四段偏移。

如下图:

根据以上描述,第一段索引其实就是 Page Directory Pointer Table(PDPT) 这张表的索引。 下面的彩图也许能帮助你理解。

这种分页方式不同于三段式,三段式分页最大只支持4GB内存寻址,intel把处理器的管脚数从32位增加到36个满足了更大的内存需求。

三段式分页中的 PDE 和 PTE 都是 4 字节,无论是 PDT 还是 PTT 都有1024个表项。而PAE分页中,PDPT只有 4 个表项,PDT 和 PTT 有 512 个表项,PDPTE、PDE、PTE 的大小是 8 字节。 PDPT 表一共占用 32 字节,PDT 、PTT 表仍然占用 4KB 的物理页。

这里列出它的PTE结构图:

PTE结构的低12位同三段式分页仍然是属性,唯一的区别就是,Page Base Address 由原来的 20 位变成了现在的 24 位,相对以前扩展了 4 位。注意从 36-63 位这28位是保留位,不可用的。

这意味着,PTE 可以索引到的物理页页号由原来的 2的20次方 变成现在的 2的24次方,同样的,一个物理页大小是 4KB,那么PTE可以索引到的最大物理地址将会达到 2^24 * 2^12 =64GB。

其实,PAE 所做的事情,只是把线性地址的 4GB 虚拟空间打散到了物理地址的64 GB 空间中。

形如图:

这里就直接给出该分页模式下 PDE 和 PTE 地址计算公式

addr 存放的是线性地址

pPDE = (int*)(0xc0600000 + ((addr >> 18) & 0x3ff8));
pPTE = (int*)(0xc0000000 + ((addr >> 9) & 0x7ffff8));