首页
社区
课程
招聘
[求助]在dispatch_level下的wcslen使用问题
发表于: 2013-5-31 18:22 10233

[求助]在dispatch_level下的wcslen使用问题

2013-5-31 18:22
10233
对测试驱动开启Verifier的标准设置,随后蓝屏,蓝屏代码指向如下:
if (wcslen(processPath) < MAX_PATH)
{
    ....
}
该段代码运行在dispatch_level,且processPath在非分页内存中分配,蓝屏调试信息如下:

1: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 8c786f98, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: 871dcb5e, address which referenced memory

Debugging Details:
------------------

READ_ADDRESS:  8c786f98 Special pool

CURRENT_IRQL:  2

FAULTING_IP:
SecMon!InsertProcessNotifyLog+9e [d:\test\secmon64\processnotify.c @ 121]
871dcb5e 668b08          mov     cx,word ptr [eax]

DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT

BUGCHECK_STR:  0xD1

PROCESS_NAME:  services.exe

TRAP_FRAME:  83301420 -- (.trap 0xffffffff83301420)
ErrCode = 00000000
eax=8c786f98 ebx=8da4e030 ecx=8c786f98 edx=8c786f9a esi=8e4a3690 edi=8da4ed48
eip=871dcb5e esp=83301494 ebp=833014e4 iopl=0         nv up ei ng nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010286
SecMon!InsertProcessNotifyLog+0x9e:
871dcb5e 668b08          mov     cx,word ptr [eax]        ds:0023:8c786f98=0063
Resetting default scope

LAST_CONTROL_TRANSFER:  from 83ef108f to 83e8d110

STACK_TEXT:  
83300fec 83ef108f 00000003 cf37a414 00000065 nt!RtlpBreakWithStatusInstruction
8330103c 83ef1b8d 00000003 8c786f98 871dcb5e nt!KiBugCheckDebugBreak+0x1c
83301400 83e535cb 0000000a 8c786f98 00000002 nt!KeBugCheck2+0x68b
83301400 871dcb5e 0000000a 8c786f98 00000002 nt!KiTrap0E+0x2cf
833014e4 871db61d 00000178 00000000 0000026c SecMon!InsertProcessNotifyLog+0x9e [d:\test\secmon64\processnotify.c @ 121]
8330153c 84079774 8da4e030 00000178 83301560 SecMon!ObCreateProcessEx+0x1ed [d:\test\secmon64\secmon.c @ 440]
833015f4 840817a1 8da4ed48 01a4e030 83301650 nt!PspInsertThread+0x5c0
83301d00 83e501ea 001bf534 001bf510 02000000 nt!NtCreateUserProcess+0x742
83301d00 76dd70b4 001bf534 001bf510 02000000 nt!KiFastCallEntry+0x12a
001bf1f4 76dd5784 7692e5d5 001bf534 001bf510 ntdll!KiFastSystemCallRet
001bf1f8 7692e5d5 001bf534 001bf510 02000000 ntdll!ZwCreateUserProcess+0xc
001bf854 768e2079 00000000 00000000 0015eab8 kernel32!CreateProcessInternalW+0xe75
001bf88c 00c2c500 00000000 0015eab8 00000000 kernel32!CreateProcessW+0x2c
001bf9d4 00c3643a 00955230 0015eab8 001bfa10 services!ScLogonAndStartImage+0x432
001bfa14 00c2885e 00000000 00000000 00000000 services!ScStartService+0x419
001bfa4c 00c28b7e 00000000 00000000 00000000 services!ScStartMarkedServices+0x14e
001bfa88 00c2f840 00000000 00000000 00000000 services!ScStartServiceAndDependencies+0x364
001bfab0 00c2e682 00000000 00c571f8 00000001 services!ScAutoStartServices+0xf9
001bfaec 00c34680 00000001 002d1010 001bfb40 services!SvcctrlMain+0x7e3
001bfafc 00c3394e 00000001 002d1010 002d1458 services!main+0x19
001bfb40 76933c45 7ffdc000 001bfb8c 76df37f5 services!_initterm_e+0x163
001bfb4c 76df37f5 7ffdc000 76fd225b 00000000 kernel32!BaseThreadInitThunk+0xe
001bfb8c 76df37c8 00c3388a 7ffdc000 00000000 ntdll!__RtlUserThreadStart+0x70
001bfba4 00000000 00c3388a 7ffdc000 00000000 ntdll!_RtlUserThreadStart+0x1b

STACK_COMMAND:  kb

FOLLOWUP_IP:
SecMon!InsertProcessNotifyLog+9e [d:\test\secmon64\processnotify.c @ 121]
871dcb5e 668b08          mov     cx,word ptr [eax]

