首页
社区
课程
招聘
驱动相关问题,诚心求指教!
发表于: 2013-5-16 22:57 8482

驱动相关问题,诚心求指教!

2013-5-16 22:57
8482
驱动方面本人是菜鸟,刚学习,瞎折腾写了一个小驱动,不过目前遇到一些问题,百思不得其解,哪位前辈如果知道希望能指点一下,在此先谢过了!
已找到问题原因所在,如有兴趣,具体请看末尾解释;

此驱动行为大致如下所述;(NT驱动)
在驱动初始化时,创建了一个系统线程,用异步于处理所有IRP,初始化代码大体如下:
pIrpQue = &pDevExt->irpListQueue;
InitializeListHead(&pIrpQue->listHead);
KeInitializeSpinLock(&pIrpQue->spinLock);
KeInitializeEvent(&pIrpQue->notifyEvent, SynchronizationEvent, FALSE);
OBJECT_ATTRIBUTES objAttr;
InitializeObjectAttributes(&objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
pDevExt->hHandleIrpThread = NULL;
ntStatus = PsCreateSystemThread(&pDevExt->hHandleIrpThread,THREAD_ALL_ACCESS, &objAttr,
NULL, NULL, HandleIrpProc, pDeviceObject);


创建出来的irp处理线程大体代码如下:
KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
PLIST_ENTRY pListEntry = NULL;
while (!pDevExt->bDriverUnloading)
{
    KeWaitForSingleObject(&pIrpQue->notifyEvent, Executive, KernelMode, FALSE, NULL);
    while (pListEntry = ExInterlockedRemoveHeadList(&pIrpQue->listHead, &pIrpQue->spinLock))
    {
        pCurIrp = CONTAINING_RECORD(pListEntry, IRP, Tail.Overlay.ListEntry);
        DispatchIrpReq(pDevObj, pCurIrp);// 此处可以直接看成IoCompleteRequest
     }
}
PsTerminateSystemThread(STATUS_SUCCESS);


驱动派发函数DeviceIoControl大体实现如下:
NTSTATUS ntStatus = STATUS_PENDING;
IoMarkIrpPending(pIrp);
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
PIRP_LIST_QUEUE pIrpQue = &pDevExt->irpListQueue;
ExInterlockedInsertTailList(&pIrpQue->listHead, &pIrp->Tail.Overlay.ListEntry, &pIrpQue->spinLock);
KeSetEvent(&pIrpQue->notifyEvent, IO_NO_INCREMENT, FALSE);
pIrp->IoStatus.Status = ntStatus;


驱动卸载DriverUnload部分代码大体如下:
KeSetEvent(&pDevExt->irpListQueue.notifyEvent, IO_NO_INCREMENT, FALSE);
KeWaitForSingleObject(pkThread, Executive, KernelMode, FALSE, NULL);
ObfDereferenceObject(pkThread);
ZwClose(pDevExt->hHandleIrpThread);


整个驱动编译好后,在我的真机(XP3)上运行没有遇到问题,但是在虚拟机中测试(XP3)就直接OVER了(处理IRP操作),不过其驱动卸载操作正常;(忽略掉DispatchIrpReq,从某一方面上看我认为我的DriverUnload跟DeviceIoControl基本一致,但为什么结果一个蓝屏一个没有问题?)

挂掉时的dump具体如下:
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

INVALID_PROCESS_ATTACH_ATTEMPT (5)
Arguments:
Arg1: 00000000
Arg2: 821b9830
Arg3: 00000000
Arg4: 00000000

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


CUSTOMER_CRASH_COUNT:  3

DEFAULT_BUCKET_ID:  DRIVER_FAULT

BUGCHECK_STR:  0x5

PROCESS_NAME:  System

LAST_CONTROL_TRANSFER:  from 804fec30 to 804f9cb5

STACK_TEXT:  
b2aeacec 804fec30 00000005 00000000 821b9830 nt!KeBugCheckEx+0x1b
b2aead3c 80501cf4 00000000 00000000 00000000 nt!KiDeliverApc+0x202
b2aead54 804fad62 00000000 81b98a08 00000000 nt!KiSwapThread+0x64
b2aead7c b20e143f 00000000 00000000 00000000 nt!KeWaitForSingleObject+0x1c2
b2aeadac 805c7160 81b987a8 00000000 00000000 MyDriver!HandleIrpProc+0x7f
b2aeaddc 80542dd2 b20e13c0 81b987a8 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16


STACK_COMMAND:  kb

FOLLOWUP_IP: 
MyDriver!HandleIrpProc+7f
b20e143f 8b55f0          mov     edx,dword ptr [ebp-10h]

FAULTING_SOURCE_CODE:  
   402:   PLIST_ENTRY pListEntry = NULL;
   403:   while (!pDevExt->bDriverUnloading)
   404:   {
   405:     KeWaitForSingleObject(&pIrpQue->notifyEvent, Executive, KernelMode, FALSE, NULL);
>  406:     while (pListEntry = ExInterlockedRemoveHeadList(&pIrpQue->listHead, &pIrpQue->spinLock))
   407:     {
   408:       pCurIrp = CONTAINING_RECORD(pListEntry, IRP, Tail.Overlay.ListEntry);
   409:       DispatchIrpReq(pDevObj, pCurIrp);
   410:     }
   411:   }


SYMBOL_STACK_INDEX:  4

SYMBOL_NAME:  MyDriver!HandleIrpProc+7f

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: MyDriver

IMAGE_NAME:  MyDriver.sys

DEBUG_FLR_IMAGE_TIMESTAMP:  5194e755

FAILURE_BUCKET_ID:  0x5_MyDriver!HandleIrpProc+7f

BUCKET_ID:  0x5_MyDriver!HandleIrpProc+7f

Followup: MachineOwner
---------


我想请教的问题一共有2点:
第1点是为什么会挂掉?(从dump中我个人没看出问题根源)
第2点是假如我在ExInterlockedInsertTailList,KeSetEvent后,强制延迟N秒返回,即确保异步irp处理线程早就处理好irp了,
那么此时分发函数pending返回会导致崩溃吗?大家一般是怎么处理的?


问题原因具体解释如下(整个驱动存在多处问题):
上面贴出来的代码中有一句“DispatchIrpReq(pDevObj, pCurIrp);// 此处可以直接看成IoCompleteRequest”我弄错了,发帖前我曾尝试过把DispatchIrpReq调用直接替换为IoCompleteRequest,结果依旧蓝屏,所以就非常信任自己DispatchIrpReq内部实现没有问题;当时蓝屏信息看错眼了,结果今天发现此蓝屏不是同一个问题,导致给大家误导信息,万分抱歉!

1、把DispatchIrpReq调用直接替换为IoCompleteRequest导致蓝屏的原因是因为此时在分派函数中pending设置还未完成(pIrp->IoStatus.Status=STATUS_PENDING),而此时由于已经调用了IoCompleteRequest,导致IofCompleteRequest把irp给Free掉了;因而对pIrp->IoStatus.Status进行赋值操作就导致了写入错误,触发了蓝屏;这个结果其实也为自己提的第二点问题做了解答:会崩溃,应该把irp pending的所有信息都设置好,最后才把irp交由异步处理线程处理,这样就不需要担心irp提前完成的情况了,因为接下来在分发函数中都不需要使用到IRP了;
不知道这对异步IRP处理方式对不对,如果哪位前辈觉着有问题,请说明下;(至少我这边处理了,Sleep N秒后再return STATUS_PENDING也不会崩溃了[SLEEP前对IRP的处理已完成])

2、第二个导致蓝屏的原因出在DispatchIrpReq内部,具体问题出在完成例程中对pending的使用上;
首先我构造了一个IRP,同时为它设置了一个完成例程,并且在完成例程中写了如下代码:
if (pIrp->PendingReturned)// 不太了解的情况下,直接人云亦云的使用了如下代码,悲剧
{
    IoMarkIrpPending(pIrp);
}

实际上作为顶层调用方,我根本不需要向上传递pending信息,也不能传递pending信息,因为此时的IoGetCurrentIrpStackLocation定位到指针已经无效了(处于IO栈末尾了);如有疑惑,可以参考下reactos中IofCompleteRequest函数的实现;

3、第三个导致蓝屏的原因也在DispatchIrpReq内部,具体原因也是完成例程中我的代码存在问题导致;(这个蓝屏才是我贴出的dump问题)
我在完成例程中蛋疼的写了如下这么一句话,KeSetEvent((PKEVENT)pWaitEvent, IO_NO_INCREMENT, FALSE);其中pWaitEvent是构造IRP是的userevent,并且是栈上的变量;因而irp处理线程比IofCompleteRequest提前结束了处理,接下来去调用KeWaitForSingleObject,而此刻IofCompleteRequest内部终于要用到我栈上传入的ioStatus变量了,为他赋值为STATUS_SUCCESS(0),但是此时该变量地址却属于KeWaitForSingleObject的函数栈,所以导致其中有一个process参数为NULL,触发了原先我认为毫无头绪的错误;
(我DispatchIrpReq函数内部的栈布局真是撞了狗屎运,竟然命中了那么一个参数,导致了INVALID_PROCESS_ATTACH_ATTEMPT错误,呵呵)

PS:还是非常感谢大家帮忙解答,由于问题实际原因跟各位回答均有差异,所以我这10分将尽量平均分摊给下面帮忙回答了的各位坛友,呵呵!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 1088
活跃值: (30)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
你不是前几天帮我解决了那个OLOGO问题的人吗?
新手入门无能为力,祝你能得到解决..
2013-5-16 23:03
0
雪    币: 107
活跃值: (73)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
呵呵,驱动方面可能比你稍微多走了几步而已,不过同是新人,大家一起互相努力吧
2013-5-16 23:52
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
检查一下irp的有效性
2013-5-17 00:14
0
雪    币: 207
活跃值: (39)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
把你联系方式留下,我也在学习,我刚回卸载和加载的编写!
2013-5-17 00:20
0
雪    币: 38
活跃值: (33)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
看了看,爱莫能助了,支持一下!
2013-5-17 01:29
0
雪    币: 1088
活跃值: (30)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
ME TOO....
2013-5-17 01:38
0
雪    币: 107
活跃值: (73)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
崩溃点好像在KeWaitForSingleObject内部,其中调用KeWaitForSingleObject时参数均没用到IRP,可能是IRP有效性导致的问题吗?

PS:你指的IRP有效性判断具体是什么?能够具体点,谢谢!
2013-5-17 09:49
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
KeWaitForSingleObject是不可能有问题的……要出问题肯定是在前面,一般要么是传参有误
第二个就是irp有效性的问题……如果你这是个过滤驱动……十有八九是r3与内核通信产生的irp和你过滤的irp搅到一起去了

这个没有完整程序来调戏不好看的……
2013-5-17 17:55
0
雪    币: 1
活跃值: (1174)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
MSDN:
Tail.Overlay.Thread
Is a pointer to the caller's thread control block. Higher-level drivers that allocate IRPs for lower-level removable-media drivers must set this field in the IRPs they allocate. Otherwise, the FSD cannot determine which thread to notify if the underlying device driver indicates that the media requires verification.

猜测一下: IRP被完成了, 需要通知某个线程, 但此成员无效, 因为Thread与ListEntry是重叠的(union),而且被你破坏了, 结论是不应该使用Tail.Overlay.ListEntry来管理你的IRP队列

如果说对了, 别忘记给分啊, 我还没弄到户口本呢~
2013-5-17 18:40
0
雪    币: 107
活跃值: (73)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
11
您好,非常感谢回答,不过有几点可能不是很认同;
1、ListEntry跟Thread成员不在union结构中的,他们同属于一个sruct,你可能看错了;
2、基于Tail.Overlay.ListEntry保存irp,我不清楚是不是标准做法,不过这种做法我是逆向一个商业驱动学到的,所以应该问题不大;

我这边今天又实验了下,应该是代码的其他部分有点问题;
2013-5-17 20:27
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
一定不是KeWaitForSingleObject的问题

你单步看看……
2013-5-17 21:34
0
雪    币: 1
活跃值: (1174)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
不好意思,是我看错了,但是我说的办法你试过了么? 我以为随便去动IRP成员是不安全的, 除非确定没别人在用,比如自己分配的IRP.

还是MSDN:
Tail.Overlay.ListEntry
If a driver manages its own internal queues of IRPs, it uses this field to link one IRP to the next. These links can be used only while the driver is holding the IRP in its queue or is processing the IRP

不过后面那句限定条件, 究竟什么意思我不明白,可以翻翻WRK怎么用的

看看crash dump, 我手边没WRK,google了下ReactOS:

00300 VOID
00301 NTAPI
00302 KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode,
00303              IN PKEXCEPTION_FRAME ExceptionFrame,
00304              IN PKTRAP_FRAME TrapFrame)
00305 {
00306     PKTHREAD Thread = KeGetCurrentThread();
00307     PKPROCESS Process = Thread->ApcState.Process;
00308     PKTRAP_FRAME OldTrapFrame;
00309     PLIST_ENTRY ApcListEntry;
00310     PKAPC Apc;
00311     KLOCK_QUEUE_HANDLE ApcLock;
00312     PKKERNEL_ROUTINE KernelRoutine;
00313     PVOID NormalContext;
00314     PKNORMAL_ROUTINE NormalRoutine;
00315     PVOID SystemArgument1;
00316     PVOID SystemArgument2;
00317     ASSERT_IRQL_EQUAL(APC_LEVEL);
00318
00319     /* Save the old trap frame and set current one */
00320     OldTrapFrame = Thread->TrapFrame;
00321     Thread->TrapFrame = TrapFrame;
00322
00323     /* Clear Kernel APC Pending */
00324     Thread->ApcState.KernelApcPending = FALSE;
00325
00326     /* Check if Special APCs are disabled */
00327     if (Thread->SpecialApcDisable) goto Quickie;
00328
00329     /* Do the Kernel APCs first */
00330     while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
00331     {
00332         /* Lock the APC Queue */
00333         KiAcquireApcLockAtApcLevel(Thread, &ApcLock);
00334
00335         /* Check if the list became empty now */
00336         if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
00337         {
00338             /* It is, release the lock and break out */
00339             KiReleaseApcLock(&ApcLock);
00340             break;
00341         }
00342
00343         /* Kernel APC is not pending anymore */
00344         Thread->ApcState.KernelApcPending = FALSE;
00345
00346         /* Get the next Entry */
00347         ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
00348         Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
00349
00350         /* Save Parameters so that it's safe to free the Object in the Kernel Routine*/
00351         NormalRoutine = Apc->NormalRoutine;
00352         KernelRoutine = Apc->KernelRoutine;
00353         NormalContext = Apc->NormalContext;
00354         SystemArgument1 = Apc->SystemArgument1;
00355         SystemArgument2 = Apc->SystemArgument2;
00356
00357         /* Special APC */
00358         if (!NormalRoutine)
00359         {
00360             /* Remove the APC from the list */
00361             RemoveEntryList(ApcListEntry);
00362             Apc->Inserted = FALSE;
00363
00364             /* Release the APC lock */
00365             KiReleaseApcLock(&ApcLock);
00366
00367             /* Call the Special APC */
00368             KernelRoutine(Apc,
00369                           &NormalRoutine,
00370                           &NormalContext,
00371                           &SystemArgument1,
00372                           &SystemArgument2);
00373
00374             /* Make sure it returned correctly */
00375             if (KeGetCurrentIrql() != ApcLock.OldIrql)
00376             {
00377                 KeBugCheckEx(IRQL_UNEXPECTED_VALUE,
00378                              (KeGetCurrentIrql() << 16) |
00379                              (ApcLock.OldIrql << 8),
00380                              (ULONG_PTR)KernelRoutine,
00381                              (ULONG_PTR)Apc,
00382                              (ULONG_PTR)NormalRoutine);
00383             }
00384         }
00385         else
00386         {
00387             /* Normal Kernel APC, make sure it's safe to deliver */
00388             if ((Thread->ApcState.KernelApcInProgress) ||
00389                 (Thread->KernelApcDisable))
00390             {
00391                 /* Release lock and return */
00392                 KiReleaseApcLock(&ApcLock);
00393                 goto Quickie;
00394             }
00395
00396             /* Dequeue the APC */
00397             RemoveEntryList(ApcListEntry);
00398             Apc->Inserted = FALSE;
00399
00400             /* Go back to APC_LEVEL */
00401             KiReleaseApcLock(&ApcLock);
00402
00403             /* Call the Kernel APC */
00404             KernelRoutine(Apc,
00405                           &NormalRoutine,
00406                           &NormalContext,
00407                           &SystemArgument1,
00408                           &SystemArgument2);
00409
00410             /* Make sure it returned correctly */
00411             if (KeGetCurrentIrql() != ApcLock.OldIrql)
00412             {
00413                 KeBugCheckEx(IRQL_UNEXPECTED_VALUE,
00414                              (KeGetCurrentIrql() << 16) |
00415                              (ApcLock.OldIrql << 8),
00416                              (ULONG_PTR)KernelRoutine,
00417                              (ULONG_PTR)Apc,
00418                              (ULONG_PTR)NormalRoutine);
00419             }
00420
00421             /* Check if there still is a Normal Routine */
00422             if (NormalRoutine)
00423             {
00424                 /* At Passive Level, an APC can be prempted by a Special APC */
00425                 Thread->ApcState.KernelApcInProgress = TRUE;
00426                 KeLowerIrql(PASSIVE_LEVEL);
00427
00428                 /* Call and Raise IRQL back to APC_LEVEL */
00429                 NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
00430                 KeRaiseIrql(APC_LEVEL, &ApcLock.OldIrql);
00431             }
00432
00433             /* Set Kernel APC in progress to false and loop again */
00434             Thread->ApcState.KernelApcInProgress = FALSE;
00435         }
00436     }
00437
00438     /* Now we do the User APCs */
00439     if ((DeliveryMode == UserMode) &&
00440         !(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
00441          (Thread->ApcState.UserApcPending))
00442     {
00443         /* Lock the APC Queue */
00444         KiAcquireApcLockAtApcLevel(Thread, &ApcLock);
00445
00446         /* It's not pending anymore */
00447         Thread->ApcState.UserApcPending = FALSE;
00448
00449         /* Check if the list became empty now */
00450         if (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))
00451         {
00452             /* It is, release the lock and break out */
00453             KiReleaseApcLock(&ApcLock);
00454             goto Quickie;
00455         }
00456
00457         /* Get the actual APC object */
00458         ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink;
00459         Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
00460
00461         /* Save Parameters so that it's safe to free the Object in the Kernel Routine*/
00462         NormalRoutine = Apc->NormalRoutine;
00463         KernelRoutine = Apc->KernelRoutine;
00464         NormalContext = Apc->NormalContext;
00465         SystemArgument1 = Apc->SystemArgument1;
00466         SystemArgument2 = Apc->SystemArgument2;
00467
00468         /* Remove the APC from Queue, and release the lock */
00469         RemoveEntryList(ApcListEntry);
00470         Apc->Inserted = FALSE;
00471         KiReleaseApcLock(&ApcLock);
00472
00473         /* Call the kernel routine */
00474         KernelRoutine(Apc,
00475                       &NormalRoutine,
00476                       &NormalContext,
00477                       &SystemArgument1,
00478                       &SystemArgument2);
00479
00480         /* Check if there's no normal routine */
00481         if (!NormalRoutine)
00482         {
00483             /* Check if more User APCs are Pending */
00484             KeTestAlertThread(UserMode);
00485         }
00486         else
00487         {
00488             /* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */
00489             KiInitializeUserApc(ExceptionFrame,
00490                                 TrapFrame,
00491                                 NormalRoutine,
00492                                 NormalContext,
00493                                 SystemArgument1,
00494                                 SystemArgument2);
00495         }
00496     }
00497
00498 Quickie:
00499     /* Make sure we're still in the same process */
00500     if (Process != Thread->ApcState.Process)
00501     {
00502         /* Erm, we got attached or something! BAD! */
00503         KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
00504                      (ULONG_PTR)Process,
00505                      (ULONG_PTR)Thread->ApcState.Process,
00506                      Thread->ApcStateIndex,
00507                      KeGetCurrentPrcb()->DpcRoutineActive);
00508     }
00509
00510     /* Restore the trap frame */
00511     Thread->TrapFrame = OldTrapFrame;
00512 }

