内核解惑:zw函数和nt函数的区别

转载 2013年12月03日 15:42:04

转载自:http://hi.baidu.com/resoft007/item/eb510a0d0ae2ac03addc7019

http://bbs.pediy.com/showthread.php?t=106888

http://bbs.pediy.com/showthread.php?t=55142

解惑:http://blog.csdn.net/u012410612/article/details/17093079

lkd> u ZwOpenProcess
nt!ZwOpenProcess:
804de044 b87a000000      mov     eax,7Ah
804de049 8d542404        lea     edx,[esp+4]
804de04d 9c              pushfd
804de04e 6a08            push    8
804de050 e8dc150000      call    nt!KiSystemService (804df631)
804de055 c21000          ret     10h
lkd> u NtOpenProcess
nt!NtOpenProcess:
80573d06 68c4000000      push    0C4h
80573d0b 6810b44e80      push    offset nt!ObWatchHandles+0x25c (804eb410)
80573d10 e826f7f6ff      call    nt!_SEH_prolog (804e343b)
80573d15 33f6            xor     esi,esi
80573d17 8975d4          mov     dword ptr [ebp-2Ch],esi
80573d1a 33c0            xor     eax,eax
80573d1c 8d7dd8          lea     edi,[ebp-28h]
80573d1f ab              stos    dword ptr es:[edi]

 

这是看雪上某人反的两个函数。

用户模式调用Nt和Zw API,如NtReadFile和ZwReadFile,二者没有任何区别,通过设置系统服务表中的索引和在堆栈中设置参数,经由SYSENTER指令进入内核态(而不是象w2k中通过int 0x2e中断),并最终由KiSystemService跳转到KiServiceTable对应的系统服务例程中。由于是从用户模式进入内核模式,因此代码会严格检查用户空间传入的参数。

内核模式调用Nt和Zw API,连接nooskrnl.lib:
Nt系列API将直接调用对应的函数代码,而Zw系列API则通过KiSystemService,最终跳转到对应的函数代码。

重要的是两种不同的调用对内核中previous mode的改变,如果是从用户模式调用Native API则previous mode是用户态,如果从内核模式调用Native API则previous mode是内核态。previous为用户态时Native API将对传递的参数进行严格的检查,而为内核态时则不会。
调用Nt API时不会改变previous mode的状态,调用Zw API时会将previous mode改为内核态,因此在进行Kernel Mode Driver开发时可以使用Zw系列API可以避免额外的参数列表检查,提高效率。(Zw*会设置KernelMode已避免检查,Nt*不会自动设置,如果是KernelMode当然没问题,如果就UserMode就挂了)


我们只要把kthread中的PreviousMode值设为0就代表来自内核态


Zw*系列是通过SSDT来间接调用,同时设置Ehread->previous mode 为 kernelmode

Nt*系列是直接调用函数,但是却不设置Ehread->previous mode

所以如果是在内核mode当然没问题,同时还可以跳过SSDT HOOK  ps:当然Inline Hook肯定不行

但是内核组件可能运行在任意进程的上下文中 所以Nt*可能在usermode中,这是就会STATUS_ACCESS_VIOLATION 了 

当然这是Nt*函数中检查当前线程结构的PreviousMode 来确定调用是来自用户态还是内核态 如果是来自用户态 函数会检测参数地址是否小于_MmUserProbeAddress.如果不是 将会产生一个错误..   所以我们的目标就是把PreviousMode改为Kernel Mode  这就是Zw*和Nt*的区别

【驱动之四】Nt和Zw

Ring3中的NATIVE API,和Ring0的系统调用,都有同名的Zw和Nt系列函数,一度让初学者感到迷糊。现在就以ZwOpenProcess和NtOpenProcess函数为例,详细阐述下他们的...
  • seedluo815
  • seedluo815
  • 2014年05月05日 02:24
  • 463

Nt*和Zw*开头的函数

原文 Ring3中的NATIVE API,和Ring0的系统调用,都有同名的Zw和Nt系列函数,这些Zw*和Nt*函数既在ntdll.dll(Ring3)中导出又在ntoskrnl.exe(Ri...
  • qiaoli278141408
  • qiaoli278141408
  • 2014年09月23日 18:52
  • 822

Hook内核函数注意点(学习笔记)

1.注意函数的IRQL等级,有些函数只能运行在PASSIVE_LEVEL,如果级别过高就会蓝屏(至于IRQL级别可查看:http://baike.baidu.com/link?url=RvjyQWQf...
  • apxar
  • apxar
  • 2013年08月27日 17:17
  • 1426

r0调用ntOpenprocess函数枚举进程

需要先把Kthread中的PreviousMode的值置成KernelMode因为调用CqEnumProcessInfoByMyOpenProcess这个函数的时候,是由应用层的程序调用DeviceI...
  • Sunny_wwc
  • Sunny_wwc
  • 2011年02月07日 21:51
  • 3437

测试结果OK、POK、NG、NT的意义

OK--就是Pass,测试通过的意思; POK - 部分通过,表示测试中有很多检查点,比如其中两个检查点通过,一个没有通过,就是POK ; NG - 是Not Good的意思,也可以解释为:NG=...
  • wanlixingzhe
  • wanlixingzhe
  • 2012年02月09日 14:37
  • 15517

在NT系列操作系统里让自己“消失”]

===================[ 在NT系列操作系统里让自己“消失”]==================                                          ...
  • yeahhook
  • yeahhook
  • 2014年12月01日 08:25
  • 1653

ZW与NT函数区别

区别: Ntdll.dll中:完全一样 Ntoskrnl.exe中: Zw*nt*,即nt函数更底层 Zw*函数会把PreviousMode设置为KernelMode  然后再调用Nt*函数...
  • zhuhuibeishadiao
  • zhuhuibeishadiao
  • 2016年04月10日 17:59
  • 494

Nt**、Zw**和Rtl** 开头的函数介绍

首先他们都是微软未公开的函数,之所以未公开主要是因为这些函数大部分功能太强大了,把他们公开会让一些别有用心的人利用。9x下的我不知道,NT(含2000/xp)下你可以参考《Windows NT Nat...
  • qq1841370452
  • qq1841370452
  • 2017年01月13日 02:15
  • 318

火绒内核注入dll方式win7-win10通用x64下不触发PG

该思路理论上7到10通用.只不过jump函数不一样.PG不会被触发 看论坛的图 到16年7月.360也能注入一个DLL进去.至于其他游戏保护驱动什么的.我估计也一起躺下...
  • programme_fancier
  • programme_fancier
  • 2017年07月09日 17:51
  • 2296

32位和64位系统内核函数调用从ZwProtectVirtualMemory到NtProtectVirtualMemory

https://www.cnblogs.com/aliflycoris/p/5828157.html 0x01 前言   我们知道R3层中,Zw系列函数和Nt系列函数函数是一样...
  • fyfywg
  • fyfywg
  • 2017年11月20日 00:15
  • 114
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内核解惑:zw函数和nt函数的区别
举报原因:
原因补充:

(最多只允许输入30个字)