原文链接:http://blog.csdn.net/tianzhhy/article/details/6184265

http://blog.csdn.net/evi10r/article/details/6742052

Ring3中的NATIVE API,和Ring0的系统调用,都有同名的Zw和Nt系列函数,这些Zw*和Nt*函数既在ntdll.dll(Ring3)中导出又在ntoskrnl.exe(Ring0)中导出,他们有什么区别呢?

我们先来看看ntdll.dll和ntoskrnl.exe的关系
Win32 API中的所有调用最终都转向了ntdll.dll,再由它转发至ntoskrnl.exe。ntdll.dll是本机API用户模式的终端,真正的接口在ntoskrnl.exe里完成。
Ntdll.dll的主要作用就是让内核函数的特定子集可以被用户模式下运行的程序调用。Ntdll.dll通过软件中断int 2Eh进入ntoskrnl.exe,就是通过中断门切换CPU特权级。

下面以ZwOpenProcess和NtOpenProcess函数为例,详细阐述下他们的分别和联系。

1.ntdll.dll中的Zw*和Nt*有什么区别?

用dependency查看ntdll.dll中的ZwOpenProcess和NtOpenProcess,如下图,可见两者的入口点是一样的,这就是说,ntdll!ZwOpenProcess仅仅是ntdll!NtOpenProcess函数的别名而已。

两者实现如下:
0:000> u ntdll!zwopenprocess
ntdll!ZwOpenProcess:
7c92d5fe b87a000000      mov     eax,7Ah
7c92d603 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d608 ff12            call    dword ptr [edx]
7c92d60a c21000          ret     10h
7c92d60d 90              nop

0:000> u ntdll!ntopenprocess
ntdll!ZwOpenProcess:
7c92d5fe b87a000000      mov     eax,7Ah
7c92d603 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d608 ff12            call    dword ptr [edx]
7c92d60a c21000          ret     10h
7c92d60d 90              nop
从反汇编代码来看,两者别无区别,都是通过SSDT服务表,通过系统服务调度程序KiSystemService调用ntoskrnl.exe中的中断处理程序Nt*函数。

7FFE0300h处是ntdll!KiFastSystemCall的入口,ntdll!KiFastSystemCall会保存起当前的栈指针,然后通过引发0x2e中断,陷入内核。 
当触发0x2e中断后,CPU将执行环境切换到Ring0状态,然后去调用内核模块的0x2e处理例程nt!KiSystemService。nt!KiSystemService会在参数检查、栈拷贝等操作之后,根据Ring3代码传递过来的调用号0x7A,在SSDT中查找相应的函数地址,然后调用找到的函数。对于我们的例子来说,这个函数就是内核模块的导出函数nt!NtOpenProcess。nt!NtOpenProcess才是真正的打开进程实现函数。

2.ntoskrnl.exe中的Zw*和Nt*有什么区别?

用dependency查看ntdll.dll中的ZwOpenProcess和NtOpenProcess,如下图。两者入口点不同,显然不是简单的别名关系了。

两者实现如下:
kd> u nt!ZwOpenProcess
nt!ZwOpenProcess:
804febfc b87a000000      mov     eax,7Ah
804fec01 8d542404        lea     edx,[esp+4]
804fec05 9c              pushfd
804fec06 6a08            push    8
804fec08 e844ea0300      call    nt!KiSystemService (8053d651)
804fec0d c21000          ret     10h

kd> u nt!ntOpenProcess
nt!NtOpenProcess:
805c0b56 68c4000000      push    0C4h
805c0b5b 6888aa4d80      push    offset nt!ObWatchHandles+0x25c (804daa88)
805c0b60 e87b75f7ff      call    nt!_SEH_prolog (805380e0)
805c0b65 33f6            xor     esi,esi
805c0b67 8975d4          mov     dword ptr [ebp-2Ch],esi
805c0b6a 33c0            xor     eax,eax
805c0b6c 8d7dd8          lea     edi,[ebp-28h]
805c0b6f ab              stos    dword ptr es:[edi]

