首页
社区
课程
招聘
[已更新!][原创/探讨]Windows 核心编程研究系列之一(改变进程 PTE)
2006-11-1 13:53 18948

[已更新!][原创/探讨]Windows 核心编程研究系列之一(改变进程 PTE)

2006-11-1 13:53
18948
首先要说明的是我一般在汇编区活动,但考虑到客观人气问题,所以发到这里,这篇
文章的目的在于想结识一些有同好的朋友一起探讨,完整包括图片的文章可以到我
的blog(hopy.blogchina.com)观赏。另外如有不如何错误请多多指正,不胜感谢。

Windows 核心编程研究系列之一
-改 变 进 程 PTE 属 性-

    这是我研究windows 核心编程的第一篇正式文章,之所以叫核心编程而不叫
内核编程,是我觉得从字面上来看核心(core)比内核(kernel)更靠近windows中心,
当然只是偶本人的看法的拉。
   
    我们知道在 win NT 中,系统把每个进程的虚拟4G空间分为两大部份,低2G
归用户所有,高2G归系统所有。用户不得访问系统的空间,连读都不行,更别说
写了!

    低2G的用户空间也并不是都能写入的。现在我要说一个特殊的区域:在每个
进程虚拟地址 0x7ffe0000 开始的一段空间称为 USER_SHARED 区域,他和虚拟
地址空间0xffdf0000指向同一物理地址空间,这片区域的长度为 0x2d8。所以不
同进程的这一虚拟地址空间被映射到同一个物理地址空间,如果可以写入该区域
就可以实现系统中所有进程共享数据的目的,注意是所有进程!但可惜的是虽然
0x7ffe0000在低2G的空间,归用户所有,但它只能读不能写,写他的后果如图1所示。
              
                              图1

很不爽哦!我前不久在网上看到一篇可以读写物理内存的文章,其实现的思想是:

1 通过系统特权API取得 System Object PhysicalMemory 的写权限;

2 通过分析 MmGetPhysicalAddress 写出其在 ring3 下的伪代码,
  从而得到任意虚拟地址映射的实际物理地址

3 写入物理地址

    我用汇编重写后好像不能实现其目的,编译运行原来VC++代码也不成功。但据作者
说他可以运行成功。因为这篇文章写得较早,我怀疑是 windows 在后来的PACK中关
闭了这个通道。但只是猜测,也不排除还有我未考虑到的因素,希望搞成功过的朋友
谈谈具体的过程。
               
    我实现的是另一种方法,其主要思想是:

1 找到该虚拟地址在进程页表中的位置;

2 将对应页表项第2位改为1

    每个进程的页表被映射到其虚拟地址空间的 0xc0000000 ? 0xc003fffff 空间中。
经过简单的计算后得到其页表项位置为:0xc0000000 + 0x1FFF80 = 0xC01FFF80 察看
其内容如图2所示,其最低3位决定了它存在,属于用户区域,但是只读不能写入!
               
                                    图2

我们下面要做的也非常简单,就是打开其写入标志,使其可写。
就是将 0x25 改为 0x27 。关键代码如下:

mov        ebx,0c01fff80h
        mov        edx,[ebx]
        mov        al,27h
        mov        byte ptr [ebx],al
        mov        eax,cr3
        mov        cr3,eax

通过一个 kernel driver 注入,修改成功。下面就是在ring3中修改 0x7ffe0080
的内容,以下是代码:

mov        ebx,7ffe0080h
        mov        eax,12345678h
        mov        dword ptr [ebx],eax

    执行结果可以用任意ring3调试器来证实,就是在调试任意程序时察看其进程地址
0x7ffe0080都会发现其值被改为 0x12345678。图3是验证情况。
                    
                                         
                                         图3

到这里貌似可以告一段落了,但是还有更值得挖掘的东西,那就是在ring3种直接改写
高2GB的系统内核区域,下面马上将给出的是就是关于改写0x80000000 ? 0xffffffff
内核区域的方法,敬请期待。

