驱动老牛
|
阅读:5411回复:34
如何让我的驱动程序在安全模式下启动
一般情况下自己的驱动在安全模式下就没用了,怎么能让驱动程序在安全模式下也能启动?
|
|
沙发#
发布于:2004-12-29 11:24
好像很难,关注学习中。。。
|
|
|
板凳#
发布于:2004-12-29 16:02
设为start=0是不是可以?
|
|
地板#
发布于:2004-12-29 19:54
关注。
|
|
|
驱动老牛
|
地下室#
发布于:2004-12-30 09:38
设置为BOOT启动是可以解决部分驱动程序安全模式加载,但是对于文件系统过滤驱动似乎不行啊,挂不上去。
|
|
5楼#
发布于:2005-01-04 10:29
要把文件系统过滤驱动依赖的所有驱动都设成0级启动也许可以吧。
|
|
6楼#
发布于:2005-01-06 09:07
设置为BOOT启动是可以解决部分驱动程序安全模式加载,但是对于文件系统过滤驱动似乎不行啊,挂不上去。 怎么不行了? 当然能挂上去, 而且也没有特别考虑什么. 就是把start设成0, 然后加到filter组去. |
|
7楼#
发布于:2005-01-07 17:41
安全模式下自动运行exe程序呢?
|
|
|
8楼#
发布于:2005-01-10 09:22
顶一下,关注中。。。
|
|
|
9楼#
发布于:2005-01-10 17:18
顶一下,我也想知道……
|
|
10楼#
发布于:2005-01-11 14:05
current control set 下safeboot
添加一个driver或者driver group就ok.... 改start=0是不对的方法.............. 难道安全模式就不加载start非0的驱动了么...... ddk上不是有写得很清楚得么 诸如device driver book或者windows driver model上面都有讲得啊....... 自己打开这个key看看就明白了..... |
|
11楼#
发布于:2005-01-11 16:36
谢谢tiamo指点.
不过并不是说要改start=0. 而是作为文件过滤就要设成start=0,并且加到filter组中. 我当时做项目就是这么做的, 没有刻意去考虑安全模式下启动的问题. 不过在代码中有专门针对安全模式的处理, 免得到时候出了问题机器起不来. toad |
|
12楼#
发布于:2005-01-12 08:14
理论一下...
start=0跟safeboot是完全不相关得两个事情好不好.. 为什么要把start=0并加到filter里面难道是为了safeboot么 safeboot下filter能加载是因为她得start=0么.. 两个风马牛不相及得事情... 至于为什么你那样作了就能在safeboot下使用... 那是因为safeboot下会加载filter这个driver group... 你把这个driver group删掉看看... start=0加入filter是一个filter本身的要求... 而safeboot与否与driver本身没有必然的联系.... 以上 |
|
驱动老牛
|
13楼#
发布于:2005-01-12 09:35
我试过了,REGMON之类的NATIVE HOOK驱动还是不行
|
|
14楼#
发布于:2005-01-12 10:07
1. 我从来没有说start=0和safeboot是相关的. 我只说了我是怎么做的, 有什么结果. 我也没说过我那么做的原因是为了safeboot. 你的那些问题全是你的联想.
2. 我查了IFSDDK2003, The Windows 2000 Device Driver Book(2nd Edition) by Art Baker, Programming the Microsoft Windows Driver Model(1st, 2nd Edition) by Walter Oney, 里面都没有说到safeboot. 我不知道你为什么在你的贴子里提了这几本书. 3. 我原来不知道为什么加入filter就能在safemode被load了, 你又知道为什么加入safeboot就能在safemode被load吗? 不都是windows缺省时用了那个键吗? 你要我把那个group删掉试试看, 那我还能说你把ntoskrnl patch一下试试看? @#$%^&* 4. "start=0加入filter是一个filter本身的要求". 不对!!! 只是我是这么做的. 事实上在XP下这两者都不需要. 5. "safeboot与否与driver本身没有必然的联系". 不对. driver可以判断是不是safemode来决定是不是load自己. |
|
15楼#
发布于:2005-01-12 13:58
driver可以判断是不是safemode来决定是不是load自己
如何判断SAFEMODE??? |
|
|
驱动老牛
|
16楼#
发布于:2005-01-12 14:48
SafeMood的时候操作系统怎么决定加载那些驱动的?
|
|
17楼#
发布于:2005-01-12 15:17
Q837643有说怎么从驱动里detect安全模式.
toad |
|
18楼#
发布于:2005-01-12 21:30
哟...有人跟我叫板....
既然自己有这么多只是知道然不知道所以然得东西... 是不是应该要谦虚一点呢.... 第一点..既然你强调那么清楚..那就算是我理解错误行了吧.呵呵 第二点..我记得我自己是在这些地方都看到有提到过...如果这些里面都没有的话..那我表示道歉.. 第三点..这个我可以肯定的说..我是知道为什么加入safeboot就能在safe mode下使用..至于你说什么ntoskrnl打patch一类的话...如果你要这样说的话..我也就没有语言了..你怎么不叫我把cpu给拔下来看看是不是还能在安全模式下加载呢..这种争论有任何的意义么..自己不知道为什么的事情是不是应该用一种谨慎的态度呢.. 第四点..我只能说你理解的有问题..好好看看ddk里面的文档..一个file system filter都应该是一个什么样子的group... 第五点..driver判断是否加载?什么意思...你代码是怎么运行的?os不加载你的driver,你能写下if else语句来判断当前是否是安全模式再决定加载不加载自己么...你的代码不运行你有办法知道当前的模式么....表告诉我你说的是在driverentry里面返回一个错误啊... 说正题...windows在安全模式下都加载什么样子的driver 其实很简单...下面都是指没有被第三方打过patch的系统 在current control set 下的control下面的safeboot 下面有两个key 一个是Minimal一个是Network 简单的情况就是你按f8出来的菜单选安全模式就使用Minimal 如果你选带网络的安全模式就是Network 这两个key下面还有很多的key 每一个标记了一个或者一组要在安全模式下加载的驱动 这下面的每一个key的default都有设置值 要么是driver..就表示这个key的名字代表了一个要加载的driver 要么是driver group..就表示这个key代表了一个driver group 所有属于这个group的driver都会被加载... 凡是没有被这些描述到的driver都不会被加载... 或者是Service表示这是一个服务 如果是GUID形式的key那表示是一个class 我记得我是在好几个地方看到过这个描述的.. 至于出处....如果真的确认是我说的不对...那我道歉... 如果你觉得描述的不好理解 代码贴上来... windows 2003 server up ntoskrnl.exe PAGE:805C0A2D ; __stdcall IopLoadDriver(x,x,x,x) PAGE:805C0A2D _IopLoadDriver@16 proc near PAGE:805C0A2D push ebp PAGE:805C0A2E lea ebp, [esp-68h] ...... 判断第一个参数是否是0.是则跳过安全模式检查 如果不是0还要检查_InitSafeBootMode变量值 都满足了跳转 PAGE:805C0B32 cmp [ebp+74h], bl ;arg0 PAGE:805C0B35 jz short loc_805C0B43 PAGE:805C0B37 cmp _InitSafeBootMode, ebx PAGE:805C0B3D jnz loc_80601AC6 PAGE:805C0B43 push 1 PAGE:805C0B45 mov edi, offset _PsLoadedModuleResource PAGE:805C0B4A push edi PAGE:805C0B4B call _ExAcquireResourceSharedLite@8 ........ 获取Group的值 PAGE:80601AC6 push offset aGroup PAGE:80601ACB lea eax, [ebp+38h] PAGE:80601ACE push eax PAGE:80601ACF call _RtlInitUnicodeString@8 PAGE:80601AD4 push 13h PAGE:80601AD6 pop ecx PAGE:80601AD7 xor eax, eax PAGE:80601AD9 lea edi, [ebp-38h] PAGE:80601ADC rep stosd PAGE:80601ADE lea eax, [ebp+74h] PAGE:80601AE1 push eax PAGE:80601AE2 push 4Ch PAGE:80601AE4 lea eax, [ebp-38h] PAGE:80601AE7 push eax PAGE:80601AE8 push 2 PAGE:80601AEA lea eax, [ebp+38h] PAGE:80601AED push eax PAGE:80601AEE push dword ptr [ebp+70h] PAGE:80601AF1 call _NtQueryValueKey@24 PAGE:80601AF6 test eax, eax PAGE:80601AF8 jl short loc_80601B1F 用这个group的值作为参数调用_IopSafebootDriverLoad函数 检查返回值如果是TRUE就跳转到加载代码(805C0B43) PAGE:80601AFA mov eax, [ebp-30h] PAGE:80601AFD add eax, 0FFFFFFFEh PAGE:80601B00 mov [ebp+38h], ax PAGE:80601B04 mov [ebp+3Ah], ax PAGE:80601B08 lea eax, [ebp-2Ch] PAGE:80601B0B mov [ebp+3Ch], eax PAGE:80601B0E lea eax, [ebp+38h] PAGE:80601B11 push eax PAGE:80601B12 call _IopSafebootDriverLoad@4 PAGE:80601B17 test al, al PAGE:80601B19 jnz loc_805C0B43 如果是FALSE 则再用driver的名字作为参数调用_IopSafebootDriverLoad函数 PAGE:80601B1F lea eax, [ebp+5Ch] PAGE:80601B22 push eax PAGE:80601B23 call _IopSafebootDriverLoad@4 PAGE:80601B28 test al, al PAGE:80601B2A jnz loc_805C0B43 如果返回TRUE则正常加载(805C0B43) 如果还是返回FALSE,则加入一个bootlog 同时dbgprint SAFEBOOT: skipping device = %wZ(%wZ),0Ah的字符串 PAGE:80601B30 push ebx PAGE:80601B31 lea eax, [ebp+5Ch] PAGE:80601B34 push eax PAGE:80601B35 call _IopBootLog@8 PAGE:80601B3A lea eax, [ebp+38h] PAGE:80601B3D push eax PAGE:80601B3E lea eax, [ebp+5Ch] PAGE:80601B41 push eax PAGE:80601B42 push offset aSafebootSkippi PAGE:80601B47 call _DbgPrint PAGE:80601B4C add esp, 0Ch PAGE:80601B4F push ebx PAGE:80601B50 push 2 PAGE:80601B52 call _HeadlessKernelAddLogEntry@8 PAGE:80601B57 xor eax, eax PAGE:80601B59 jmp loc_805C074E 再看看关键函数 PAGE:806398BB ; __stdcall IopSafebootDriverLoad(x) PAGE:806398BB _IopSafebootDriverLoad@4 proc near PAGE:806398BB push ebp PAGE:806398BC mov ebp, esp PAGE:806398BE sub esp, 18h 先根据_InitSafeBootMode的值选择一个key string PAGE:806398C1 mov eax, _InitSafeBootMode PAGE:806398C6 dec eax ;eax =1 Minimal PAGE:806398C7 jz short loc_806398E4 PAGE:806398C9 dec eax ;eax = 2 Network PAGE:806398CA jz short loc_806398DD PAGE:806398CC dec eax ;eax = 3 直接返回1 PAGE:806398CD jz short loc_806398D6 PAGE:806398CF xor al, al 否则返回0 PAGE:806398D1 jmp locret_806399B3 PAGE:806398D6 mov al, 1 PAGE:806398D8 jmp locret_806399B3 PAGE:806398DD push offset aNetwork ; "NETWORK" PAGE:806398E2 jmp short loc_806398E9 PAGE:806398E4 push offset aMinimal ;"MINIMAL" PAGE:806398E9 lea eax,[ebp+SourceString] PAGE:806398EC push eax PAGE:806398ED call _RtlInitUnicodeString@8 PAGE:806398F2 push ebx PAGE:806398F3 push esi PAGE:806398F4 mov esi, [ebp+arg_0] PAGE:806398F7 xor eax, eax PAGE:806398F9 mov ax, [esi] PAGE:806398FC add ax, [ebp+SourceString.Length] 分配内存放key PAGE:80639900 push ' oI' PAGE:80639905 xor ebx, ebx PAGE:80639907 mov word ptr [ebp+Destination], bx PAGE:8063990B add eax, 8 PAGE:8063990E mov word ptr [ebp+Destination+2], ax PAGE:80639912 movzx eax, ax PAGE:80639915 push eax PAGE:80639916 push 1 PAGE:80639918 call _ExAllocatePoolWithTag@12 PAGE:8063991D cmp eax, ebx PAGE:8063991F mov [ebp-0Ch], eax PAGE:80639922 jnz short loc_8063992B PAGE:80639924 xor al, al ;失败直接返回0 PAGE:80639926 jmp loc_806399B1 PAGE:8063992B lea eax, [ebp+SourceString] PAGE:8063992E push eax PAGE:8063992F lea eax, [ebp+Destination] PAGE:80639932 push eax PAGE:80639933 call _RtlCopyUnicodeString@8 PAGE:80639938 push offset asc_806399D8 ;反斜杠 PAGE:8063993D lea eax, [ebp+Destination] PAGE:80639940 push eax PAGE:80639941 call _RtlAppendUnicodeToString@8 PAGE:80639946 test eax, eax PAGE:80639948 jl short loc_806399A2 PAGE:8063994A push esi PAGE:8063994B lea eax, [ebp+Destination] PAGE:8063994E push eax PAGE:8063994F call _RtlAppendUnicodeStringToString@8 根据当前的模式..生成key string PAGE:80639954 test eax, eax PAGE:80639956 jl short loc_806399A2 PAGE:80639958 push ebx PAGE:80639959 mov esi, 0F003Fh PAGE:8063995E push esi PAGE:8063995F push offset _CmRegistryMachineSystemCurrentControlSetControlSafeBoot PAGE:80639964 push ebx PAGE:80639965 lea eax, [ebp+KeyHandle] PAGE:80639968 push eax PAGE:80639969 call _IopOpenRegistryKey@20 打开这个safeboot key,失败就跳转 PAGE:8063996E test eax, eax PAGE:80639970 jl short loc_806399A2 然后打开生成的key string PAGE:80639972 push ebx PAGE:80639973 push esi PAGE:80639974 lea eax, [ebp+Destination] PAGE:80639977 push eax PAGE:80639978 push [ebp+KeyHandle] PAGE:8063997B lea eax, [ebp+var_8] PAGE:8063997E push eax PAGE:8063997F call _IopOpenRegistryKey@20 关闭safe bootkey PAGE:80639984 push ebx PAGE:80639985 push [ebp+KeyHandle] PAGE:80639988 mov esi, eax PAGE:8063998A call _ObpCloseHandle@8 判断打开成功与否失败了就跳转,否则关闭 PAGE:8063998F cmp esi, ebx PAGE:80639991 jl short loc_806399A2 PAGE:80639993 push ebx PAGE:80639994 push [ebp+var_8] PAGE:80639997 call _ObpCloseHandle@8 设置返回值1 PAGE:8063999C mov byte ptr [ebp+arg_0+3], 1 PAGE:806399A0 jmp short loc_806399A5 失败了就跳转到这里,设置返回值0 PAGE:806399A2 mov byte ptr [ebp+arg_0+3], bl 释放key string的内存 PAGE:806399A5 push ebx PAGE:806399A6 push dword ptr [ebp-0Ch] PAGE:806399A9 call _ExFreePoolWithTag@8 设置返回的eax PAGE:806399AE mov al, byte ptr [ebp+arg_0+3] 返回 PAGE:806399B1 pop esi PAGE:806399B2 pop ebx PAGE:806399B3 leave PAGE:806399B4 retn 4 非常清楚了...这个函数很简单 除了几个特别处理的返回地方 其他的都是用[ebp+arg_0+3]作为返回值 修改她的地方有两个 一个就是出错跳转的地址806399A2,设置成0 ebx一直是0 另外一个就是所有条件都满足了设置成了1 我想...我要说的已经很明白了... 没有什么好争论的了吧...代码面前.. 如果有人觉得我说得话有些过分或者其他的 我在这里道歉.... 以上 调整了下排版 [编辑 - 1/12/05 by tiamo] |
|
19楼#
发布于:2005-01-13 06:27
> 既然自己有这么多只是知道然不知道所以然得东西...
一切工业产品都是在component的基础上的. 只要知道接口(然)就行了, 不需要知道具体的实现过程(所以然). 如果你要往里追究, 你的程序是跑在OS上的, OS跑在CPU上, CPU里面有复杂的解码和时序电路, 这些你又知道多少? 当然是知道得越多越好, 可是只要接口定义得好, 内部机制其实什么都不需要知道. 我们希望知道WINDOWS的内部机制, 是因为WINDOWS的接口定义不全/不好, 现有接口使我们无法完成目标. > 是不是应该要谦虚一点呢.... 真不明白你说的是什么. 谦虚? 你是不是在这社会上混的? 现在社会需要的是自信! 找过工作的人都知道, 谦虚只会让你失去一次次的工作机会. 退一步说, 这个BBS是给大家讨论问题的, 不是发表专利的. 我发一个贴子是因为我自己认为这是对的, 也许客观上这是错的, 这叫不谦虚吗? 我是不是要先找MS去认证一下我的观点是正确的, 然后才能贴出来? 关于第三点, filter组和ntoskrnl本来就都是OS的成分. 如果你能用更改OS的东西(删filter组看看)来证明你的观点, 为什么我不能用改OS的东西(patch kernel)来反驳它呢? 关于第四点, 给你贴一个IFSDDK上的原话: If a file system filter driver does not specify a load order group, it is loaded after all other drivers of the same start type that do specify a load order group. 这很清楚地说明了, 文件过滤驱动可以不属于任何group. 关于第五点, 当然不能在DriverEntry里面简单地返回一个错误码, 不同的驱动处理方式不一样. 具体在Q837643里有描述. 最后我也贴一段代码: NTSTATUS IopLoadDriver( IN HANDLE KeyHandle, IN BOOLEAN CheckForSafeBoot ) { ... if (CheckForSafeBoot && InitSafeBootMode) { ... bLoadInSafeMode = IopSafebootDriverLoad(...); ... } ... } 如果CheckForSafeBoot是FALSE, 那么不管当前是不是安全模式,更不管这个驱动是不是在tiamo所说的注册表中的位置, 系统都会试图去LOAD这个驱动. PNP就是这么LOAD驱动的. toad |
|
上一页
下一页