tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1539回复:16

(反弹琵琶)kernel调用user的函数限制?

楼主#
更多 发布于:2002-12-07 10:04
我们知道运行于用户空间的应用程序是不可以直接调用内核提供的函数的,这是由cpu的硬件和操作系统所决定的,那么运行于核心的驱动程序等核心态程序调用函数的问题呢?
1、像sprintf等函数是可以调用的,因为它们好象根本不受运行环境的影响,这是为什么呢?
2、NTDLL里的导出函数。有的可用,有的不可用,导致这种差别的原因是什么?
3、像kernel32.dll、user32.dll、gdi32.dll等的导出函数是完全无法使用的,又是什么原因呢?
最后,如果我们知道了这些原因,能不能通过什么代码或方法去掉这些不同呢?如果能的话那真是太爽了!
 :D

最新喜欢:

flyfoxflyfox
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
OneWind
驱动小牛
驱动小牛
  • 注册日期2002-05-15
  • 最后登录2009-04-10
  • 粉丝0
  • 关注0
  • 积分82分
  • 威望11点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-12-07 13:31
财主说的正是我迷惑的... :D
嘿,大家好!
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-12-07 14:15
我们知道运行于用户空间的应用程序是不可以直接调用内核提供的函数的,这是由cpu的硬件和操作系统所决定的,那么运行于核心的驱动程序等核心态程序调用函数的问题呢?
1、像sprintf等函数是可以调用的,因为它们好象根本不受运行环境的影响,这是为什么呢?
//首先ntoskrnl.exe导出了很多类似于C运行时库的函数,很多人用了却不自知;其次很多代码原就可在核心态与用户态运行(如很多内存拷贝类函数),核心态与用户态的限制没有你想得那么严重,但是本来为用户态设计的代码一旦得到过多权限后果往往致命,比如用户态有相当多的页异常是属系统正常机理,是可继续执行的;再如2000ring0可用printf!而Xp则不行,这与LPC的实现与系统调用方式有关。二者机理并不能寥寥数语来解释。

2、NTDLL里的导出函数。有的可用,有的不可用,导致这种差别的原因是什么?
//严格的说,ntdll导出函数都不应该在核心态使用。Rtl*很多确实能用,理由如上;在2000及以下版本很多nativeAPI也能用,这仍由系统调用方式决定,换了XP就不行。

3、像kernel32.dll、user32.dll、gdi32.dll等的导出函数是完全无法使用的,又是什么原因呢?
//首先说不是“完全”,它们与ntdll是同一类的,都不该用。原理同ntdll,它们做的某些事更多,限制比ntdll大了一点而已。

最后,如果我们知道了这些原因,能不能通过什么代码或方法去掉这些不同呢?如果能的话那真是太爽了!
//部分可行,但无意义,得不偿失。
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-12-07 15:13
感觉“LPC的实现与系统调用方式”比较抽象,不太懂。能不能解释一下?
还有用户态函数如果使用了特权指令,比如IN,OUT,INT等就会导致非法操作,但是对核心态函数来说是没有所谓的不可操作的特殊指令的,那么为什么还有那么多的限制呢?我知道一点,那就是分页内存,在DISPATCH_LEVEL以上不可以访问分页内存。请问还有没有别的限制?
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-12-07 16:03
感觉“LPC的实现与系统调用方式”比较抽象,不太懂。能不能解释一下?
//printf使用的WriteFile用LPC与环境子系统通信。系统调用使用自陷方式还是用特殊指令影响很大。

我知道一点,那就是分页内存,在DISPATCH_LEVEL以上不可以访问分页内存。请问还有没有别的限制?
//这点不是我说的限制,开始我说的就是在PASSIVE_LEVEL下,不必考虑更高级别的调用(虽然有很多C运行时函数可在任意IRQL下工作)。但页异常正是限制的最重要原因,实际上你调用ring3函数出错几乎都是0xE异常。原因之一前面提过了,ring3下页异常是系统机理之一,比如栈空间的扩展就靠它等等;更多的,系统代码本就未考虑这种调用,经过一些比较测试跳转,往往会访问到未在设计范围内的内存,于是死掉,你可在ring0调用一下Sleep(...),跟踪看看。其它冲突因素比如非常小的核心栈等等不那么明显。
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-12-07 16:26
这么说来,要设计内核和用户态都可以使用的或者将用户态代码改成核心态也可以使用的c/c++代码的话,最主要是要注意内存的使用罗?
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-12-07 16:45
这么说来,要设计内核和用户态都可以使用的或者将用户态代码改成核心态也可以使用的c/c++代码的话,最主要是要注意内存的使用罗?