……………………代码未完
ZwOpenProcess函数很短,首先把0x7a(NtOpenProcess的系统服务号)存入eax,然后做一些保存现场的工作,之后调用KiSystemService函数,KiSystemService内部会根据eax中的service id(系统服务号)在SSDT中查找相应的系统服务,然后调用之。

NtOpenProcess函数很长(反汇编结果只是一部分),事实上,NtOpenProcess是真正执行打开进程操作的函数(在Ring0中通常称为服务或例程)。所以若在驱动中直接调用Nt系列函数,是不会经过SSDT的,也就不会被SSDT HOOK所拦截。

可见,ZwOpenProcess通过中断来实现功能,2E软中断的7Ah子中断号的处理程序是NtOpenProcess。那这么一说他们是没区别了?错!NtOpenProcess是在Ring0下;而ZwOpenProcess是通过int 7Ah进入Ring0的,不管ZwOpenProcess处于什么模式下。

总结如下:
1.
用户空间,即Ring3(ntdll.dll)中的Zw*和Nt*的实现都是一样的;
内核空间,即Ring0(ntoskrnl.exe)中Nt*是真正的函数实现,而Zw*函数是Nt*的一个stub函数,其内部通过SSDT来找到对应的Nt*函数。

2.
ntdll.dll中ZwOpenProcess与ntoskrnl.exe中ZwOpenProcess的区别是:
前者在ring3下工作,后者在ring0下工作。

ntdll.dll中NtOpenProcess与ntoskrnl.exe中NtOpenProcess区别是:
前者在ring3下工作,后者在ring0下工作;前者通过中断实现,后者是前者的中断处理程序。

3.
由以上对Zw*反汇编可知,Zw*代码内部是通过SSDT中的对应Nt*索引号查找到真正Nt*执行代码的入口地址。
ntdll.dll:        传入服务号到eax--->调用ntdll!KiFastSystemCall (7ffe0300)函数--->KiSystemService--->Nt*(ntoskrnl)
ntoskrnl.exe:传入服务号到eax--->KiSystemService--->Nt*(ntoshrnl)

4.
R3下无论如何调用,均无法绕过SSDT HOOK,R0下调用Nt*可以绕过SSDT HOOK。

5.
从用户模式调用Nt和Zw API,连接ntdll.lib。由于是从用户模式进入内核模式,因此代码会严格检查用户空间传入的参数。

从内核模式调用Nt和Zw API,连接nooskrnl.lib。Nt系列API将直接调用对应的函数代码,而Zw系列API则通过KiSystemService,最终跳转到对应的函数代码。
在进行Kernel Mode Driver开发时可以使用Zw系列API可以避免额外的参数列表检查,提高效率。

参考文章:

http://blog.csdn.net/yushiqiang1688/archive/2010/03/19/5393286.aspx

http://hi.baidu.com/ligh0721/blog/item/123c99fa4808b6839f514668.html

http://blog.csdn.net/syf442/archive/2009/09/15/4554927.aspx

http://blog.csdn.net/bobohack/archive/2009/10/24/4724140.aspx