OK,让我们进入这一部分,其实有了上面的基础,这个就变得轻而易举了。但是要注意的是:
1 要改写的 0x80000000 ? 0xffffffff 区域属于内核,可能
搞不要就要ODBS;
2 要修改的不单单是 PTE 还有 页目录表项

现在我们选择写入的位置,上面说过的 0xffdf0000 ~ 0xffdf02d8 是个不错的选择,因为除了开头一段最好别碰以外,后面都是“自由”区域,写入因该没什么问题。我们首先


图4
要确定修改的页目录项的位置,它可以通过 0xc03000000 + 0xffc 算出等于 0xc0300ffc,如图4,将63改为67。然后再找到
页表项的位置,通过 0xc0000000 + 0x3FF7C0 = 0xC03FF7C0,同样的要将63改为67,关键代码为:

mov        ebx,0C0300FFCh
        mov        edx,[ebx]
        mov        al,67h
        mov        byte ptr [ebx],al
        mov        eax,cr3
        mov        cr3,eax
        mov        ebx,0C03FF7C0h
        mov        edx,[ebx]
        mov        al,67h
        mov        byte ptr [ebx],al
        mov        edx,[ebx]
        mov        eax,cr3
        mov        cr3,eax
       
That’s All Right !!!,让我们看下实际的效果,如图5所示。

图5

至此我们已经成功地在ring3中修改了用户区只读区域,和位于内核的“不可见”区域。呵呵,西游记至此终~真的终么?当然只是joke了,呵呵。

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

收藏
点赞7
打赏
分享
最新回复 (27)
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2006-11-1 13:55
2
0
在我的2个博客都可以看到:

http://blog.csdn.net/mydo

htto://hopy.blogchina.com

希望感兴趣的各位多多发表高见
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
prince 16 2006-11-1 14:36
3
0
我支持先~ 学习学习!
雪    币: 625
活跃值: (1057)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
xzchina 1 2006-11-1 15:40
4
0
学习!!!
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
北极星2003 25 2006-11-1 20:38
5
0
最初由 prince 发布
我支持先~ 学习学习!


prince, 你想什么就来什么
雪    币: 214
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
colboy 2006-11-1 20:46
6
0
好像真的很强阿!!!!!!!!!!
雪    币: 441
活跃值: (149)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
rockhard 4 2006-11-2 01:14
7
0
先做个标记,天亮后进来再学习。
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
firstrose 16 2006-11-2 08:18
8
0
直接动页表。不错的实现。还以为这条路早被win封了呢
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
prince 16 2006-11-2 09:58
9
0
最初由 北极星2003 发布
prince, 你想什么就来什么


呵呵,人品好啊~
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
prince 16 2006-11-2 10:06
10
0
最初由 firstrose 发布
直接动页表。不错的实现。还以为这条路早被win封了呢


在driver中手动定位PTE,修改,这没法儿封吧?
雪    币: 441
活跃值: (149)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
rockhard 4 2006-11-2 12:04
11
0
现在有不少办法可以让程序时入ring0,
进入ring0后要改什么就很简单了。
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2006-11-3 12:34
12
0
各位好,见我帖子中的部分,各位对于通过改写物理内存的写权限来达到写物理内存的办法,有没有成功过的?
雪    币: 70
活跃值: (64)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
yiyiguxing 1 2006-11-3 21:49
13
0
又学着新东东了  顶!
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2006-12-22 13:51
14
0
多谢各位!
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
shoooo 16 2006-12-22 19:39
15
0
csdn的强人啊, 膜拜+学习+收藏
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 30 2006-12-22 20:18
16
0
牛人来了

我想修改进程pte,另外分配一块内存替换原来的KUSER_SHARED_DATA,再提供个ring3访问的接口,就可以自己来更新时钟数据,这样做以后时常因pfn list损坏蓝屏,请高人指点一二
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2006-12-22 20:33
17
0
高人不敢

