1、10-10-12分页
在XP系统创建一个记事本文件,输入字符串Hello WorddADDDDD,通过CE找到该字符串的线性地址0106D8F8。
拆分线性地址: 0106D8F8
0000 0001 0000 0110 1101 8F8
0000 0001 00 -> 4*4 -> 10
00 0110 1101 -> 6D*4 -> 1B4
8F8
记事本进程notepad.exe的CR3: a3e05000
PDE = CR3 + 10 = a3e05010 -> [a3e05010] == 947b9867
基址: 947b9000
属性: 867
PTE = PDE.base +1B4 = 947b91b4 -> [947b91b4] = 1ce34867
基址: 1ce34000
属性: 867
物理地址 = PTE.base + 8F8 = 1ce348f8 -> 存储的字符串:Hello WorddADDDDD
2、实验
2.1 使得R3下的NULL地址能被读取到指定的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
int
main(
int
argc,
char
* argv[])
{
int
* ptr = 0;
int
x = 111;
printf
(
"x的线性地址是:%x\n"
, &x);
getchar
();
*ptr = 12345;
printf
(
"%d\n"
, *ptr);
return
0;
}
|
拆分地址: 0x0
CR3: a0ff6000
PDE = CR3 + 0 = a0ff6000 -> [a0ff6000] == a5c55867
PTE = PDE.base + 0 = a5c55000 -> [a5c55000] == 00000000
拆分地址: 0x12ff78
0000 0000 0001 0010 1111 f78
0000 0000 00 -> 0*4 = 0
01 0010 1111-> 12F*4 = 4BC
F78
CR3: a0ff6000
PDE = CR3 + 0 = a0ff6000 -> [a0ff6000] == a5c55867
PTE = PDE.base + 4BC = a5c554bc -> [a5c554bc] = a525b867
将变量x的PTE值复制到ptr的PTE当中
恢复程序
该实验存在一个问题:
当通过windbg将x的PTE挂载到空指针ptr后,直接访问*ptr的值是一个未知数,为什么不是变量x的值123,而通过*ptr = 12345语句后*ptr的值变成了12345
问题分析:
当没有挂载PET时,直接访问*ptr时会报访问异常错误,说明此时ptr的PET还没有指向一个有效的物理地理
当挂载PET后,直接访问*ptr获得到一个未知数,说明这个时候已经拿到了物理地址上的一个随机值了
这说明ptr和x的物理地址不是同一个,所以ptr的值 != x的值
分析线性地址找到物理地址的流程后发现,ptr和x的PTE相同,但是PTE.base + 偏移 = 物理地址,二者的偏移不同导致了物理地址不一样
解决办法:
构造出一个物理地址偏移与空指针ptr相同的线性地址,再将该线性地址的PTE挂载到ptr就可以使得二者指向同一块物理地址
构造线性地址:0x0012F000
0000 0000 00 -> 0
0100 1011 11 -> 12F
000 -> 0 物理偏移
通过VirtualAlloc函数指定分配的地址即可
2.2 通过修改物理页属性使字符串常量可修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
int
main(
int
argc,
char
* argv[])
{
char
* str =
"Hello World"
;
printf
(
"线性地址:%x"
, str);
getchar
();
str[0] =
'A'
;
printf
(
"修改后的值:%s\n"
, str);
return
0;
}
|
线性地址:0x00423044
0000 0000 01 -> 1*4 = 4
0000 1000 11 -> 23*4 = 8C
044
更多【10-10-12分页】相关视频教程:www.yxfzedu.com