2010年01月02日 21:21

玩过Shadow SSDT Hook的都知道,在System进程中是无法访问win32k.sys的内存空间的,要想访问必须切换到csrss进程或者任意一个GUI进程。
问题一:为什么System进程里无法访问win32k.sys呢?
某同学的说法,"在System进程和非GUI进程里,win32k.sys被页换出了,所以无法访问"
win32k.sys作为GUI服务例程的载体,NtGdiXxxx,NtUserXxxx等GUI服务例程调用极其频繁。
所以,不管使用何种页置换算法,win32k几乎都不可能被页换出,因为它的使用频率太高了
真正的原因是因为win32k所占用的地址范围在System进程的页目录中没有相应的描述,也就是对应的PTE是无效的
下面来观察之:
先取得win32k.sys的地址:

可以知道模块地址为bf800000
下面切换到System进程空间:
kd> dt _EPROCESS 823a7660 ImageFileName
ntdll!_EPROCESS
   +0x174 ImageFileName : [16] "System"
kd> .process /i 823a7660 
kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
80527da8 cc              int     3
kd> db bf800000
bf800000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800020 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800030 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800040 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800050 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800060 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800070 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
kd> !pte bf800000
               VA bf800000
PDE at 00000000C0602FE0    PTE at 00000000C05FC000
contains 0000000000000000
可以看到win32k无法访问,而且PTE是无效的。
切换到csrss.exe看看:
kd> dt _EPROCESS 8235ada0 ImageFileName
ntdll!_EPROCESS
   +0x174 ImageFileName : [16] "csrss.exe"
kd> .process /i 8235ada0 
kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
80527da8 cc              int     3
kd> db bf800000
bf800000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
bf800010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
bf800020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
bf800030 00 00 00 00 00 00 00 00-00 00 00 00 e0 00 00 00 ................
bf800040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
bf800050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
bf800060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS 
bf800070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
kd> !pte bf800000
               VA bf800000
PDE at 00000000C0602FE0    PTE at 00000000C05FC000
contains 00000000047BB063 contains 0000000005AA8221
pfn 47bb ---DA--KWEV    pfn 5aa8 C---A--KREV
清清楚楚,就是PTE的问题。由于System进程中该地址的PTE无效,使得我们明明知道这个地址,但就是无法访问。
问题二:为什么一定要切换到一个GUI进程空间?
我们可能都是这样认为的:GUI进程要调用GUI服务例程,而这些服务例程都在win32k.sys中,就必然会访问win32k.sys,所以win32k.sys的地址范围在GUI进程中必然是可以访问的。这个逻辑没有错误。按照这个逻辑来推断,一个没有任何GUI的进程空间里,是无法访问win32k.sys的。事实当真如此吗?
来切换到lsass.exe进程看看,这个进程负责本地安全认证,并没有任何GUI。
kd> dt _EPROCESS 821e6348 ImageFileName
ntdll!_EPROCESS
   +0x174 ImageFileName : [16] "lsass.exe"
kd> .process /i 821e6348 
kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
80527da8 cc              int     3
kd> db bf800000
bf800000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
bf800010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
bf800020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
bf800030 00 00 00 00 00 00 00 00-00 00 00 00 e0 00 00 00 ................
bf800040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
bf800050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
bf800060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS 
bf800070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
kd> !pte bf800000
               VA bf800000