Nt*和Zw*开头的函数相关推荐

  1. ntdll.dll和ntoskrnl.exe中的NT*和ZW*函数区别

    以NtOpenProcess和ZwOpenProcess为例,结合Windbg的lkd调试来说明 1.Q:ntdll.dll中的Nt*和Zw*区别? lkd> u ntdll!zwopenpro ...

  2. 本地系统服务例程:Nt和Zw系列函数

    Windows本地操作系统服务API由一系列以Nt或Zw为前缀的函数实现的,这些函数以内核模式运行,内核驱动可以直接调用这些函数,而用户层程序只能通过系统进行调用.通常情况下用户层应用程序不会直接调用 ...

  3. Nt*和Zw*系列函数的区别

    ntdll.dll和ntoskrnl.exe的Nt和Zw系列函数区别 in ring3: lkd> ? ntdll!ZwOpenProcess Evaluate expression: 2089 ...

  4. Opencv 中cv开头的函数和没有cv的区别,例如cvWaitkey()和waitKey()的区别

    1. 问题描述 在opencv中,有很多功能类似或者相同的函数,例如cvWaitKey()和waitKey().新手在刚刚接触opencv时,很容易弄糊涂,到底有什么区别,为什么要有这些功能类似的函数 ...

  5. C语言函数大全-- m 开头的函数(1)

    C语言函数大全 本篇介绍C语言函数大全-- m 开头的函数 1. malloc 1.1 函数说明 函数声明 函数功能 void *malloc(size_t size); 用于动态分配内存 参数: s ...

  6. C语言函数大全-- q 开头的函数

    C语言函数大全 本篇介绍C语言函数大全-- q 开头的函数 1. qsort 1.1 函数说明 函数声明 函数功能 void qsort(void *base, size_t nmemb, size_ ...

  7. C语言下划线开头的函数

    首先,C++里关于下划线的问题是源于C语言,因为C++允许用extern "C"来修饰代码以C语言语法方式编译.然后说C语言里的下划线:C语言确实允许以下划线开头的函数存在,实际上 ...

  8. C语言函数大全-- s 开头的函数(1)

    C语言函数大全 本篇介绍C语言函数大全-- s 开头的函数(1) 1. sbrk 1.1 函数说明 函数声明 函数功能 void *sbrk(intptr_t increment); 它是一个 Uni ...

  9. C语言函数大全-- i 开头的函数

    C语言函数大全 本篇介绍C语言函数大全– i 开头的函数 1. imagesize 1.1 函数说明 函数声明 函数功能 unsigned imagesize(int left, int top, i ...

最新文章

  1. mysql localhost无法登陆_MySQL 'root'@'localhost'无法登录
  2. Xcode文件名后的字母含义
  3. android 常见异常解决
  4. ARM WFI和WFE指令
  5. 15 函数回调 模块
  6. SDNU 1469.校门外的树(水题)
  7. s7-1200跟mysql_让西门子S7-1200直接连接MySQL数据库!!!
  8. Struts2和hibernate框架整合实现简单的注册登陆功能
  9. iphone个人热点无法开启_无法在 iPhone 上正常使用“个人热点”怎么办?
  10. TrueNAS Enterprise是什么
  11. 传统企业如何选择优质的微信解决方案提供商
  12. mysql的collate_MYSQL中的COLLATE是什么?
  13. Amy-Tabb机器人世界手眼标定(1、环境搭配)
  14. 学生家乡网页设计作品静态HTML网页—— HTML+CSS+JavaScript制作辽宁沈阳家乡主题网页源码(11页)
  15. vue项目引入typescript(vue与ts混用)
  16. Java日志框架 -- 日志框架介绍、日志门面技术、JUL日志(JUL架构、JUL入门示例、JUL日志级别、JUL日志的配置文件)
  17. 关于SES2000找管线定位问题的实验
  18. d435i 深度相机运行踩坑大合集
  19. Pycharm设置快捷键放大缩小字体
  20. html指定区域的背景颜色,JS实现点击颜色块切换指定区域背景颜色的方法

热门文章

  1. Java并发系列(10)——FutureTask 和 CompletionService
  2. 去一趟公园前,我要先饿足三天三夜 广州美食
  3. 2017广州两日游(提高组总结)
  4. 黑莓安装HANDBASE数据库
  5. 百度网盘下载慢怎么解决
  6. 凯文·凯利对人工智能的思考与我的理解
  7. 数藏行业周报(06.20-06.26)
  8. 最大似然法的原理与介绍
  9. 小清新业务汇报PPT模板
  10. Java中IO流,输入输出流概述与总结(转载自别先生文章)