我想问一下:
0 你将原来KUSER_SHARED_DATA所在页的PTE中的
  物理页基址改变了么?

1 你会修改KUSER_SHARED_DATA偏移多少的数据?
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 30 2006-12-22 21:20
18
0
没有修改物理基址,ring0偶不懂

我想绕过利用检查运行时间来anti-debug的手法。这种代码直接模仿GetTickCount或类似的api从KUSER_SHARED_DATA读取数据,难以用hook某个api的办法来解决。所以我想自己搞1页来换掉该页,给程序假的时间(更缓慢地更新数据)。页里其他的内容copy过来就行。

修改的大概是:
+0x000 TickCountLow     : Uint4B
   +0x004 TickCountMultiplier : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
      +0x000 LowPart          : Uint4B
      +0x004 High1Time        : Int4B
      +0x008 High2Time        : Int4B
   +0x014 SystemTime       : _KSYSTEM_TIME
      +0x000 LowPart          : Uint4B
      +0x004 High1Time        : Int4B
      +0x008 High2Time        : Int4B
   +0x020 TimeZoneBias     : _KSYSTEM_TIME
      +0x000 LowPart          : Uint4B
      +0x004 High1Time        : Int4B
      +0x008 High2Time        : Int4B

大概是这里的,记不大清楚了。以前是乱试的,我感觉这想法是可行的,但不会正确地实现。那些代码就不拿来现眼了。

因为进程加载时这里已经映射了内存,感觉应先释放原来的,再另外分配1页映射到这个地址。
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2006-12-25 19:09
19
0
如果你的数据覆盖或复写了KUSER_SHARED_DATA中的某些
部分,会像你所说的发生蓝屏现象。按你所说,好像蓝屏
没有规律性,还有一种可能,就是你在新建一个pte时可能
没有保存以前的属性,如果以前没有使用则不会有问题,但是
若相反,就会在以后用到该pte属性时发生蓝屏。

以上只是猜测,因为没有实际测试环境调试。说得不好请
包涵。
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 30 2006-12-26 12:57
20
0
谢谢答复,的确是没有规律性,一般在开了多个程序时蓝屏,当时感觉需要修改页帧号链表上的数据。

有时间我再试试
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
xIkUg 9 2007-1-5 23:07
21
0
最初由 softworm 发布
牛人来了

我想修改进程pte,另外分配一块内存替换原来的KUSER_SHARED_DATA,再提供个ring3访问的接口,就可以自己来更新时钟数据,这样做以后时常因pfn list损坏蓝屏,请高人指点一二


我试了一下,确实有问题。。。
我是在进程创建的时候分配了一块内存,把原来的KUSER_SHARED_DATA内容复制过去,然后替换原来的KUSER_SHARED_DATA。。。

不过我的不会蓝屏。。。而是提示我STATUS_INVALID_IMAGE_FORMAT。。。目前还没找到原因。。。初步估计应该是进程还没有完全创建完成所致。。。

回头再研究研究。。。
雪    币: 625
活跃值: (1057)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
xzchina 1 2007-1-9 15:05
22
0
图一的图片不能显示了.
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2007-1-13 19:19
23
0
已经解决在ring3中读写物理地址的问题(不借助驱动),其实
也算老生常谈了。通过注册一个callgate即可实现ring3中
无驱进入ring0,即可为所欲为了:)

会开新贴谈谈细节,先预告一下,呵呵。
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2007-1-14 21:07
24
0
是图床出了问题,谢谢 xzchina  细心.准备找机会重传一张
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 8 2007-2-28 20:01
25
0
向大家申明一下:

很多朋友看了本人的拙作后,给我发电子邮件询问细节,虽然
我都作了回应,但是最好还是QQ或msn联系比较方便:

qq:411987378
msn:kf2b@hotmail.com

谢谢大家支持!

侯佩|hopy
游客
登录 | 注册 方可回帖
返回