avatar

Catalog
基址小实验(10-10-12)

在学习完页目录表基址,页表基址后,我们知道通过C0300000和C0000000这两个地址,可以访问相应的PDE和PTE,今天就来实践一下。

之前在介绍PDE/PTE属性R/W位时有过一个实验,是对位于常量区的内容进行修改,当时通过Windbg修改了所在PDE/PTE的R/W位。这次实验,我们利用页目录表/页表基址来进行修改。

测试原始代码

首先测试原始代码,发现直接修改常量区的字符串,是会失败的

提权进入0环

提权这里还是会用到Windbg,根据调用函数的地址,填入段选择子,并通过调用门进行提权(就当复习调用门知识了)

修改R/W位

提权进入0环后(为啥要提权呢?因为C0300000/C0000000都属于高2G的线性地址,3环没法直接访问),就到了我们最关键的步骤了,修改R/W位。

c
1
2
3
4
5
6
temp = *(int*)0xC0300004;
temp = temp|0x2;
*(int*)0xC0300004 = temp;
temp = *(int*)0xC000108C;
temp = temp|0x2;
*(int*)0xC000108C = temp;

在这之前声明了一个中间变量temp(int类型)。

具体步骤:

  1. 打印出字符串所在常量区的地址0x423fb0,进行拆分:10-10-12 -> 0x1-0x23-0xfb0
  2. PDI = 0x1,带入公式:PDE = C0300000 + 0x1 x 4
  3. PTI = 0x23,带入公式:PTE = C0000000 + 0x1 x 1000 + 0x23 x 4
  4. 分别取PDE和PTE处的值,并和0x2进行或运算(将R/W位置1)

这样就完成了对R/W位的修改,在接下来再次对常量区的值进行修改操作时,便可以成功。

完整代码

c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "stdafx.h"

int temp;

__declspec(naked) void ModifyRW() {
__asm {
pushad
pushfd
}
temp = *(int*)0xC0300004;
temp = temp|0x2;
*(int*)0xC0300004 = temp;
temp = *(int*)0xC000108C;
temp = temp|0x2;
*(int*)0xC000108C = temp;

__asm {
popfd
popad
retf
}
}


int main(int argc, char* argv[])
{
char* str = "hello";
char buffer[6] = {0, 0, 0, 0, 0x4B, 0};
printf("addr: %x, str: %s", str, str);
getchar();

_asm {
call fword ptr buffer
}
*str = 'a';
printf("str: %s", str);
getchar();
return 0;
}
Author: cataLoc
Link: http://cataloc.gitee.io/blog/2020/03/20/%E5%9F%BA%E5%9D%80%E5%B0%8F%E5%AE%9E%E9%AA%8C/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