Driver Verifier Problems

收集執行Verifier不過的解決方法與經驗分享。

Note. 我是App開發人員,不是專業的驅動程式開發人員,因此方法僅供參考。

我們最早沒通過驗證的是這個錯誤:

DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 0000021f, (Non-fatal error) A driver has not filled out a dispatch
routine for a required IRP major function. (IRP specified.)
Arg2: f10de2f7
Arg3: 887c8e48
Arg4: 00000000
原因是PNP driver沒處理IRP_MJ_POWER與IRP_MJ_SYSTEM_CONTRO的IRP。最後解法是參考M$的sample,將IRP pass down。

The caller has changed the status field of an IRP it does not understand

我們這個問題發生在註冊Driver、處理IRP_MJ_PNP的流程中。

DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 000000000000023b, The caller has changed the status field of an IRP it does not understand.
 
Arg2: fffff80125e58ebd, The address in the driver's code where the error was detected.
Arg3: ffffcf816fb40dc0, IRP address.
Arg4: 0000000000000000
原本做法會把IRP的狀態都初始化為STATUS_SUCCESS:
IRP->IoStatus.Status       = STATUS_SUCCESS;
最後我們是針對有處理的情況回應對應結果,不處理的就by-pass,順利解決這個問題。

MmMapLockedPages called without MDL_MAPPING_CAN_FAIL

這問題是由於MmMapLockedPages已屬於legacy API,改使用MmMapLockedPagesSpecifyCache就可以解決問題;可以參考link1link2

DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
A device driver attempting to corrupt the system has been caught. This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Arguments:
Arg1: 0000000000000081, MmMapLockedPages called without MDL_MAPPING_CAN_FAIL
Arg2: ffffcf81d838efc0, MDL address.
Arg3: 0000000000000804, MDL flags.
Arg4: 0000000000000000, 0.

MmMapIoSpace called to map, but the caller hasn't locked down the MDL pages

這個問題發生在使用MmMapIoSpace去存取硬體資源位置;以我們的例子來說,我是要存取實體記憶體0x1000000:

DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
A device driver attempting to corrupt the system has been caught. This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Arguments:
Arg1: 0000000000000083, MmMapIoSpace called to map, but the caller hasn't locked down the MDL pages.
Arg2: 0000000010003000, Starting physical address to map.
Arg3: 0000000000000100, Number of bytes to map.
Arg4: 0000000000010003, The first page frame number that isn't locked down.
在程式碼本身我沒有什麼方法可以解決。目前網路上看到的做法有兩個,可以當參考:

  1. 不應該存取這個位置,link
  2. 請disable verifier,link

An IRP dispatch handler has returned without passing down or completing this IRP, or someone forgot to return STATUS_PENDING

我們這個問題發生在處理IRP_MJ_SHUTDOWN的流程中:

DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 0000000000000226, An IRP dispatch handler has returned without passing down or completing this IRP,
	or someone forgot to return STATUS_PENDING.
Arg2: fffff880016f3ed4, The address in the driver's code where the error was detected.
Arg3: fffff98005020d80, IRP address.
Arg4: 0000000000000000
原因是沒有對IRP做任何處置,解決方法是在最後加上:
IoCompleteRequest(irp, IO_NO_INCREMENT);

IRP_MJ_SYSTEM_CONTROL has been completed by someone other than the ProviderId

這個問題是由於沒有處理好IRP_MJ_SYSTEM_CONTROL的IRP:

DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 0000000000000220, IRP_MJ_SYSTEM_CONTROL has been completed by someone other than the ProviderId.
This IRP should either have been completed earlier or should have been passed
down.
Arg2: fffff803795b1f30, The address in the driver's code where the error was detected.
Arg3: ffffff0052de8d80, IRP address.
Arg4: ffff8480aa0a0180, ProviderId.
我們的處理方式就是pass down:
NTSTATUS
DispatchSystemControl(
    PDEVICE_OBJECT    DeviceObject,
    PIRP              Irp
    )
{
    PDEVICE_EXTENSION   deviceExtension;
    NTSTATUS status= STATUS_SUCCESS;
 
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    IoSkipCurrentIrpStackLocation(Irp);
    status=IoCallDriver(deviceExtension->TopOfStack, Irp);
    return status;
}