Zw函数与Nt函数的分别与联系
Ring3中的NATIVE API,和Ring0的系统调用,都有同名的Zw和Nt系列函数,一度让初学者感到迷糊。N久前的我,也是相当的迷糊。现在就以ZwOpenProcess和NtOpenProcess函数为例,详细阐述下他们的分别和联系。
ntdll.dll导出了NtOpenProcess和ZwOpenProcess两个函数,我们记为ntdll!NtOpenProcess和ntdll!ZwOpenProcess。仔细看一下,会发现他们的入口点实际上都是一样的,这就是说,ntdll!ZwOpenProcess仅仅是ntdll!NtOpenProcess函数的别名而已,实现如下:
ZwOpenProcess
.text:7C92D5FE mov eax, 7Ah ; NtOpenProcess
.text:7C92D603 mov edx, 7FFE0300h
.text:7C92D608 call dword ptr [edx]
.text:7C92D60A retn 10h
7FFE0300h处是ntdll!KiFastSystemCall的入口,ntdll!KiFastSystemCall会保存起当前的栈指针,然后通过引发0x2e中断,陷入内核。
当触发0x2e中断后,CPU将执行环境切换到Ring0状态,然后去调用内核模块的0x2e处理例程nt!KiSystemService。nt!KiSystemService会在参数检查、栈拷贝等操作之后,根据Ring3代码传递过来的调用号0x7A,在SSDT中查找相应的函数地址,然后调用找到的函数。对于我们的例子来说,这个函数就是内核模块的导出函数nt!NtOpenProcess。nt!NtOpenProcess才是真正的打开进程实现函数。但是内核模块也导出了nt!ZwOpenProcess,这个nt!ZwOpenProcess,有什么用处呢?会不会像ntdll!ZwOpenProcess一样,也仅仅是ntdll!NtOpenProcess的一个别名?实际上,nt!ZwOpenProcess并不仅仅是nt!NtOpenProcess一个别名,我们可以看一下nt!ZwOpenProcess的实现:
kd> u nt!ZwOpenProcess
nt!ZwOpenProcess:
804fede8 mov eax,7Ah
804feded lea edx,[esp+4]
804fedf1 pushfd
804fedf2 push 8
804fedf4 call nt!KiSystemService (8053d891)
804fedf9 ret 10h
与ntdll.ZwOpenProcess是不是很接近?nt!ZwOpenProcess也只是让nt!KiSystemService调用SSDT中的第0x7A号函数,他自己本身没有进行任何打开进程的实现。
到这儿,就可以总结一下了:用户空间中的Zw***和Nt***的实现都是一样的,比如ntdll!ZwOpenProcess和ntdll!NtOpenProcess的入口都是0x7C92D5FE,ntdll!ZwOpenFile和ntdll!NtOpenFile的入口都是0f7C92D59E。内核空间中的Zw函数,是Nt函数的一个Stup,只是mov系统调用号到eax中,转而直接调用(注意,没有像ntdll!ZwOpenProcess)nt!KiSystemService去从SSDT中找到相应号码的函数再调用之,真正的实现都在Nt***函数中。
什么是“未公开”函数呢?微软为了某种目的。对于一些封装在系统中的函数没有在任何开发文档提供任何函数说明和定义。而这些函数有很多都是很有用的。所幸的是一些有心之人对Windows系统动态连接库做了十分详细的分析,从而将这些未公开函数公开以供广大开发人员共享(我对他们的感激之情就象滔滔江水,绵绵不绝…)
首先他们都是微软未公开的函数,之所以未公开主要是因为这些函数大部分功能太强大了,把他们公开会让一些别有用心的人利用。9x下的我不知道,NT(含2000/xp)下你可以参考《Windows NT Native API》,他们中的大部分函数几乎就从来没有变过。而几乎所有从Kenerl.dll中引出的Win32API,都是通过调用的Native API(NTDLL.DLL中导出)实现系统调用的。举一个例子:NtQuerySystemInformation 这个函数就强大到可以查询所有的系统信息,使用时需要用户拥有相当高的访问权限。
in ring3:
lkd> ? ntdll!ZwOpenProcess
Evaluate expression: 2089999739 = 7c92dd7b
lkd> ? ntdll!NtOpenProcess
Evaluate expression: 2089999739 = 7c92dd7b
可以看到,在ntdll中,ZwOpenProcess和NtOpenProcess其实是同一个函数,只不过拥有两个名称而已。
也就是说,在ring3环境中,Zw***系列函数和Nt***系列函数无区别。
in ring0:
lkd> u nt!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 nt!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]
可以看得出,ZwOpenProcess函数很短,首先把0x7a(NtOpenProcess的服务号)存入eax,然后做一些保存现场的工作即KiSystemService——这个函数根据eax中的service id在SSDT中查找相应的系统服务,然后调用之。
而NtOpenProcess函数很长(反汇编结果只是一部分),事实上,NtOpenProcess便是真正执行打开进程操作的函数(在r0中通常称为服务,或例程),所以,若在驱动中直接调用Nt系列函数,是不会经过SSDT的,也就不会被SSDT HOOK所拦截。
简单总结如下:
r3下无论如何调用,均无法绕过SSDT HOOK,r0下调用Nt*可以绕过SSDT HOOK。
Zw函数与Nt函数的分别与联系的更多相关文章
- 《zw版·Halcon-delphi系列原创教程》 zw版-Halcon常用函数Top100中文速查手册
<zw版·Halcon-delphi系列原创教程> zw版-Halcon常用函数Top100中文速查手册 Halcon函数库非常庞大,v11版有1900多个算子(函数). 这个Top版,对 ...
- 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数001·3D函数
<zw版·Halcon-delphi系列原创教程> Halcon分类函数001·3D函数 为方便阅读,在不影响说明的前提下,笔者对函数进行了简化: :: 用符号“**”,替换:“proce ...
- C++如何在r3静态调用NT函数
原文最早发表于百度空间2010-02-22. 1.把ntapi.h.ntdll.lib放在一个目录,然后设置工具——选项——项目和解决方案——VC++目录——包含文件,把刚刚的目录设置在改包 含文件中 ...
- 调用Nt函数内核模式切换问题
很久不写博客了,笔记大多记在电脑上在,以后整理好了再搬运上来吧. 今天记一下“进程内存管理器”这个小程序上遇到的一个问题——内核模式调用Nt*函数. 使用的是内核中的NtQueryVirtualMem ...
- map函数和filter函数 zip函数
1.map函数 接收一个函数f和一个可迭代对象(列表,字典等),并通过把函数f依次作用在li每个元素上,得到一个新的list并返回 # -*-coding:utf8 -*- import reques ...
- 消息循环中的TranslateMessage函数和DispatchMessage函数,特别注意WM_TIMER消息
原文:http://www.cnblogs.com/xingrun/p/3583357.html TranslateMessage函数 函数功能描述:将虚拟键消息转换为字符消息.字符消息被送到调用线程 ...
- 深入理解javascript函数定义与函数作用域
最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把思路整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径 ...
- JavaScript 函数节流和函数去抖应用场景辨析
概述 也是好久没更新 源码解读,看着房价蹭蹭暴涨,心里也是五味杂陈,对未来充满恐惧和迷茫 ...(敢问一句你们上岸了吗) 言归正传,今天要介绍的是 underscore 中两个重要的方法,函数节流和函 ...
- 如果你也会C#,那不妨了解下F#(4):了解函数及常用函数
函数式编程其实就是按照数学上的函数运算思想来实现计算机上的运算.虽然我们不需要深入了解数学函数的知识,但应该清楚函数式编程的基础是来自于数学. 例如数学函数\(f(x) = x^2+x\),并没有指定 ...
随机推荐
- A + B for you again HDU - 1867(最大前缀&最大后缀的公共子缀&kmp删除法)
Problem Description Generally speaking, there are a lot of problems about strings processing. Now yo ...
- shell习题第17题:检测磁盘
[题目要求] 写一个shell脚本,检测所有磁盘分区使用率和inode使用率并记录到以当天日期命名的日志文件里,当发现某个分区容量或者inode使用量大于85%时候,发邮件提醒 [核心要点] df d ...
- shell习题第12题:批量创建用户
[题目要求] 用shell脚本实现如下需求 添加user_00 -- user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母及数字,注意要把每个用户的密码记录到一个日志文 ...
- 不吹不黑,赞一下应用运维管理的cassacdra
不吹不黑的为菊厂的应用运维管理AOM点个赞.Why? 某菊厂应用运维管理工具AOM每天处理着亿级条数据,这么多数据是怎么存储的呢? 说到数据存储就会想到关系型数据库,比如mysql,oracle,sy ...
- Java优化高性能高并发+高并发程序设计视频教程
转自:https://www.cnblogs.com/ajianku/p/10236573.html 第1章 课程介绍及项目框架搭建1-1 Java高并发商城秒杀优化导学1-2 项目环境搭建(Ecli ...
- 《浏览器工作原理与实践》<02>TCP协议:如何保证页面文件能被完整送达浏览器?
前言: 在衡量 Web 页面性能的时候有一个重要的指标叫“FP(First Paint)”,是指从页面加载到首次开始绘制的时长.这个指标直接影响了用户的跳出率,更快的页面响应意味着更多的 PV.更高的 ...
- 02 js原型链
1 js原型链是一个绕不开的话题.直接上说吧. /** * 1. js里的原型链是怎么样的? 带class 和不带class的原型链的不同. */ const util = require('util ...
- Java&Selenium处理页面Table以及Table中随机位置的数据
一.摘要 前一段时间公司小伙伴刚刚接触自动化,遇到的一个问题,页面新创建的数据保存后,出现在table中的某个位置,并不一定是第一行还是第几行,这种情况下如何去操控它 本篇博文将介绍处理这个问题的一种 ...
- TestNG-Annotations
@BeforeSuite The annotated method will be run before all tests in this suite have run. @AfterSuite ...
- 【Java基础 项目实例--Bank项目5】Account 和 customer 对象等 继承、多态、方法的重写
延续 Java基础 项目实例--Bank项目4 实验要求 实验题目 5: 在银行项目中创建 Account 的两个子类:SavingAccount 和 CheckingAccount 实验目的: 继承 ...