能力值:
( LV7,RANK:110 )
|
-
-
2 楼
以上代码我测试了一下,好像在WIN7中蓝屏
|
能力值:
( LV12,RANK:760 )
|
-
-
3 楼
SeCreateAccessState时某个参数的大小不对,于是蓝屏了~
AUX_ACCESS_DATA的实际大小要比DDK里定义的大小要大不少,跟DriverObject类似~
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
还是V大牛呀。建议LZ修正后发个完整工程
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
mark
以后回头来看
|
能力值:
( LV4,RANK:50 )
|
-
-
6 楼
发出来 估计就不能用了
|
能力值:
( LV9,RANK:610 )
|
-
-
7 楼
http://hi.baidu.com/_achillis/blog/item/23b32a28ad5bdef298250a0c.html
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
强贴留名。
|
能力值:
( LV9,RANK:160 )
|
-
-
9 楼
膜拜教主,自己确实没在Windows7下测试……
|
能力值:
( LV12,RANK:760 )
|
-
-
10 楼
其实对付这种情况有一个统一的有效的方法就是直接申请1MB的nonpagedpool给它呀玩~
|
能力值:
( LV9,RANK:610 )
|
-
-
11 楼
有效是有效,但也得先知道原因在哪儿才行啊~~
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
这个的原因是为什么呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
下载了符号后就一目了然了。。。
|
能力值:
( LV9,RANK:610 )
|
-
-
14 楼
有符号怎么了?有符号就什么都看得出来了?undocument的东西啊~~
|
能力值:
( LV12,RANK:470 )
|
-
-
15 楼
人家可能是用的私有符号
貌似只有私有符号里面有变量和结构的实际大小
|
能力值:
( LV12,RANK:470 )
|
-
-
16 楼
引用的文字都保存到论坛里面一份,下文出处是教主的blog
这也许是我这个假期唯一做的跟Code有关的事了,已经一个多月没写代码了~~ 问题是这样的,某同学A,在自己的工程中使用了PsVoid的部分驱动源码(感谢炉子开源~~),提到里面的IrpCreateFile函数在Win7下始终会蓝屏,希望我能帮忙解决一下。于是,拿出调试器开始debug之旅~~ 先简单介绍下,IrpCreateFile中PsVoid中Irp文件操作库中的一个函数,主要功能就是直接发IRP实现文件打开操作。该函数在 WinXP/2003下均正常工作,但是在Win7下总是会蓝屏。写了个测试驱动扔到Vmware里,挂上调试器跟踪了一下,初步发现问题出在填充完 IRP准备向下IoCallDriver时。现场如下: kd> u IofCallDriver nt!IofCallDriver: 83a7b458 8bff mov edi,edi 83a7b45a 55 push ebp 83a7b45b 8bec mov ebp,esp 83a7b45d 51 push ecx 83a7b45e a15c7aba83 mov eax,dword ptr [nt!pIofCallDriver (83ba7a5c)] 83a7b463 56 push esi 83a7b464 8bf1 mov esi,ecx //DeviceObject参数保存至esi 83a7b466 33c9 xor ecx,ecx .... 83a88492 8a08 mov cl,byte ptr [eax] //eax指向IoStackLocation,這里是判断MajorFunction 83a88494 897014 mov dword ptr [eax+14h],esi //取刚才保存的DeviceObject参数,赋给IrpStack->DeviceObject 83a88497 80f916 cmp cl,16h 83a8849a 7514 jne nt!IofCallDriver+0x57 (83a884b0) kd> p nt!IofCallDriver+0x57: 83a884b0 8b4608 mov eax,dword ptr [esi+8] //取DeviceObject->DriverObject,很不幸这里DeviceObject是NULL,于是杯具发生了。。。 大概就是这样的,DeviceObject是IrpCreateFile函数中的一个局部变量,当IoCallDriver时DeviceObject参数竟然是NULL,那取DeviceObject->DriverObject必然会蓝屏了~~ 刚开始,我怀疑前面取到的DeviceObject就是NULL,代码如下: DbgPrint("The Volume FileObject=0x%08X\n",pFile); DeviceObject = pFile->Vpb->DeviceObject; DbgPrint("pFile->Vpb->DeviceObject = 0x%08X\n",DeviceObject); RealDevice = pFile->Vpb->RealDevice; DbgPrint("pFile->Vpb->RealDevice = 0x%08X\n",RealDevice); 但是再次调试,发现这里是正常的,DeviceObject的值有效,不知怎的在准备IoCallDriver时变成了0,于是,再次调试~~ 这次调试时,密切监视DeviceObject值的变化。终于发现,在走过以下代码之后,DeviceObject变成了0 RtlZeroMemory(&AuxData, sizeof(AUX_ACCESS_DATA)); ntStatus = SeCreateAccessState( &AccessState, &AuxData, DesiredAccess, IoGetFileObjectGenericMapping()); 在调用完SeCreateAccessState之后,DeviceObject变成了0,很莫名的问题啊。不过,目标已经锁定在SeCreateAccessState,再重启,再次来过。。。 过程如下: 在IrpCreateFile中: //DeviceObject = pFile->Vpb->DeviceObject; 93f14759 8b4df4 mov ecx,dword ptr [ebp-0Ch] 93f1475c 8b5108 mov edx,dword ptr [ecx+8] 93f1475f 8b4208 mov eax,dword ptr [edx+8] 93f14762 898550ffffff mov dword ptr [ebp-0B0h],eax //DeviceObject保存在了ebp-b0处,如下: kd> dd ebp-b0 807e1994 85bcb020 00000006 807e19b4 83e16b29 //可以看到,此时DeviceObject=85bcb020,是有效值 807e19a4 83b2ac02 80000574 3c8fb9d2 83b2ac02 807e19b4 807e19c0 83e16cca 534fa145 807e19d0 继续往下,一直到调用SeCreateAccessState之前,这个值都没有变化。 到了SeCreateAccessState,跟进去,发现这个函数只是直接调用了SeCreateAccessStateEx函数,WRK中源码如下,Win7中也没什么变化。 NTSTATUS SeCreateAccessState( __out PACCESS_STATE AccessState, __out PAUX_ACCESS_DATA AuxData, __in ACCESS_MASK DesiredAccess, __in_opt PGENERIC_MAPPING GenericMapping ) { return SeCreateAccessStateEx (PsGetCurrentThread (), PsGetCurrentProcess (), AccessState, AuxData, DesiredAccess, GenericMapping); } 继续跟进至SeCreateAccessStateEx。。。 发现了两个memset调用~~ kd> nt!SeCreateAccessStateEx+0x23: 83c6f633 e8e0440400 call nt!RtlMapGenericMask (83cb3b18) 83c6f638 8b7d10 mov edi,dword ptr [ebp+10h] //取第三个参数至edi 83c6f63b 6a74 push 74h 83c6f63d 6a00 push 0 83c6f63f 57 push edi 83c6f640 e8fbe7e0ff call nt!memset (83a7de40) //将第三个参数AccessState指向的内存清零 83c6f645 8b7514 mov esi,dword ptr [ebp+14h] ////取第三个参数至esi 83c6f648 83c40c add esp,0Ch 83c6f64b 68c0000000 push 0C0h 83c6f650 6a00 push 0 83c6f652 56 push esi 83c6f653 e8e8e7e0ff call nt!memset (83a7de40) //将第四个参数AuxData指向的内存清零 这两句对应于以下代码: RtlZeroMemory(AccessState, sizeof(ACCESS_STATE)); RtlZeroMemory(AuxData, sizeof(AUX_ACCESS_DATA)); //在SeCreateAccessStateEx这个函数中: kd> p nt!SeCreateAccessStateEx+0x3b: 83c3664b 68c0000000 push 0C0h 83c36650 6a00 push 0 83c36652 56 push esi 83c36653 e8e8e7e0ff call nt!memset (83a44e40) //准备清零 kd> dd esp l4 8cc678cc 8cc6793c 00000000 000000c0 8cc67958 //memset的参数 kd> dd 8cc67994 //此时局部变量DeviceObject的值,仍然是正确值 8cc67994 85bd4020 00040001 00000000 8cc679a0 8cc679a4 8cc679a0 80000648 00000000 00000000 kd> ? 8cc6793c+c0 Evaluate expression: -1933149700 = 8cc679fc 也就是说,要memset清零的区域是从8cc6793c到8cc679fc, 我们的局部变量的地址8cc67994就在这之间,于是被清零了。。。
为什么会出现这样一个结果呢?AuxData是一个结构体,该参数是从IrpCreateFile中传过来的,和DeviceObject都是局部变量。而现在,对AuxData的操作竟然影响到了DeviceObject,能想到的,就是从他们在栈中的布局入手了。
可以看到,AuxData位于ebp-108h处,与它相邻的局部变量是SourceString,位于ebp-ECh处。 也就是说,AuxData的实际大小只有0x108-0xEC=0x1C 而在SeCreateAccessStateEx中,我们明显可以看到系统认为这个结构的大小是0xC0,那么进行memset时,实际影响的范围是 从ebp-108h到ebp-108h+0xC0=ebp-48h,而我们的局部变量DeviceObject位于ebp-B0h处,正位于这个范围之间,于是就被清零了,同样受影响的还有位于该范围内的 SourceString,NameBuffer,ntStatus,ObjectAttributes,DeviceObject,Event,Handle,AccessState 等局部变量,如果要再使用这些变量的话,同样会出现问题,比如你要使用Handle的时候,发现竟然成无效句柄了。。。 所以,根本原因就是使用了不正确的结构定义,导致SeCreateAccessStateEx函数对局部变量AuxData清零初始化时同时修改了其它局部变量的值。 原因既然找到了,解决起来就容易了。经询问,A同学说这个结构是他根据PsVoid源码中的定义自己修改的,是一个未文档化的结构。恩,未文档化的东西,用起来难免会有不可靠的时候啊~~~ 解决方案:修改AUX_ACCESS_DATA的定义就行了。该结构原来的定义为: typedef struct _AUX_ACCESS_DATA { PPRIVILEGE_SET PrivilegesUsed; GENERIC_MAPPING GenericMapping; ACCESS_MASK AccessesToAudit; ACCESS_MASK MaximumAuditMask; } AUX_ACCESS_DATA, *PAUX_ACCESS_DATA; 该结构现在的大小为0x1C,而Win7中该结构实际大小为0xC0。(0xC0-0x1C)/sizeof(ULONG)=0x29=41,那么修改定义如下: typedef struct _AUX_ACCESS_DATA { PPRIVILEGE_SET PrivilegesUsed; GENERIC_MAPPING GenericMapping; ACCESS_MASK AccessesToAudit; ACCESS_MASK MaximumAuditMask; ULONG Unknown[41]; } AUX_ACCESS_DATA, *PAUX_ACCESS_DATA; 修改之后,经测试,蓝屏问题解决~~
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
有效是有效,但也得先知道原因在哪儿才行啊~~
|
能力值:
( LV9,RANK:610 )
|
-
-
18 楼
私有符号我知道,但是问题就是这玩意儿一般人没有吧~~
|
能力值:
( LV12,RANK:760 )
|
-
-
19 楼
原因直接用意念猜测就行了。话说那个IrpCreateFile看起来很眼熟。
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
强 留名强 留名
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
你好,能发一份修正的吗?这个win7下蓝屏
|