PDE at 00000000C0602FE0    PTE at 00000000C05FC000
contains 00000000047BB063 contains 0000000005AA8221
pfn 47bb ---DA--KWEV    pfn 5aa8 C---A--KREV
可以清楚地看到,在一个非GUI进程中也可以访问!
又有同学说了,本来非GUI进程是无法访问win32k.sys的,可能是因为某个线程调用了GUI服务,导致产生了某种转换,使得win32k在一个非GUI进程里可以访问。
实际上,完成这个转换的函数就是PsConvertToGuiThread
但是PsConvertToGuiThread实际上只做了两件事,一是给当前线程使用新的更大的内核栈空间,另外就是把KTHREAD->ServiceTable由KeServiceDescriptorTable切换为KeServiceDescriptorTableShadow。PsConvertToGuiThread完成这个切换之后,就可以正常调用Shadow SSDT中的GUI服务了,也就说,这当中并没有一个过程来完成向当前进程页目录中添加win32k.sys的地址对应的PTE这个过程,由此推断,当一个进程刚出生的时候,win32k.sys的地址就已经在页目录中有描述了,此时就已经可以访问。
空口无凭,实验观察之:
下一个PspCreateProcess断点,当此函数成功返回时,进程已经创建并插入PsActiveProcessLink中,来看一下
PROCESS 82161030 SessionId: 0 Cid: 0344    Peb: 7ffd5000 ParentCid: 02b0
    DirBase: 044402a0 ObjectTable: e20ae7b8 HandleCount:   1.
    Image: ftp.exe
此时进程已经创建,但是还未创建第一个线程,我们在第一个线程运行时断下来。
可以看一下调用栈,此时这个线程刚刚出生,还未调用任何SSDT服务或Shadow SSDT服务.
kd> kvn
# ChildEBP RetAddr Args to Child              
00 f8acbd20 80660017 00000007 8055b140 8055b1fc nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0])
01 f8acbd74 80534dd0 00000000 00000000 823a4030 nt!ExpDebuggerWorker+0x91 (FPO: [Non-Fpo])
02 f8acbdac 805c5a28 00000000 00000000 00000000 nt!ExpWorkerThread+0x100 (FPO: [Non-Fpo])
03 f8acbddc 80541fa2 80534cd0 00000001 00000000 nt!PspSystemThreadStartup+0x34 (FPO: [Non-Fpo])
04 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
来访问下win32k.sys看看:
kd> db bf800000
bf800000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
bf800010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
bf800020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
bf800030 00 00 00 00 00 00 00 00-00 00 00 00 e0 00 00 00 ................
bf800040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
bf800050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
bf800060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS 
bf800070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
kd> !pte bf800000
               VA bf800000
PDE at 00000000C0602FE0    PTE at 00000000C05FC000
contains 00000000047BB063 contains 0000000005AA8221
pfn 47bb ---DA--KWEV    pfn 5aa8 C---A--KREV
完全可以正常访问!也就是说,在进程刚创建完成的时候,win32k.sys的地址就已经可以访问了,并不存在某种切换。而这个进程是系统自带的ftp.exe,一个标准的CUI程序。
MJ说win32k.sys和Session有关,也就是说,win32k.sys在Session Leader(Csrss.exe)及属于该Session的任何一个进程空间中都可以访问。
WindowsXP下系统服务和第一个登录用户共享同一个Session,即Session 0,Vista/Win7中采用了Session隔离,系统服务使用Session 0,第一个用户使用Session 1,其它依次类推。
在这两种系统中,都是遵守这个规则的。但是有一个特殊的不属于任何Session的进程,就是Session Manager(Smss.exe)。
切换到Smss.exe进程空间看一看:
kd> dt _EPROCESS 822474e0 ImageFileName
ntdll!_EPROCESS
   +0x174 ImageFileName : [16] "smss.exe"
kd> .process /i 822474e0 
kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
80527da8 cc              int     3
kd> db bf800000
bf800000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800020 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800030 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800040 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800050 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800060 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800070 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
kd> !pte bf800000
               VA bf800000
PDE at 00000000C0602FE0    PTE at 00000000C05FC000
contains 0000000000000000
在Session Manager的进程空间中,win32k.sys也是无法访问的,因为它不属于任何一个Session.
观察一下进程可以看到了:

也就是说,除了System进程和Smss进程,在其它任何一个属于某个Session进程内都可以访问win32k.sys,并非只有GUI进程才能访问。

PS:感谢某同学打破砂锅问到底的精神,才使我没有继续错下去。