呵呵,“将用户态代码改成核心态”在于原先的代码访问了多少API等资源,相关的都得改掉才是安全的,而这一点就相当于自己写,完全违背了初衷(调用系统强大的ring3服务完成自己难于实现的一些功能)。当然可以用特殊手法切换回ring3再做,但仍是不可靠的。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-12-07 17:10
财主兄怎么突然有闲情了,呵呵
 :cool:
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-12-07 18:54
[quote]这么说来,要设计内核和用户态都可以使用的或者将用户态代码改成核心态也可以使用的c/c++代码的话,最主要是要注意内存的使用罗?

呵呵,“将用户态代码改成核心态”在于原先的代码访问了多少API等资源,相关的都得改掉才是安全的,而这一点就相当于自己写,完全违背了初衷(调用系统强大的ring3服务完成自己难于实现的一些功能)。当然可以用特殊手法切换回ring3再做,但仍是不可靠的。 [/quote]
比如我有JPEG解码的源代码,我要把它放到驱动程序里去解码,不是满有意思吗?
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-12-07 18:56
财主兄怎么突然有闲情了,呵呵
 :cool:

别提了,现在的公司没什么劲。USB驱动程序做完后无事可做。我想考虑换一个真正作核心的公司。公司需要,自己也可以更深入学习一些东西。
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-12-07 18:59
[quote][quote]这么说来,要设计内核和用户态都可以使用的或者将用户态代码改成核心态也可以使用的c/c++代码的话,最主要是要注意内存的使用罗?

呵呵,“将用户态代码改成核心态”在于原先的代码访问了多少API等资源,相关的都得改掉才是安全的,而这一点就相当于自己写,完全违背了初衷(调用系统强大的ring3服务完成自己难于实现的一些功能)。当然可以用特殊手法切换回ring3再做,但仍是不可靠的。 [/quote]
比如我有JPEG解码的源代码,我要把它放到驱动程序里去解码,不是满有意思吗? [/quote]

就看你这代码访问了哪些API喽? :D
[color=red]大头鬼! :P[/color]
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-12-07 19:14
比如我有JPEG解码的源代码,我要把它放到驱动程序里去解码,不是满有意思吗?


只要核心算法是自己写的,移到核心态做改动不多啊,计算性质的代码本无所谓权级。但是核心态程序所能用资源甚少,浮点运算亦很不如别人方便,如果不是特殊需要,没有理由这么做嘛。比如ring3的解码程序顺手就可在函数里写char buf[2500];核心态就不行。
ygxm
驱动牛犊
驱动牛犊
  • 注册日期2002-04-26
  • 最后登录2003-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-12-08 01:13
开发核心态程序,可使用内存大小受到限制,如果我要处理的数据量比较大(超1M),用什么办法可以调用更大的内存空间呢?
lifeship
驱动小牛
驱动小牛
  • 注册日期2002-10-18
  • 最后登录2005-07-19
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-12-08 19:48
首先,用户太代码一般不能被核心态调用,但是事实上,很多代码也能被核心态调用,而条件是他们本身也处于核心太,
其二, 在核心态运行代码要考虑到irql 的变化,有的代码在某些irql 上不能运行,所以,要的代码运行,必须处于正确的irql,而用户太代码一般是在passive下运行的,超出了这个范围,可能会出错
杯汝前来,  老子今朝,  放荡形骸!  甚长年抱渴,  咽如焦釜,  于今喜醉,  气似奔雷!  慢说刘伶,  古今达者,  醉后何妨死便埋! 
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-12-08 20:18
首先,用户太代码一般不能被核心态调用,但是事实上,很多代码也能被核心态调用,而条件是他们本身也处于核心太,
----------------------------------------------------
为用户态写的代码被ring0程序调用运行于ring0,这是必然而不是“条件”。


其二, 在核心态运行代码要考虑到irql 的变化,有的代码在某些irql 上不能运行,所以,要的代码运行,必须处于正确的irql,而用户太代码一般是在passive下运行的,超出了这个范围,可能会出错
-----------------------------------------------------
re时看完贴子先 :o
kernel_kernel
驱动小牛
驱动小牛
  • 注册日期2002-12-08
  • 最后登录2009-02-06
  • 粉丝0
  • 关注0
  • 积分435分
  • 威望51点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-12-08 21:12
开发核心态程序,可使用内存大小受到限制,如果我要处理的数据量比较大(超1M),用什么办法可以调用更大的内存空间呢?


内存池还是分得出1M的东西来的嘛;要是上10M甚至更多只好修改系统启动项让它空一批内存了,不好 :P
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-12-09 08:43
其实我只是有这个想法和疑问,并不是要实际做什么东西。感谢各位!
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
游客

返回顶部