我们这次来根据dump动手来实际转化一个虚拟地址到物理地址,此次的地址不是线性地址映射。
Target_Address_|________________logical|_physical______________|
| C:FFFFFF8008015000| A:C549F000
上面0xFFFFFF8008015000就是虚拟地址,而我们努力的方向就是物理地址:0xC549F000。 让我们朝这个方向一路高歌吧。
转化之前先确认的是此地址是属于用户空间还是内核空间。
很明显我们需要转化的地址是属于内核空间的,则首先需要确认init_mm→pgd的值,它来了
init_mm = (
mmap = 0x0,
mm_rb = (rb_node = 0x0),
vmacache_seqnum = 0x0,
mm_rb_lock = (raw_lock = (cnts = (counter = 0x0), wlocked = 0x0, __lstate = (0x0, 0x0, 0x0), wai
get_unmapped_area = 0x0,
mmap_base = 0x0,
mmap_legacy_base = 0x0,
task_size = 0x0,
highest_vm_end = 0x0,
pgd_=_0xFFFFFF9B4FCA7000 -> ( //虚拟地址
pgd = 0x000000017AC05003), //虚拟地址里面的值
mm_users = (counter = 0x2),
mm_count = (counter = 0x1),
前期条件:
PGD_Index = 虚拟地址>>30位 = (0xFFFFFF8008015000 >>30)&(0x200-1) = 0
PGD_entry_virt = 0xFFFFFF9B4FCA7000 + 0*8 = 0xFFFFFF9B4FCA7000
PGD_entry_phy = rd(0xFFFFFF9B4FCA7000) = 0x000000017AC05003
PMD_Index = 虚拟地址 >> 21位 = (0xFFFFFF8008015000 >>21)&(0x1ff) = 0x40
PMD_entry_virt = 0x000000017AC05003 + 0x40 * 8 = 0x000000017AC05000 + 0x40 *8 = 0x17AC05200
PMD_entry_phy = rd(0x17AC05200) = 0x17AC06003
PTE_Index = 虚拟地址 >> 12位 = (0xFFFFFF8008015000>>12)&(0x200-1)=0x15
PTE_entry_virt = 0x17AC06003 + 0x15 * 8 = 0x17AC06000 + 0x15*8= 0x17AC060A8
PTE_entry_phy = rd(0x17AC060A8) = 0xE00000C549F793
pfn = 0xE00000C549F793 >> 12 = 0xC549F
物理地址 = 0xC549F000 + 0x000 = 0xC549F000
上面之所以需要清空低12位,还有index*8都是因为页表的低12位存储着一些flag,这些flag如下,比如T32