首页
社区
课程
招聘
[讨论]ntdll 中 为什么有两套相同函数 ZwXXX 和 NtXXX ?
发表于: 2011-8-23 14:46 8048

[讨论]ntdll 中 为什么有两套相同函数 ZwXXX 和 NtXXX ?

2011-8-23 14:46
8048
看一些代码里有的是用 NtXXX 有的是用 ZwXXX,所以想看一下它们的区别

#include <windows.h>
#include <stdio.h>


typedef void (*myproc)(LPSTR);

int main(int argc, char* argv[]){

	if(argc<2){
		printf("Usage: S libName FuncName\n");
		exit(0);
	}

	HINSTANCE libAddr;
	myproc funcAddr;

	libAddr = LoadLibrary(argv[1]);
	printf("%s addr: 0x%8x\n", argv[1], libAddr);
	if(argc>2) {
		funcAddr = (myproc)GetProcAddress(libAddr, argv[2]);
		printf("%s addr: 0x%8x\n", argv[2], funcAddr);
	}

	return 0;
}


执行用以上函数
G:\>s ntdll ZwQueryInformationThread
ntdll addr: 0x77890000
ZwQueryInformationThread addr: 0x778d54b0

G:\>s ntdll NtQueryInformationThread
ntdll addr: 0x77890000
NtQueryInformationThread addr: 0x778d54b0

可以看到 ZwQueryInformationThread 和 NtQueryInformationThread 是一样的
为什么要提供2个名字?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
2
ntdll里没区别~
ntos里有区别~
2011-8-23 14:52
0
雪    币: 57
活跃值: (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
是stub 一个给内核用的 (native)一个给win32 子系统
2011-8-23 15:04
0
雪    币: 793
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
在RING3下,应用程序调用NT或者ZW效果是一样的 就像楼主指出的
在RING0下,调用NT函数跟ZW函数就不一样了
ZW开头的函数是通过eax中系统服务号去SSDT中查找相应的系统服务,然后调用之
若在驱动中直接调用NT开头的函数是不会经过SSDT的 也不会被SSDT HOOK拦截的
即:在R0下通过调用NT系列函数可以绕过SSDT HOOK
所以微软不推荐你使用Native API 而是让你用WIN32 API
2011-8-23 15:25
0
雪    币: 196
活跃值: (96)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
多谢,大致了解了。
2011-8-23 18:15
0
雪    币: 292
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
的确,用户态确实没什么区别。
内核态下,两者最大的区别在于Zw系列的函数会正确设置previousMode是用户态还是内核态。

参见下面的引文:
The NtXxxx version of the native system service is the name of the function
itself. Thus, when a Kernel Mode component calls the NtXxxx version of the
system service, whatever is presently set into previous mode is unchanged.
Thus, it is quite possible that the Kernel component could be running on an
arbitrary User stack, with the requestor mode set to User. The system service
will not know any better, attempt to validate the request parameters, possibly
using the credentials of the arbitrary User Mode thread, and thus possibly fail
the request. Another problem here is that one step in the validation process
for a User Mode request is that all passed in bu®ers have either ProbeForRead
or ProbeForWrite executed on them, depending on the bu®er's usage. These
routines raise exceptions if executed on Kernel Mode addresses. Therefore,
if you pass in Kernel Mode bu®ers with your request mode set to User, your
calls into the native API return STATUS ACCESS VIOLATION.
The moral of this bedtime story is that if you are in User Mode, use
whatever variant you think makes your code look pretty. In Kernel Mode,
use the ZwXxx routines and get your previous mode set properly, to Kernel
Mode.
2011-8-23 19:13
0
雪    币: 212
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
刚有这疑问,感谢 LZ 提的问题~
顺便问下 Rtl 开头的函数是什么意思的?
Nt 是 native 的意思?
那 Zw 呢?

PS:小菜想了解下它们各是什么的简写~
2011-8-23 19:32
0
雪    币: 793
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
ZW NT RTL 都是微软未公开的函数,之所以未公开主要是因为这些函数大部分功能太强大了,把他们公开会让一些别有用心的人利用。
ZW 跟NT的区别上面解释了
Zw: Mirror entry point for system services (beginning with Nt) that sets previous access mode to kernel, which eliminates parameter validation, since Nt system services validate parameters only if previous access mode is user
RTL:Run-time library
Rtl函数是windows ddk提供的编写驱动的函数。
2011-8-23 20:10
0
雪    币: 544
活跃值: (264)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
9
微软闲得蛋疼
2011-8-23 21:49
0
雪    币: 212
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
回家荒废了一点时间,来晚了,感谢牛牛指导!
2011-8-30 10:46
0
游客
登录 | 注册 方可回帖
返回
//