第503行, 注意你的crash dump 其中KeBugCheckEx第一个参数为什么是NULL, 本该是Process的? 很诡异

虽然ListEntry没和Thread重叠,但却与APC重叠了:

lkd> dt nt!_IRP -r

   +0x040 Tail             : __unnamed
      +0x000 Overlay          : __unnamed
         +0x000 DeviceQueueEntry : _KDEVICE_QUEUE_ENTRY
         +0x000 DriverContext    : [4] Ptr32 Void
         +0x010 Thread           : Ptr32 _ETHREAD
         +0x014 AuxiliaryBuffer  : Ptr32 Char
         +0x018 ListEntry        : _LIST_ENTRY
         +0x020 CurrentStackLocation : Ptr32 _IO_STACK_LOCATION
         +0x020 PacketType       : Uint4B
         +0x024 OriginalFileObject : Ptr32 _FILE_OBJECT
      +0x000 Apc              : _KAPC
         +0x000 Type             : Int2B
         +0x002 Size             : Int2B
         +0x004 Spare0           : Uint4B
         +0x008 Thread           : Ptr32 _KTHREAD
         +0x00c ApcListEntry     : _LIST_ENTRY
         +0x014 KernelRoutine    : Ptr32           void
         +0x018 RundownRoutine   : Ptr32           void
         +0x01c NormalRoutine    : Ptr32           void
         +0x020 NormalContext    : Ptr32 Void
         +0x024 SystemArgument1  : Ptr32 Void
         +0x028 SystemArgument2  : Ptr32 Void
         +0x02c ApcStateIndex    : Char
         +0x02d ApcMode          : Char
         +0x02e Inserted         : UChar
      +0x000 CompletionKey    : Ptr32 Void

所以我问问,你试过了不用IRP内的ListEntry吗?  这个错看起来又确实与投递APC有关.

如果再不行,那只有设法跟一下KiDeliverApc了,对那个栈变量Process下个断点,看谁动了它
2013-5-17 22:00
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
如果你函数的用法,参数跟例子的都一样,可以考虑检查下自己的派遣函数里的返回值是否正确,这个也很重要。如果是该返回STATUS_PENDING的你返回STATUS_SUCCESS也有可能蓝屏
2013-5-17 22:18
0
雪    币: 1
活跃值: (1174)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
调用了IoMarkIrpPending,但返回的是什么没列出来
2013-5-17 22:23
0
雪    币: 3110
活跃值: (143)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
我也不太会,我一般都是搭建好的
2013-5-17 23:37
0
雪    币: 107
活跃值: (73)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
17
返回的是STATUS_PENDING;
正在动手调试,有结论会告知大家;
2013-5-18 12:47
0
游客
登录 | 注册 方可回帖
返回
//