SystemCallStub与KiFastSystemCall的关系

来源:互联网 发布:福建广电网络 编辑:程序博客网 时间:2024/05/29 16:04

最近在读《格蠹汇编》第八章时,书中提到在windbg中执行kn命令显示栈回溯,USER32!NtUserMessageCall调用了ntdll!KiFastSystemCall,但在windbg中执行uf USER32!NtUserMessageCall时,结果如下:

0:000> uf USER32!NtUserMessageCall USER32!NtUserMessageCall:77d194b2 b8cc110000      mov     eax,11CCh77d194b7 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)77d194bc ff12            call    dword ptr [edx]77d194be c21c00          ret     1Ch

USER32!NtUserMessageCall调用了SharedUserData!SystemCallStub中保存的值,SharedUserData!SystemCallStub是一个地址,这个值是0x7ffe0300,在windbg中查看7ffe0300处的值,

0:000> dd 7ffe03007ffe0300  7c92e4f0 7c92e4f4 00000000 000000007ffe0310  00000000 00000000 00000000 000000007ffe0320  00000000 00000000 00000000 000000007ffe0330  95ed03c5 00000000 00000000 000000007ffe0340  00000000 00000000 00000000 000000007ffe0350  00000000 00000000 00000000 000000007ffe0360  00000000 00000000 00000000 000000007ffe0370  00000000 00000000 00000000 00000000

0x7ffe0300中保存的值是0x7c92e4f0,继续跟踪,

0:000> uf 7c92e4f0ntdll!KiFastSystemCall:7c92e4f0 8bd4            mov     edx,esp7c92e4f2 0f34            sysenter7c92e4f4 c3              ret

由此可见,SharedUserData!SystemCallStub的地址里面保存着KiFastSystemCall的地址。SharedUserData总是存放在0x7ffe0000处,其偏移0x300处正是KiFastSystemCall。

上述调试的内核版本:Windows XP Kernel Version 2600 (Service Pack 3) MP (2 procs) Free x86 compatible

在call dword ptr [edx]之前,mov eax,11cch把系统调用号保存到eax中
由此可以观察出ntdll.dll和user32.dll中API函数的规律,

在 Win-XP-SP1 中:0: kd> u ntdll!ZwReadFilentdll!NtReadFile:77f761e8 b8b7000000      mov     eax,0xb777f761ed ba0003fe7f      mov     edx,0x7ffe030077f761f2 ffd2            call    edx77f761f4 c22400          ret     0x24 Win-XP-SP2 以后的操作系统:0:000> u ntdll!NtReadFilentdll!ZwReadFile:7c92e27c b8b7000000      mov     eax,0B7h7c92e281 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)7c92e286 ff12            call    dword ptr [edx]7c92e288 c22400          ret     24h相同点是先把系统调用号保存到eax中,区别是:sp1是 call EDX,sp2是 call [EDX]

至于为什么要改变这个 call [EDX],《Kernel-mode Payloads on Windows》(Uninformed, 2005)写在脚注里且红色标出。

Due to the fact that SharedUserData contained executable instructions, it was thus necessary that the SharedUserData mapping had to be marked as executable. When Microsoft began work on some of the security enhancements included with XP SP2 and 2003 SP1, such as Data Execution Prevention (DEP), they presumably realized that leaving SharedUserData executable was largely unnecessary and that doing so left open the possibility for abuse. To address this, the fields in KUSER_SHARED_DATA were changed from sets of instructions to function pointers that resided within ntdll.dll.

由于 SharedUserData 中包含了可执行指令,那么 SharedUserData 所在的页就会被映射成可执行代码段。当微软试图对 XP SP2 以及 2003 SP1 做一些安全性增强工作时(例如:数据执行保护 DEP),他们大概意识到让 SharedUserData (所在页面)变得可执行非常地多余,这留下了潜在的滥用可能性。为了解决这个问题,那个在 KUSER_SHARED_DATA 里的域由一组指令变成了指向 ntdll.dll 里指令的函数指针。
参考:http://advdbg.org/forums/1982/ShowPost.aspx

0 0
原创粉丝点击