Ns

Windows 10 1809以降、CreateFile over USB HIDデバイスがアクセス拒否(5)で失敗する



Createfile Over Usb Hid Device Fails With Access Denied Since Windows 10 1809



解決:

これは、最新のWindows10バージョンの新しいセキュリティ制限だと思います。

文字列を探しましたKBD(UTF-16形式)-バージョン1809の2つのドライバーにのみ存在します。 hidclass.syskbdhid.sys 、およびバージョン1709には存在しません。



hidclass.sys 彼らは変更しましたHidpRegisterDeviceInterface関数。このリリースの前にそれは呼ばれましたIoRegisterDeviceInterface withGUID_DEVINTERFACE_HIDと ReferenceString ポインタは0に設定されます。ただし、新しいバージョンでは、GetHidClassCollection、合格KBDとして ReferenceString ポインタ。

中身 kbdhid.sys 彼らは変わったKbdHid_Create、ここにチェックがありますエラー(アクセスが拒否されたか、共有違反)を返すKBD文字列。



その理由をより正確に理解するには、さらに調査が必要です。いくつかの不満:

ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください


参考までに、1709ビルドのHidpRegisterDeviceInterface



ここに画像の説明を入力してください

ここ ReferenceString == 0常に( コーラスr8d、r8d )、チェックはありませんクラスコレクションデータのcmpワード[rbp + a]、6


しかし、1809年のKbdHid_Createにはバグが含まれています。コードは次のとおりです。

NTSTATUS KbdHid_Create(PDEVICE_OBJECT DeviceObject、PIRP Irp){// ... PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); if(PFILE_OBJECT FileObject = IrpSp-> FileObject){PCUNICODE_STRING FileName =&FileObject-> FileName; if(FileName-> Length){#if ver == 1809 UNICODE_STRING KBD = RTL_CONSTANT_STRING(L'KBD '); // !!バグ !! NTSTATUSステータス= RtlEqualUnicodeString(FileName、&KBD、FALSE)? STATUS_SHARING_VIOLATION:STATUS_ACCESS_DENIED; #else NTSTATUS status = STATUS_ACCESS_DENIED; #endif //ログIrp-> IoStatus.Status = status; IofCompleteRequest(Irp、IO_NO_INCREMENT);ステータスを返します。 }} // ...}

この関数がここで何をしようとしているのですか?合格を探しますPFILE_OBJECT FileObject from Irp 現在のスタックの場所。それはありませんFileObjectが提供されているか、名前が空です。開くことができます。それ以外の場合、オープンは失敗します。

1809年以前は、常にエラーで失敗していましたSTATUS_ACCESS_DENIED(0xc0000022)、ただし1809以降、名前がチェックされ、KBD(大文字と小文字を区別)別のエラー-STATUS_SHARING_VIOLATIONが返されます。ただし、名前は常に記号なので、一致することはありませんKBD。かもね KBDなので、このチェックを修正するには、次の行を次のように変更する必要があります。

UNICODE_STRING KBD = RTL_CONSTANT_STRING(L '\ KBD');

この文字列との比較を実行します。したがって、設計上、を介してキーボードデバイスを開こうとしたときのSTATUS_SHARING_VIOLATIONエラー* KBD名ですが、実装エラーのため、実際に取得しましたここでSTATUS_ACCESS_DENIED

ここに画像の説明を入力してください

別の変更がありましたHidpRegisterDeviceInterface-を呼び出す前クエリを実行するデバイスのIoRegisterDeviceInterfaceGetHidClassCollectionの結果、および構造体のWORD(2バイト)フィールドは6に等しく、追加しますKBDサフィックス( ReferenceString )。 6がキーボードの使用IDになる可能性があると思います(ただし、わかりません)。このプレフィックスの理由は、排他的アクセスモードを設定することです。


実際には、FileNameをなしで開始することができますを介して開いている相対デバイスを使用する場合OBJECT_ATTRIBUTES。したがって、テストのためだけに、これを行うことができます:インターフェイス名がで終わる場合 KBD、最初にこのサフィックスなしで(したがって、相対デバイス名が空の状態で)ファイルを開きます。このオープンは正常に機能する必要があります。次に、名前の付いた相対的なオープンファイルを試すことができますKBD-取得する必要があります1809年のSTATUS_SHARING_VIOLATIONおよび以前のビルドのSTATUS_ACCESS_DENIED(ただし、ここではありません KBDサフィックス):

void TestOpen(PWSTR pszDeviceInterface){HANDLE hFile; if(PWSTR c = wcsrchr(pszDeviceInterface、 '\')){static const UNICODE_STRING KBD = RTL_CONSTANT_STRING(L'KBD '); if(!wcscmp(c + 1、KBD.Buffer)){* c = 0; OBJECT_ATTRIBUTES oa = {sizeof(oa)、0、const_cast(&KBD)}; oa.RootDirectory = CreateFileW(pszDeviceInterface、0、FILE_SHARE_VALID_FLAGS、0、OPEN_EXISTING、0、0); if(oa.RootDirectory!= INVALID_HANDLE_VALUE){IO_STATUS_BLOCK iosb; // STATUS_SHARING_VIOLATION(c0000043)になりますNTSTATUS status = NtOpenFile(&hFile、SYNCHRONIZE、&oa、&iosb、FILE_SHARE_VALID_FLAGS、FILE_SYNCHRONOUS_IO_NONALERT); CloseHandle(oa.RootDirectory); if(0<= status) { PrintAttr(hFile); CloseHandle(hFile); } } return ; } } hFile = CreateFileW(pszDeviceInterface, 0, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0); if (hFile != INVALID_HANDLE_VALUE) { PrintAttr(hFile); CloseHandle(hFile); } } void PrintAttr(HANDLE hFile) { HIDD_ATTRIBUTES deviceAttributes = { sizeof(deviceAttributes) }; if(HidD_GetAttributes(hFile, &deviceAttributes)) { printf('VID = %04x PID = %04x
', (ULONG)deviceAttributes.VendorID, (ULONG)deviceAttributes.ProductID); } else { bad(L'HidD_GetAttributes'); } }  

1809年のテストで私は実際に得ましたSTATUS_SHARING_VIOLATION、これもで別のバグを示していますkbdhid.KbdHid_Create-チェックした場合FileName、確認する必要がありますRelatedFileObject-0かどうか。


また、バグとは関係ありませんが、提案として:使用する方が効率的ですSetupAPIの代わりにCM_Get_Device_Interface_List:

揮発性UCHARguz = 0; CONFIGRET EnumInterfaces(PGUID InterfaceClassGuid){CONFIGRET err; PVOIDスタック= alloca(guz); ULONG BufferLen = 0、NeedLen = 256;ユニオン{​​PVOIDbuf; PWSTR pszDeviceInterface; }; for(;;){if(BufferLen

修正は、本日(2019年3月1日)にリリースされたこのWindowsUpdateにあります。

https://support.microsoft.com/en-us/help/4482887/windows-10-update-kb4482887