gpt4 book ai didi

c - 如何与 NT 安装管理器交互以分配驱动器号?

转载 作者:可可西里 更新时间:2023-11-01 14:19:24 25 4
gpt4 key购买 nike

我正在尝试替换一些遗留的 DefineDosDevice 用户空间代码(由于提升的和正常的 session 由不同的 DosDevice 存储表示,因此在具有管理员用户的 Vista 上不起作用,因此创建一个相当奇怪的场景,即如果从未提升的进程创建驱动器是可见的,但如果从提升的进程创建则不可见)。

这个的替代品,正如我通过检查 Truecrypt source 发现的那样还有这个WDM sample是向 mountmgr.sys 发出 IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION 消息,然后向 IOCTL_MOUNTMGR_CREATE_POINT/IOCTL_MOUNTMGR_DELETE_POINT 发送消息。

这就是我正在做的 - 我的代码如下所示:

首先是各种本地人:

NTSTATUS ntStatus;
PDEVICE_EXTENSION device_extension;
UNICODE_STRING uVolumeName;

ULONG mntNameLen = 0;
ULONG mntPointLen = 0;
PMOUNTMGR_TARGET_NAME mntName = NULL;
PMOUNTMGR_CREATE_POINT_INPUT mntPoint = NULL;

然后,我构造并提出我的两个请求。第一个失败并显示上述状态代码。第二个失败并显示不同的状态代码(但如果第一个失败则预计不会工作)。

mntNameLen = sizeof(MOUNTMGR_TARGET_NAME) + device_extension->sDevName.Length;
mntName = ExAllocatePool(PagedPool, mntNameLen);

mntName->DeviceNameLength = device_extension->sDevName.Length;
RtlCopyMemory(mntName->DeviceName, device_extension->sDevName.Buffer,
mntName->DeviceNameLength);

ntStatus = MakeDeviceIoRequest (MOUNTMGR_DEVICE_NAME,
IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
mntName, mntNameLen, 0, 0);

mntPointLen = sizeof(PMOUNTMGR_CREATE_POINT_INPUT) +
device_extension->sDevName.Length + uVolumeName.Length;
mntPoint = ExAllocatePool(PagedPool, mntPointLen);

mntPoint->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
RtlCopyMemory(&mntPoint+mntPoint->SymbolicLinkNameOffset,
uVolumeName.Buffer, uVolumeName.Length * sizeof(WCHAR));
mntPoint->SymbolicLinkNameLength = uVolumeName.Length;

mntPoint->DeviceNameOffset = mntPoint->SymbolicLinkNameOffset +
mntPoint->SymbolicLinkNameLength;
RtlCopyMemory(&mntPoint+mntPoint->DeviceNameOffset,
device_extension->sDevName.Buffer, device_extension->sDevName.Length);
mntPoint->DeviceNameLength = device_extension->sDevName.Length;

ntStatus = MakeDeviceIoRequest(MOUNTMGR_DEVICE_NAME,
IOCTL_MOUNTMGR_CREATE_POINT, mntPoint,
mntPointLen, 0, 0);

然后我创建符号链接(symbolic link)\GLOBAL??\L: ->\Device\DeviceName

ntStatus = IoCreateSymbolicLink(&uVolumeName, &(device_extension->sDevName));
DbgPrint("Mapped %wZ -> %wZ\n", &uVolumeName, &(device_extension->sDevName));
RtlFreeUnicodeString(&uVolumeName);
if ( mntName != NULL )
{
ExFreePool(mntName);
}
if ( mntPoint != NULL)
{
ExFreePool(mntPoint);
}

但是,挂载管理器的 ntStatus 响应是 0xC0000010 STATUS_INVALID_DEVICE_REQUEST;我的设备字符串的格式为 \Device\DevName 并响应每个:

  • IOCTL_VOLUME_ONLINE
  • IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
  • IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
  • IOCTL_MOUNTDEV_QUERY_DEVICE_NAME

以及存储设备预期的其他 IOCTL 列表。但是,我在所有这些例程上都设置了断点,但都没有达到。

我的设备是通过这个小片段创建的:

// Security descriptor
RtlInitUnicodeString(&sddl,
_T("D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;BU)(A;;GA;;;WD)"));

// named device
status = IoCreateDeviceSecure(
DriverObject,
sizeof(DEVICE_EXTENSION),
&device_name, // \Device\DeviceName
DeviceType, // valid devicetype.
0,
FALSE,
&sddl, // security descriptor
NULL, // no idea what this does.
&device_object // output device object.
);

那么,下面是一些问题:

  1. 我是否正确地为挂载管理器创建了消息?调用 MakeDeviceIoRequest 基本上包装了 IoCallDriver,我有理由相信这不是问题所在。
  2. 我使用 CreateDevice 做的事情有问题吗?我问是因为我读了this blog post这暗示了一些关于设备名称、FDO 和 PDO 的东西,老实说我不太明白。
  3. 如果我似乎陷得太深,是否有机会澄清我对这一切如何运作的理解?

注意:我有一些限制。我在其上构建的代码相当遗留,因此我包括了 ntddk.h 和 wdmsec.h;在此阶段,我无法将它们更改为 wdm.hntifs.h

最佳答案

在深入探讨之前,您是否有机会将对 DefineDosDevice 的调用转移到服务中?从服务调用它会将链接放在全局目录中,这将完全消除您遇到的别名问题。

如果您不能这样做,我的第一个猜测是您没有处理其他一些必需的安装管理器 IOCTL。我知道您在所有特定的 IOCTL 上都有断点,但是您在默认处理程序中有断点吗?通常这是 STATUS_INVALID_DEVICE_REQUEST 的来源。

关于c - 如何与 NT 安装管理器交互以分配驱动器号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9944475/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com