我在找绳子
KBD
(UTF-16格式)-在1809版本中,它只存在于两个驱动程序中,
hidclass.sys
和
,在1709版本中不存在。
在
hidclass.sys
他们改变了
HidpRegisterDeviceInterface
功能。在这次发布之前
IoRegisterDeviceInterface
GUID_DEVINTERFACE_HID
以及
引用字符串
指针设置为0。但在新版本中,取决于
GetHidClassCollection
,它通过了
作为
引用字符串
内部
kbdhid.sys公司
他们变了
KbdHid_Create
KBD公司
为了更确切地了解原因,还需要进行更多的研究。一些灾难:
作为参考,hidpresisterDeviceInterface来自1709 build
引用字符串
),而且没有支票
cmp word [rbp + a],6
论类集合数据
然而,
创建KbdHid
1809年有一个窃听器。代码是:
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"); // !! bug !!
NTSTATUS status = RtlEqualUnicodeString(FileName, &KBD, FALSE)
? STATUS_SHARING_VIOLATION : STATUS_ACCESS_DENIED;
#else
NTSTATUS status = STATUS_ACCESS_DENIED;
#endif
// log
Irp->IoStatus.Status = status;
IofCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
}
// ...
}
PFILE_OBJECT FileObject
从
当前堆栈位置。不是吗
FileObject
在1809年以前,它总是错误地失败
STATUS_ACCESS_DENIED
0xc0000022
),但从1809年开始,检查名称,如果它等于
KBD公司
STATUS_SHARING_VIOLATION
返回。但是,名称总是以
\
符号,所以永远不会匹配
KBD公司
. 它可以
\KBD
,因此,要修复此检查,需要将以下行更改为:
UNICODE_STRING KBD = RTL_CONSTANT_STRING(L"\\KBD");
并与这个字符串进行比较。所以,按设计我们应该有一个
尝试通过打开键盘设备时出错
*\KBD
名称,但由于实现错误,我们实际上
拒绝访问状态
另一个变化发生了
IoRegisterDeviceInterface
在设备上查询
GetHidClassCollection
结果,如果有的话
WORD
结构中的(2字节)字段等于6,加上
后缀(
引用字符串
Usage ID for keyboard
,这个前缀的基本原理是设置独占访问模式
实际上,我们可以在没有
\
如果我们使用相关设备打开
OBJECT_ATTRIBUTES
. 所以,为了测试,我们可以这样做:如果接口名以
,首先打开不带此后缀的文件(因此相对设备名为空),此打开必须正常工作;然后,我们可以尝试使用名称相对打开文件
KBD公司
状态共享违反
1809年和
在这里将没有以前的版本
\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<PUNICODE_STRING>(&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;
// will be 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\r\n",
(ULONG)deviceAttributes.VendorID, (ULONG)deviceAttributes.ProductID);
} else {
bad(L"HidD_GetAttributes");
}
}
在1809年的一次测试中
状态共享违反
kbdhid.KbdHid_Create
-如果我们检查一下
FileName
,我们需要检查
RelatedFileObject
-是不是0。
CM_Get_Device_Interface_List
而不是SetupAPI:
volatile UCHAR guz = 0;
CONFIGRET EnumInterfaces(PGUID InterfaceClassGuid)
{
CONFIGRET err;
PVOID stack = alloca(guz);
ULONG BufferLen = 0, NeedLen = 256;
union {
PVOID buf;
PWSTR pszDeviceInterface;
};
for(;;)
{
if (BufferLen < NeedLen)
{
BufferLen = RtlPointerToOffset(buf = alloca((NeedLen - BufferLen) * sizeof(WCHAR)), stack) / sizeof(WCHAR);
}
switch (err = CM_Get_Device_Interface_ListW(InterfaceClassGuid,
0, pszDeviceInterface, BufferLen, CM_GET_DEVICE_INTERFACE_LIST_PRESENT))
{
case CR_BUFFER_SMALL:
if (err = CM_Get_Device_Interface_List_SizeW(&NeedLen, InterfaceClassGuid,
0, CM_GET_DEVICE_INTERFACE_LIST_PRESENT))
{
default:
return err;
}
continue;
case CR_SUCCESS:
while (*pszDeviceInterface)
{
TestOpen(pszDeviceInterface);
pszDeviceInterface += 1 + wcslen(pszDeviceInterface);
}
return 0;
}
}
}
EnumInterfaces(const_cast<PGUID>(&GUID_DEVINTERFACE_HID));