为什么win32k.sys在System进程空间无法访问相关推荐

  1. 【旧文章搬运】为什么win32k.sys在System进程空间无法访问

    原文发表于百度空间,2010-01-02 ========================================================================== 玩过Sh ...

  2. 番外:win32k.sys什么情况下会挂上PTE

    一.前因 在HOOK SSDT Shadow的时候老师说,必须要调用一个界面函数使自己成为GUI进程(线程),才会给这个进程挂上PTE,我对此表示怀疑,于是有了以下探讨 二.探究 1.首先来看一下sy ...

  3. 45个案例一一破解win32k.sys蓝屏

    为什么Windows 2000/XP会蓝屏?45个经典蓝屏案例一一破解 NT内核的操作系统采用的是分层管理结构(层又称为模式),主要有用户层(User Mode)和内核层(Kernel Mode),我 ...

  4. 2019最有意思的五大 ZDI 案例之:通过调色板索引实现 Win32k.sys 本地提权漏洞(上)...

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 本文是趋势科技 ZDI 项目推出的第二届年度最有意思的五大案例系列文章之一.他们从1000多份安全公告中遴选出这些案例,奇安信代码卫士 ...

  5. MS08-025 win32k.sys NtUserFnOUTSTRING Privilege Escalation Exploit

    <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 以下消息来自幻 ...

  6. 2019最有意思的五大 ZDI 案例之:通过调色板索引实现 Win32k.sys 本地提权漏洞 (下)...

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 本文是趋势科技 ZDI 项目推出的第二届年度最有意思的五大案例系列文章之一.他们从1000多份安全公告中遴选出这些案例,奇安信代码卫士 ...

  7. 查看Oracle sys_lob,system表空间满的处理-SYS_LOB0003450292C00039$$

    今天同事发现一个库的system表空间快满了,正好没事,登录上去也分析一下. $ sqlplus '/ as sysdba' SQL*Plus: Release 10.2.0.2.0 - Produc ...

  8. win32k.sys文件简介

    说到win32k.sys,要先说一下win32子系统.win32k.sys是win32子系统的一部分. 子系统指操作系统的一部分,为操作系统的上层应用程序提供运行环境和接口(API).windows  ...

  9. win32k.sys 映射地址

    windows - session 空间中的 win32k.sys 映射地址 原文 标签 windows session kernel driver 我的问题: 当 win32k.sys 加载到 se ...

最新文章

  1. python字符串连接方式_Python 字符串连接方式有这么种,你知道吗?
  2. WebLogic RCE(CVE-2019-2725)漏洞之旅
  3. 特斯拉炫技现场:电驴、行人、快递车,中国的小路难不倒Autopilot自动驾驶
  4. Linux下一些实用的操作记录
  5. Python单例模式的4种实现方法
  6. linux修改su的PAM配置文件,linux pam安全认证模块su命令的安全隐患
  7. 为什么阿里飞猪、滴滴、携程都被质疑滥用大数据杀熟?
  8. 中国电子学会scratch等级考试二级
  9. Spark自定义分区(Partitioner)
  10. iView UI常用组件DatePicker清空技巧
  11. USB2.0协议学习笔记---USB工作过程(类的方法)
  12. Excel表格数据很少但是文件却很大该怎么缩小
  13. ZeroMQ之Request/Response (Java)
  14. 毕设题目:Matlab三维装箱
  15. ALBB 二叉树中相差最大节点的绝对差值
  16. mysql搜索斯芬克斯_如何用sphinx正确搜索数字?
  17. Win10+Ubuntu18.04双系统安装教程
  18. 怎样把k歌作品发到html里,如何将自己的原创歌曲上传入库到全民K歌
  19. python编程狮_Python编程狮-零基础学Python
  20. Linux服务器硬件及RAID配置(详细图解)

热门文章

  1. 微信小程序--首行缩进
  2. android AppWidgetProvider开发桌面小工具
  3. 《联想本有更好的路走》《杨元庆会不会掉队》《少帅杨元庆》
  4. 鼠标悬停之hover选择器
  5. 小学教师资格证全套资料
  6. mint-ui使用手册
  7. 【深度学习篇】---CNN和RNN结合与对比,实例讲解
  8. EditText设置只允许输入文字、拼音、数字
  9. 百度地图全景——百度经纬度显示全景
  10. 某速的体育视频采集分析