[转载]Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
2015-02-02 20:59
423 查看
原文地址:点击打开链接
为什么要写这篇文章
1. 因为最近在学习《软件调试》这本书,看到书中的某个调试历程中讲了Windows的系统调用的实现机制,其中讲到了从Ring3跳转到Ring0之后直接进入了KiFastCallEntry这个函数。
2. 碰巧前天又在网上看到了一篇老文章介绍xxx安全卫士对Windows系统调用的Hook,主要就是Hook到这个函数
3. 刚刚做完毕业设计,对使用中断来实现系统调用的方式记忆犹新。
以上原因导致我最近眼前总是出现系统调用这个词,脑海中总是出现系统调用的实现方式,所以决定写篇文章清理一下思维。本文所有举例如无明确指明,均是在Windows XP SP3系统中获得。
本文的目的是探索一下Windows目前的系统调用的实现架构,介绍一种中规中矩的获取KiFastCallEntry函数地址的方法,但是在介绍之前还是要把该解释的解释清除。
肯定会有人说Windows API就是系统调用,系统调用就是Windwos API,是这样的么?负责任的说:不是这样的!
先从广义上来说,Windows API是对于整个Windows操作系统自身的程序代码之外的应用程序来说的,而系统调用是Windows内核对于非内核程序代码之外的Windows系统程序代码来说的。也就是说系统调用要比Windows API低一个层次。一个Windows API是一个函数,这个函数可能会使用系统调用,请注意是可能,因为并不是所有的API都需要进入内核去完成这个API的功能。
在一个安装完成的Windows操作系统中可见并有效的内核实现文件是
C:\Windows\System32\ntoskrnl.exe
C:\Windows\System32\ntkrnlpa.exe
请注意有两个内核文件,其中第二个比第一个的名字少了os多了个pa,省去的os没有任何意义,但是多出来的pa所代表的意思是PAE(物理地址扩展),这是X86CPU的一个硬件特性,Windows启动之后根据当前系统设置是否开启了PAE特性会自动选择把其中一个作为内核加载到内存中。
为什么加了这么多限定词,因为ntoskrnl.exe这个文件名并不一定是这个文件的真实名称,可以从文件属性中看到
ntoskrnl.exe原始文件名为可能为ntoskrnl.exe或者ntkrnlmp.exe
ntkrnlpa.exe原始文件名为可能为ntkrnlpa.exe或者ntkrpamp.exe
可以发现其中的不同之处就是mp,mp就是Multi-processor(多处理器,也可以理解为多核,因为IA-32架构对多核处理器的编程和多处理器的编程是相似的机制)。为什么会出现这中情况呢?因为这完全是由计算机硬件的不同配置导致的。当安装Windows操作系统的时候,Windows安装程序会自动检测机器的CPU特性,根据CPU的核心数来确定使用哪一套内核。如果是单核心就只复制ntkrnlpa.exe和ntoskrnl.exe到系统目录下,如果是多核心就复制ntkrnlpamp.exe和ntoskrnlmp.exe到系统目录下,所以如果你有一台单核心CPU的机器,有一天你换了双核的CPU却没有重新安装操作系统,那么你就不会在看到熟悉的Windows启动画面了。类似这两个文件的还有一个文件C:\Windows\System32\hal.dll,这是Windows的硬件抽象层程序文件,这个就不做具体介绍了。额外补充一个不同的硬件配置所需要的文件列表:
不论什么配置,一旦系统安装完成后,对我们来说可见的内核文件就只有两个ntoskrnl.exe和ntkrnlpa.exe。这两个文件中的代码就是运行于RING0下的内核代码,他们里面所包含了真正的系统调用的代码。我们用Dependency Walker看一下:
View Code
测试用驱动代码及结果如下图:
(P21)
(P22)
这个结果和我们用Windbg查看得到的是一样的。
这篇文章写的有点长,而且知识有点砸碎希望各位看过之后能理解。
为什么要写这篇文章
1. 因为最近在学习《软件调试》这本书,看到书中的某个调试历程中讲了Windows的系统调用的实现机制,其中讲到了从Ring3跳转到Ring0之后直接进入了KiFastCallEntry这个函数。
2. 碰巧前天又在网上看到了一篇老文章介绍xxx安全卫士对Windows系统调用的Hook,主要就是Hook到这个函数
3. 刚刚做完毕业设计,对使用中断来实现系统调用的方式记忆犹新。
以上原因导致我最近眼前总是出现系统调用这个词,脑海中总是出现系统调用的实现方式,所以决定写篇文章清理一下思维。本文所有举例如无明确指明,均是在Windows XP SP3系统中获得。
本文的目的是探索一下Windows目前的系统调用的实现架构,介绍一种中规中矩的获取KiFastCallEntry函数地址的方法,但是在介绍之前还是要把该解释的解释清除。
Windows API和系统调用的关系
肯定会有人说Windows API就是系统调用,系统调用就是Windwos API,是这样的么?负责任的说:不是这样的!先从广义上来说,Windows API是对于整个Windows操作系统自身的程序代码之外的应用程序来说的,而系统调用是Windows内核对于非内核程序代码之外的Windows系统程序代码来说的。也就是说系统调用要比Windows API低一个层次。一个Windows API是一个函数,这个函数可能会使用系统调用,请注意是可能,因为并不是所有的API都需要进入内核去完成这个API的功能。
Windows内核实现文件和应用层文件
在一个安装完成的Windows操作系统中可见并有效的内核实现文件是C:\Windows\System32\ntoskrnl.exe
C:\Windows\System32\ntkrnlpa.exe
请注意有两个内核文件,其中第二个比第一个的名字少了os多了个pa,省去的os没有任何意义,但是多出来的pa所代表的意思是PAE(物理地址扩展),这是X86CPU的一个硬件特性,Windows启动之后根据当前系统设置是否开启了PAE特性会自动选择把其中一个作为内核加载到内存中。
为什么加了这么多限定词,因为ntoskrnl.exe这个文件名并不一定是这个文件的真实名称,可以从文件属性中看到
ntoskrnl.exe原始文件名为可能为ntoskrnl.exe或者ntkrnlmp.exe
ntkrnlpa.exe原始文件名为可能为ntkrnlpa.exe或者ntkrpamp.exe
可以发现其中的不同之处就是mp,mp就是Multi-processor(多处理器,也可以理解为多核,因为IA-32架构对多核处理器的编程和多处理器的编程是相似的机制)。为什么会出现这中情况呢?因为这完全是由计算机硬件的不同配置导致的。当安装Windows操作系统的时候,Windows安装程序会自动检测机器的CPU特性,根据CPU的核心数来确定使用哪一套内核。如果是单核心就只复制ntkrnlpa.exe和ntoskrnl.exe到系统目录下,如果是多核心就复制ntkrnlpamp.exe和ntoskrnlmp.exe到系统目录下,所以如果你有一台单核心CPU的机器,有一天你换了双核的CPU却没有重新安装操作系统,那么你就不会在看到熟悉的Windows启动画面了。类似这两个文件的还有一个文件C:\Windows\System32\hal.dll,这是Windows的硬件抽象层程序文件,这个就不做具体介绍了。额外补充一个不同的硬件配置所需要的文件列表:
Standard PC | hal.dll ntkrnlpa.exe ntoskrnl.exe |
Advanced Configuration and Power Interface (ACPI) PC | halacpi.dll---->hal.dll ntkrnlpa.exe ntoskrnl.exe |
ACPI Uniprocessor PC | halaacpi.dll--->hal.dll ntkrnlpa.exe ntoskrnl.exe |
MPS Uniprocessor PC | halapic.dll---->hal.dll ntkrnlpa.exe ntoskrnl.exe |
ACPI Multiprocessor PC | halmacpi.dll--->hal.dll ntkrpamp.exe--->ntkrnlpa.exe ntkrnlmp.exe---->ntoskrnl.exe |
Compag SystemPro Multiprocessor or 100% Compatible | halsp.dll---->hal.dll ntkrpamp.exe--->ntkrnlpa.exe ntkrnlmp.exe--->ntoskrnl.exe |
MPS Multiprocessor PC | halmps.dll----->hal.dll ntkrpamp.exe----->ntkrnlpa.exe ntkrnlmp.exe--->ntoskrnl.exe |
Silicon Graphics Visual Workstation | halsp.dll---->hal.dll ntkrpamp.exe----->ntkrnlpa.exe ntkrnlmp.exe---->ntoskrnl.exe |
#define IA32_SYSENTER_CS 174H 2. #define IA32_SYSENTER_ESP 175H 3. #define IA32_SYSENTER_EIP 176H 4. 5. ULONG GetAddressOfKiFastCallEntry() 6. { 7. ULONG dwAddress = 0; 8. __asm 9. { 10. jmp func_main 11. vgdtr: 12. _emit 0x00 13. _emit 0x00 14. _emit 0x00 15. _emit 0x00 16. _emit 0x00 17. _emit 0x00 18. _emit 0x00 19. _emit 0x00 20. 21. func_main: 22. push eax 23. push ebx 24. push ecx 25. push edx 26. mov ecx, 0x174 27. rdmsr 28. mov ebx, eax //Selector offset 29. 30. sgdt vgdtr 31. mov edx, vgdtr 32. add edx, 0x02 33. mov eax, [edx] //GDT base 34. add ebx, eax //Selector base 35. 36. mov edx, ebx 37. add edx, 0x07 38. mov eax, [edx] 39. shl eax, 24; 40. mov edx, ebx 41. add edx, 0x02 42. mov ecx, [edx] 43. and ecx, 0x00FFFFFF 44. add eax, ecx //Address CodeSegment 45. mov ebx, eax 46. 47. mov ecx, 0x176 48. rdmsr 49. add eax, ebx 50. 51. mov dwAddress, eax 52. 53. pop edx 54. pop ecx 55. pop ebx 56. pop eax 57. } 58. 59. return dwAddress; 60. }
View Code
测试用驱动代码及结果如下图:
(P21)
(P22)
这个结果和我们用Windbg查看得到的是一样的。
这篇文章写的有点长,而且知识有点砸碎希望各位看过之后能理解。
相关文章推荐
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取 + 一个hook的实现
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取
- Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取 .
- 系统调用计算KiFastCallEntry地址的过程以及由此得到的一种获取KiFastCallEntry地址的方式
- C或C++调用Windows系统函数 实现延时 或 获取当前时间的处理
- Windows系统调用架构分析
- Windows获取当前系统时间函数总结
- [转载]直接调用类成员函数地址
- Windows系统下获取一段函数执行的时间
- 直接调用类成员函数地址(转载自http://blog.csdn.net/shamozhihuzhubohu/archive/2010/07/30/5776979.aspx)
- 多种方法获取sys_call_table(linux系统调用表)的地址
- 大型网站系统架构分析(转载自博客园)
- temu分析之提取系统调用函数