FAULTING_SOURCE_CODE:  
   117:                 g_Process_Log_Head->processId=pid;
   118:                 g_Process_Log_Head->parentPid=parentPid;
   119:                 g_Process_Log_Head->flags=flags;
   120:                 g_Process_Log_Head->userGeted=0;
>  121:                 if (wcslen(processPath) < MAX_PATH)
   122:                 {
   123:                         RtlCopyMemory(g_Process_Log_Head->processPath,processPath,wcslen(processPath)*sizeof(WCHAR));
   124:                 }
   125:                 else
   126:                 {

SYMBOL_STACK_INDEX:  4

SYMBOL_NAME:  SecMon!InsertProcessNotifyLog+9e

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: SecMon

IMAGE_NAME:  SecMon.sys

DEBUG_FLR_IMAGE_TIMESTAMP:  51a8706e

FAILURE_BUCKET_ID:  0xD1_VRF_SecMon!InsertProcessNotifyLog+9e

BUCKET_ID:  0xD1_VRF_SecMon!InsertProcessNotifyLog+9e

Followup: MachineOwner

查看与wcslen类似的函数,“RtlStringCchLengthW”,发现其运行irql要求为:

PASSIVE_LEVEL

怪哉,不会在dispatch_level下运行wcslen也有问题吧。

请各位高手指点指点,谢谢。。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 496
活跃值: (286)
能力值: ( LV13,RANK:400 )
在线值:
发帖
回帖
粉丝
2
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.
试图在一个太高的中断请求级别访问一个可分页内存地址.

看看你的processPath这个地址是不是在Paged-pool里了。

在DISPATCH_LEVEL发生的问题多数都是内存不合法。
2013-5-31 18:48
0
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
就是IRQL的问题,堆栈中不是写得很清楚么?

nt!KiTrap0E+0x2cf                <<<----
2013-5-31 19:44
0
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
那段代码中,肯定有一个函数触发了缺页中断~~~
2013-5-31 19:46
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
processPath是以\0结尾的吗?
2013-5-31 19:47
0
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
好吧.收回上面的话,也许是访问了不存在的内存~~~
2013-5-31 20:04
0
雪    币: 194
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
分配的是nonpaged内存,而且清零了。
2013-5-31 20:30
0
雪    币: 194
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
查看与wcslen类似的函数,“RtlStringCchLengthW”,发现其运行irql要求为:
PASSIVE_LEVEL
很怪。
不知道为什么??
2013-5-31 20:31
0
雪    币: 194
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
自己顶一下。。
2013-6-1 09:44
0
雪    币: 194
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢各位了。。。
2013-6-24 17:07
0
雪    币: 1711
活跃值: (516)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
11
几个原因:
RtlXxx函数本身是pageable的
string buffer往往是从paged pool里分配的而非stack里
NLS table是pageable的
2013-6-24 17:25
0
雪    币: 194
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
那么wcslen是不是可以计算nonpage pool内的字符串。
2013-6-24 18:08
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
原因是你开了校验器,开了校验器后,非分页内存会用分页内存包裹,一旦字符串没按0结尾,你这什么wcslen就飞出非分页区了。

用校验器前好歹看看windows internals之类的科普书籍嘛!

另外,你这process notify看进程路径,到内核里面都是unicode string,人家都给你计算好了length了你何苦用个什么wcslen嘛!
2013-6-24 21:09
0
雪    币: 1711
活跃值: (516)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
14
nonpageable的一直都在内存里的,任何时候访问都不会发生page fault的。
不过unicode string本身就有长度了呀,何必多此一举再算一遍
typedef struct _LSA_UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
2013-6-24 21:27
0
雪    币: 194
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
各位大爷,我说的是在dispatch_level下,用wcslen计算在非分页的内存中的unicode字符串,而这个字符串肯定以\0结束的。
而不是UNICODE_STRING,要是他的话,费那个劲,干什么。
谢谢各位关注。。。
2013-6-25 09:57
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
你不就是个进程回调吗?又不是什么多了不起的东西,为什么不是unicode_string?

你又怎么知道一定以0结尾?如果以0结尾,而且字符串都在非分页内存,是绝对不会蓝屏的,所以你这个只可能是你wcslen到了分页内存里面,那么要么是原来就是分页,要么就是飞了

至于是不是,用!pte看一下8c786f98这个地址的属性就知道了
2013-6-25 14:05
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
根據bugcheck給的資料,你的確給了一個pageable的指針,
wcslen在確定nonpaged pool的情況下使用是不會掛的,
RtlStringCchLengthW就不曉得了,裡面可能有塞bugcheck檢查

另外就是從callstack來看,你應該是想從PS_CREATE_NOTIFY_INFO或PEB裡面取值,
你自己定義的g_Process_Log_Head可以是nonpaged pool,那processPath的來源是?
2013-7-26 03:19
0
游客
登录 | 注册 方可回帖
返回
//