首页
社区
课程
招聘
[原创]x64下定位随机页表基址的思路
发表于: 2022-5-14 00:43 8116

[原创]x64下定位随机页表基址的思路

2022-5-14 00:43
8116

昨天在看周哥讲x64内核的时候,得知了windows10的某个版本开始,页表基址不再固定了。
今天晚上突然有了个思路,就动手把他敲出来了,这种思路是不是已经烂大街了我也不确定,就当发出来学习交流吧。

这里用x86的10-10-12分页举例吧,比较好理解,理解了x64的也差不多的

启用了保护模式和分页机制后,咱就不能直接访问物理地址了,都会被cpu当作虚拟地址进行转换。

但是cr3存的又是物理地址,不能直接操作页表了,那咋办呢?

聪明的前辈们,选择在页目录表中选择一项(共1024项,每一项4字节),使其存储的物理地址与页目录表的基址(cr3)相同,这样子就可以构造一个访问页表的虚拟地址了,大概就是让cpu在地址转换的过程中绕圈圈

图片描述

理解有限,如有错误,还请指正

 
 
 
PVOID GetPXTBase() {
    UINT64 cr3 = __readcr3();
    KdPrint(("yuyu:cr3:%p\n", cr3));
    for (UINT64 i = 0; i < 512; i++) {
        // 构造虚拟地址
        PVOID pxtBase = (PVOID)(0xffff000000000000 | (i << 12) | (i << 21) | (i << 30) | (i << 39));
        PHYSICAL_ADDRESS physical = MmGetPhysicalAddress(pxtBase);
        KdPrint(("yuyu:i:%d 物理:%p 虚拟:%p\n", i, physical.QuadPart, pxtBase));
        if (cr3 == physical.QuadPart) {
            return pxtBase;
        }
    }
    return NULL;
}
PVOID GetPXTBase() {
    UINT64 cr3 = __readcr3();
    KdPrint(("yuyu:cr3:%p\n", cr3));
    for (UINT64 i = 0; i < 512; i++) {
        // 构造虚拟地址
        PVOID pxtBase = (PVOID)(0xffff000000000000 | (i << 12) | (i << 21) | (i << 30) | (i << 39));
        PHYSICAL_ADDRESS physical = MmGetPhysicalAddress(pxtBase);
        KdPrint(("yuyu:i:%d 物理:%p 虚拟:%p\n", i, physical.QuadPart, pxtBase));
        if (cr3 == physical.QuadPart) {

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-12-18 12:30 被yuyuaqwq编辑 ,原因:
收藏
免费 5
支持
分享
最新回复 (8)
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
2
思路是对的,并且已经有厂在用了
https://bbs.pediy.com/thread-254276.htm
2022-5-14 00:54
0
雪    币: 263
活跃值: (1979)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
はつゆき 思路是对的,并且已经有厂在用了 https://bbs.pediy.com/thread-254276.htm

谢谢佬回复,这个帖我看过了,还是有点区别的,鹅厂是通过映射cr3来比较的,我这个并没有映射

最后于 2022-11-13 22:57 被yuyuaqwq编辑 ,原因:
2022-5-14 00:55
0
雪    币: 190
活跃值: (21)
能力值: ( LV9,RANK:289 )
在线值:
发帖
回帖
粉丝
4
char __fastcall LocatePteBase()
{
  unsigned __int64 v0; // rax
  __int64 v1; // krB8_8
  __int64 i; // krA0_8
  __int64 index; // rsi
  __int64 v4; // r9
  PHYSICAL_ADDRESS v5; // krA0_8
  unsigned __int64 v6; // krD8_8
  __int64 v7; // krE8_8
  unsigned __int64 v8; // kr30_8
  unsigned int v9; // eax
  char v10; // cf
  ULONG v11; // krB0_4
  void *v14; // rax
  __int64 v15; // r9
  unsigned __int64 VA; // [rsp+44h] [rbp+8h]

  v0 = __readcr3();
  v1 = v0 & 0xFFFFFFFFFF000i64;
  for ( i = 1i64; ; i = index + 1 )
  {
    VA = (i | ((i | ((i | (i << 9)) << 9)) << 9)) << 12;
    index = i;
    v5 = (*(PHYSICAL_ADDRESS (__stdcall **)(PVOID))pfnMmGetPhysicalAddress_0)((PVOID)VA);
    v6 = VA;
    v7 = v4;
    if ( v5.QuadPart == v1 )
      break;
    if ( (unsigned __int64)(index + 1) >= 0x200 )
    {
      SelfAutoIndex = 0i64;
      goto LABEL_11;
    }
  }
  if ( (VA >> 47) & 1 != 0 )
    v6 = VA | 0xFFFF000000000000ui64;
  SelfAutoIndex = index;
  if ( !v6
    || (PteBase = (index << 39) | 0xFFFF000000000000ui64,
        PdeBase = (index << 30) | (index << 39) | 0xFFFF000000000000ui64,
        PpeBase = (index << 21) | PdeBase,
        PxeBase = (index << 21) | PdeBase | (index << 12),
        PxeBase != v6) )
  {
LABEL_11:
    v11 = -536870756;
LABEL_12:
    DbgPrintEx(6, v11, L"\n", v7);
    return 0;
  }
  return 1;
}

来自vgk

2022-5-14 01:39
0
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
5
咋回事儿啊 char&nbsp;__fastcall&nbsp;LocatePteBase() { &nbsp;&nbsp;unsigned&nbsp;__int64& ...
vgk不是基本上全v了,这段咋找到的?
2022-5-14 10:02
1
雪    币: 246
活跃值: (4427)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
6
MmPteBase  不是有这玩意吗
2022-5-14 10:53
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
7
ookkaa MmPteBase 不是有这玩意吗
未导出
2022-5-14 18:33
0
雪    币: 190
活跃值: (21)
能力值: ( LV9,RANK:289 )
在线值:
发帖
回帖
粉丝
8
hzqst vgk不是基本上全v了,这段咋找到的?
全程序vm还原 就像be
2022-5-14 20:39
0
雪    币: 6166
活跃值: (4937)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
9
mark
2022-6-26 02:03
0
游客
登录 | 注册 方可回帖
返回
//