Попытка отключить доступ к устройству через OS X kext с более высокой оценкой проверки

Мне нужно отключить доступ к определенным устройствам (например, к встроенной камере FaceTime), и я пытался сделать это, предоставив простой кекст с более высоким рейтингом проверки, чем тот, который в настоящее время подключен.

Мой кекст совпадает и прикрепляется к камере как IOProviderClass IOUSBInterface, так и IOProviderClass IOUSBDevice, но все исходные кексты по-прежнему также прикрепляются к ней. Вот как это выглядит в IORegistryExplorer:

FaceTime HD Camera (Built-in)@14700000   # USB device
+-- FaceTime HD Camera (Built-in)@0      # USB interface
|   +-- FaceTimeDisabler                 # my kext matching as IOUSBInterface
|   +-- IOUSBInterfaceUserClientV3       # original
+-- IOUSBDeviceUserClientV2              # original
+-- IOUSBInterface@1                     # original
|   +-- IOUSBInterfaceUserClientV3       # original
+-- IOUSBInterface@2                     # original
+-- FaceTimeDisabler                     # my kext matching as IOUSBDevice

Я думал, что смысл сопоставления устройства и драйвера заключается в выборе одного kext для подключения к устройству, поэтому я ожидал, что если мой kext совпадет с наивысшей оценкой зонда, он получит эксклюзивный контроль над устройством, но это явно не так. дело.

Мои вопросы таковы:

  1. Как я могу гарантировать, что мой kext получит эксклюзивный доступ к устройству?
  2. Если есть лучший способ отключить доступ к устройству, то какой?

person Neil Steiner    schedule 21.09.2015    source источник


Ответы (1)


Если вы хотите получить эксклюзивный доступ к USB-устройству или интерфейсу, вам потребуется open() объект nub, указав бит kUSBOptionBitOpenExclusivelyMask в аргументе options.

Итак, в вашем методе FaceTimeDisabler start() сделайте что-то вроде:

IOUSBNub* usb_provider = OSDynamicCast(IOUSBNub, provider);
if (usb_provider == nullptr)
{
  IOLog("FaceTimeDisabler: Provider is not USB nub\n");
  return false;
}

bool got_exclusive_access = usb_provider->open(this, kUSBOptionBitOpenExclusivelyMask);
this->opened = got_exclusive_access;
if (!got_exclusive_access)
{
  IOLog("FaceTimeDisabler: failed to acquire exclusive access to camera USB device/interface.\n");
  return false;
}

А затем в своем методе stop() убедитесь, что вы делаете соответствующий вызов close(), если и только open() выполняется успешно (this->opened верно в приведенном выше примере).

Обратите внимание, что флаг kUSBOptionBitOpenExclusivelyMask работает только для семейства USB, хотя open() существует везде. Для объектов IOPCIDevice эксклюзивность подразумевается в open(), поэтому не передавайте бит эксклюзивности USB, когда пытаетесь заблокировать доступ к камерам FaceTime на базе PCI, а вызывайте open/close. (Моя 13-дюймовая камера rMBP 2015 года основана на PCI — идентификатор производителя 0x14e4, идентификатор устройства 0x1570, код класса 04 80 00)

person pmdj    schedule 21.09.2015
comment
Прекрасно работает. Отмечено в kUSBOptionBitOpenExclusivelyMask, относящемся только к USB-устройствам. - person Neil Steiner; 21.09.2015