Gain user-space access to hardware devices and drivers using IOKit.

Posts under IOKit tag

29 Posts

Post

Replies

Boosts

Views

Activity

Kext loads well after launchd and early os_log entries rarely appear in unified log
Is there a way to ensure a kernel extension in the Auxiliary Kernel Collection loads (and runs its start routines) before launchd? I'm emitting logs via os_log_t created with an os_log_create (custom subsystem/category) in both my KMOD's start function and the IOService::start() function. Those messages-- which both say "I've been run"-- inconsistently show up in log show --predicate 'subsystem == "com.bluefalconhd.pandora"' --last boot, which makes me think they are running very early. However, I also record timestamps (using mach_absolute_time, etc.) and expose them to user space through an IOExternalMethod. The results (for the most recent boot): hayes@fortis Pandora/tests main % build/pdtest Pandora Metadata: kmod_start_time: Time: 2025-07-22 14:11:32.233 Mach time: 245612546 Nanos since boot: 10233856083 (10.23 seconds) io_service_start_time: Time: 2025-07-22 14:11:32.233 Mach time: 245613641 Nanos since boot: 10233901708 (10.23 seconds) user_client_init_time: Time: 2025-07-22 14:21:42.561 Mach time: 14893478355 Nanos since boot: 620561598125 (620.56 seconds) hayes@fortis Pandora/tests main % ps -p 1 -o lstart= Tue Jul 22 14:11:27 2025 Everything in the kernel extension appears to be loading after launchd (PID 1) starts. Also, the kext isn't doing anything crazy which could cause that kind of delay. For reference, here's the Info.plist: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleExecutable</key> <string>Pandora</string> <key>CFBundleIdentifier</key> <string>com.bluefalconhd.Pandora</string> <key>CFBundleName</key> <string>Pandora</string> <key>CFBundlePackageType</key> <string>KEXT</string> <key>CFBundleVersion</key> <string>1.0.7</string> <key>IOKitPersonalities</key> <dict> <key>Pandora</key> <dict> <key>CFBundleIdentifier</key> <string>com.bluefalconhd.Pandora</string> <key>IOClass</key> <string>Pandora</string> <key>IOMatchCategory</key> <string>Pandora</string> <key>IOProviderClass</key> <string>IOResources</string> <key>IOResourceMatch</key> <string>IOKit</string> <key>IOUserClientClass</key> <string>PandoraUserClient</string> </dict> </dict> <key>OSBundleLibraries</key> <dict> <key>com.apple.kpi.dsep</key> <string>24.2.0</string> <key>com.apple.kpi.iokit</key> <string>24.2.0</string> <key>com.apple.kpi.libkern</key> <string>24.2.0</string> <key>com.apple.kpi.mach</key> <string>24.2.0</string> </dict> </dict> </plist> My questions are: A. Why don't the early logs (from KMOD's start function and IOService::start) consistently appear in the unified log, while logs later in IOExternalMethods do? B. How can I force this kext to load earlier-- ideally before launchd? Thanks in advance for any guidance!
0
0
255
Jul ’25
Does CMIO support "hide" build-in camera
Hi guys, Can I use CMIO to achieve the following feature on macOS when a USB device (Camera/Mic/Speaker) is connected: When a third-party video conferencing app is not in a meeting, ensure the app defaults to using the USB device (Camera/Mic/Speaker). When a third-party conferencing app is in a meeting, ensure the app automatically switches to the USB device (Camera/Mic/Speaker).
2
0
428
Jul ’25
Why a driverkit extension needs a CMIO extension
I developed a driverkit extension based on overriding-the-default-usb-video-class-extension, but the link didn’t give the details of realization. I asked DTS who gave two tips: 1, Do you also have a CMIO extension to load in place of the default overriding-the-default-usb-video-class-extension 2, Your DriverKit extension’s info.plist is also missing the CameraAssistantBundleID. I want to know why a driverkit extension needs a CMIO extension, what’s the data and control flow?
2
0
599
Jun ’25
How to toggle usb device
When I use IOKit/usb/IOUSBLib to toggle build-in camera, I got an ERROR:ret IOReturn -536870210 How can I resolve it? Can I use IOUSBLib to disable or hide build-in camera? My environment: Model Name: MacBook Pro ProductVersion: 15.5 Model Identifier: MacBookPro15,2 Processor Name: Quad-Core Intel Core i5 Processor Speed: 2.4 GHz Number of Processors: 1 // 禁用/启用USB设备 bool toggleUSBDevice(uint16_t vendorID, uint16_t productID, bool enable) { std::cout << (enable ? "Enabling" : "Disabling") << " USB device with VID: 0x" << std::hex << vendorID << ", PID: 0x" << productID << std::endl; // 创建匹配字典查找指定VID/PID的USB设备 CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (!matchingDict) { std::cerr << "Failed to create USB device matching dictionary." << std::endl; return false; } // 设置VID/PID匹配条件 CFNumberRef vendorIDRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &vendorID); CFNumberRef productIDRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &productID); CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), vendorIDRef); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), productIDRef); CFRelease(vendorIDRef); CFRelease(productIDRef); // 获取匹配的设备迭代器 io_iterator_t deviceIterator; if (IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &deviceIterator) != KERN_SUCCESS) { std::cerr << "Failed to get USB device iterator." << std::endl; CFRelease(matchingDict); return false; } io_service_t usbDevice; bool result = false; int deviceCount = 0; // 遍历所有匹配的设备 while ((usbDevice = IOIteratorNext(deviceIterator)) != IO_OBJECT_NULL) { deviceCount++; // 获取设备路径 char path[1024]; if (IORegistryEntryGetPath(usbDevice, kIOServicePlane, path) == KERN_SUCCESS) { std::cout << "Found device at path: " << path << std::endl; } // 打开设备 IOCFPlugInInterface** plugInInterface = NULL; IOUSBDeviceInterface** deviceInterface = NULL; SInt32 score; IOReturn ret = IOCreatePlugInInterfaceForService( usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if (ret == kIOReturnSuccess && plugInInterface) { ret = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&deviceInterface); (*plugInInterface)->Release(plugInInterface); } if (ret != kIOReturnSuccess) { std::cerr << "Failed to open USB device interface. Error:" << ret << std::endl; IOObjectRelease(usbDevice); continue; } // 禁用/启用设备 if (enable) { // 启用设备 - 重新配置设备 ret = (*deviceInterface)->USBDeviceReEnumerate(deviceInterface, 0); if (ret == kIOReturnSuccess) { std::cout << "Device enabled successfully." << std::endl; result = true; } else { std::cerr << "Failed to enable device. Error: " << ret << std::endl; } } else { // 禁用设备 - 断开设备连接 ret = (*deviceInterface)->USBDeviceClose(deviceInterface); if (ret == kIOReturnSuccess) { std::cout << "Device disabled successfully." << std::endl; result = true; } else { std::cerr << "Failed to disable device. Error: " << ret << std::endl; } } // 关闭设备接口 (*deviceInterface)->Release(deviceInterface); IOObjectRelease(usbDevice); } IOObjectRelease(deviceIterator); if (deviceCount == 0) { std::cerr << "No device found with specified VID/PID." << std::endl; return false; } return result; }
0
0
255
Jun ’25
get Wi-Fi controller info
Hello, I'm trying to get a list of all network devices (device audit for DLP system). CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIONetworkControllerClass); if (matchingDictionary == nullptr) { std::cerr << "IOServiceMatching() returned empty matching dictionary" << std::endl; return 1; } io_iterator_t iter; if (kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iter); kr != KERN_SUCCESS) { std::cerr << "IOServiceGetMatchingServices() failed" << std::endl; return 1; } io_service_t networkController; while ((networkController = IOIteratorNext(iter)) != IO_OBJECT_NULL) { std::cout << "network device: "; if (CFDataRef cfIOMACAddress = (CFDataRef) IORegistryEntryCreateCFProperty(networkController, CFSTR(kIOMACAddress), kCFAllocatorDefault, kNilOptions); cfIOMACAddress != nullptr) { std::vector<uint8_t> data(CFDataGetLength(cfIOMACAddress)); CFDataGetBytes(cfIOMACAddress, CFRangeMake(0, data.size()), data.data()); std::cout << std::hex << std::setfill('0') << std::setw(2) << (short)data[0] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[1] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[2] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[3] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[4] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[5]; CFRelease(cfIOMACAddress); } std::cout << std::endl; IOObjectRelease(networkController); } IOObjectRelease(iter); The Wi-Fi controller shows up in I/O Registry Explorer, but IOServiceGetMatchingServices() does not return any information about it. Any way to retrieve Wi-Fi controller info in daemon code? Thank you in advance!
3
0
192
Jun ’25
block all USB devices
Hello, I am working on app which must prevent attaching any USB devices to Mac due to security. Unfortunately I have not found any direct way to implement such blocking: Looks like IOKit does not allow to block USB (at least in user space) ES_EVENT_TYPE_AUTH_IOKIT_OPEN (Endpoint Security) does not prevent using USB device if I send response ES_AUTH_RESULT_DENY for "AppleUSBHostDeviceUserClient" I have found several similar problems on forum but no any solution: https://developer.apple.com/forums/thread/671193 (https://developer.apple.com/forums/thread/756573 https://developer.apple.com/forums/thread/741051 What is the easiest way to implement such blocking? Thank you in advance!
7
0
1.6k
Jun ’25
how to enumerate build-in media devices?
Hello, I need to enumerate built-in media devices (cameras, microphones, etc.). For this purpose, I am using the CoreAudio and CoreMediaIO frameworks. According to the table 'Daemon-Safe Frameworks' in Apple’s TN2083, CoreAudio is daemon-safe. However, the documentation does not mention CoreMediaIO. Can CoreMediaIO be used in a daemon? If not, are there any documented alternatives to detect built-in cameras in a daemon (e.g., via device classes in IOKit)? Thank you in advance, Pavel
0
0
228
May ’25
Kext loads well after launchd and early os_log entries rarely appear in unified log
Is there a way to ensure a kernel extension in the Auxiliary Kernel Collection loads (and runs its start routines) before launchd? I'm emitting logs via os_log_t created with an os_log_create (custom subsystem/category) in both my KMOD's start function and the IOService::start() function. Those messages-- which both say "I've been run"-- inconsistently show up in log show --predicate 'subsystem == "com.bluefalconhd.pandora"' --last boot, which makes me think they are running very early. However, I also record timestamps (using mach_absolute_time, etc.) and expose them to user space through an IOExternalMethod. The results (for the most recent boot): hayes@fortis Pandora/tests main % build/pdtest Pandora Metadata: kmod_start_time: Time: 2025-07-22 14:11:32.233 Mach time: 245612546 Nanos since boot: 10233856083 (10.23 seconds) io_service_start_time: Time: 2025-07-22 14:11:32.233 Mach time: 245613641 Nanos since boot: 10233901708 (10.23 seconds) user_client_init_time: Time: 2025-07-22 14:21:42.561 Mach time: 14893478355 Nanos since boot: 620561598125 (620.56 seconds) hayes@fortis Pandora/tests main % ps -p 1 -o lstart= Tue Jul 22 14:11:27 2025 Everything in the kernel extension appears to be loading after launchd (PID 1) starts. Also, the kext isn't doing anything crazy which could cause that kind of delay. For reference, here's the Info.plist: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleExecutable</key> <string>Pandora</string> <key>CFBundleIdentifier</key> <string>com.bluefalconhd.Pandora</string> <key>CFBundleName</key> <string>Pandora</string> <key>CFBundlePackageType</key> <string>KEXT</string> <key>CFBundleVersion</key> <string>1.0.7</string> <key>IOKitPersonalities</key> <dict> <key>Pandora</key> <dict> <key>CFBundleIdentifier</key> <string>com.bluefalconhd.Pandora</string> <key>IOClass</key> <string>Pandora</string> <key>IOMatchCategory</key> <string>Pandora</string> <key>IOProviderClass</key> <string>IOResources</string> <key>IOResourceMatch</key> <string>IOKit</string> <key>IOUserClientClass</key> <string>PandoraUserClient</string> </dict> </dict> <key>OSBundleLibraries</key> <dict> <key>com.apple.kpi.dsep</key> <string>24.2.0</string> <key>com.apple.kpi.iokit</key> <string>24.2.0</string> <key>com.apple.kpi.libkern</key> <string>24.2.0</string> <key>com.apple.kpi.mach</key> <string>24.2.0</string> </dict> </dict> </plist> My questions are: A. Why don't the early logs (from KMOD's start function and IOService::start) consistently appear in the unified log, while logs later in IOExternalMethods do? B. How can I force this kext to load earlier-- ideally before launchd? Thanks in advance for any guidance!
Replies
0
Boosts
0
Views
255
Activity
Jul ’25
Does CMIO support "hide" build-in camera
Hi guys, Can I use CMIO to achieve the following feature on macOS when a USB device (Camera/Mic/Speaker) is connected: When a third-party video conferencing app is not in a meeting, ensure the app defaults to using the USB device (Camera/Mic/Speaker). When a third-party conferencing app is in a meeting, ensure the app automatically switches to the USB device (Camera/Mic/Speaker).
Replies
2
Boosts
0
Views
428
Activity
Jul ’25
How to toggle usb device
Can i use iokit usb lib to disable build-in camera?
Replies
4
Boosts
0
Views
292
Activity
Jun ’25
Why a driverkit extension needs a CMIO extension
I developed a driverkit extension based on overriding-the-default-usb-video-class-extension, but the link didn’t give the details of realization. I asked DTS who gave two tips: 1, Do you also have a CMIO extension to load in place of the default overriding-the-default-usb-video-class-extension 2, Your DriverKit extension’s info.plist is also missing the CameraAssistantBundleID. I want to know why a driverkit extension needs a CMIO extension, what’s the data and control flow?
Replies
2
Boosts
0
Views
599
Activity
Jun ’25
How to toggle usb device
When I use IOKit/usb/IOUSBLib to toggle build-in camera, I got an ERROR:ret IOReturn -536870210 How can I resolve it? Can I use IOUSBLib to disable or hide build-in camera? My environment: Model Name: MacBook Pro ProductVersion: 15.5 Model Identifier: MacBookPro15,2 Processor Name: Quad-Core Intel Core i5 Processor Speed: 2.4 GHz Number of Processors: 1 // 禁用/启用USB设备 bool toggleUSBDevice(uint16_t vendorID, uint16_t productID, bool enable) { std::cout << (enable ? "Enabling" : "Disabling") << " USB device with VID: 0x" << std::hex << vendorID << ", PID: 0x" << productID << std::endl; // 创建匹配字典查找指定VID/PID的USB设备 CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (!matchingDict) { std::cerr << "Failed to create USB device matching dictionary." << std::endl; return false; } // 设置VID/PID匹配条件 CFNumberRef vendorIDRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &vendorID); CFNumberRef productIDRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &productID); CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), vendorIDRef); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), productIDRef); CFRelease(vendorIDRef); CFRelease(productIDRef); // 获取匹配的设备迭代器 io_iterator_t deviceIterator; if (IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &deviceIterator) != KERN_SUCCESS) { std::cerr << "Failed to get USB device iterator." << std::endl; CFRelease(matchingDict); return false; } io_service_t usbDevice; bool result = false; int deviceCount = 0; // 遍历所有匹配的设备 while ((usbDevice = IOIteratorNext(deviceIterator)) != IO_OBJECT_NULL) { deviceCount++; // 获取设备路径 char path[1024]; if (IORegistryEntryGetPath(usbDevice, kIOServicePlane, path) == KERN_SUCCESS) { std::cout << "Found device at path: " << path << std::endl; } // 打开设备 IOCFPlugInInterface** plugInInterface = NULL; IOUSBDeviceInterface** deviceInterface = NULL; SInt32 score; IOReturn ret = IOCreatePlugInInterfaceForService( usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if (ret == kIOReturnSuccess && plugInInterface) { ret = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&deviceInterface); (*plugInInterface)->Release(plugInInterface); } if (ret != kIOReturnSuccess) { std::cerr << "Failed to open USB device interface. Error:" << ret << std::endl; IOObjectRelease(usbDevice); continue; } // 禁用/启用设备 if (enable) { // 启用设备 - 重新配置设备 ret = (*deviceInterface)->USBDeviceReEnumerate(deviceInterface, 0); if (ret == kIOReturnSuccess) { std::cout << "Device enabled successfully." << std::endl; result = true; } else { std::cerr << "Failed to enable device. Error: " << ret << std::endl; } } else { // 禁用设备 - 断开设备连接 ret = (*deviceInterface)->USBDeviceClose(deviceInterface); if (ret == kIOReturnSuccess) { std::cout << "Device disabled successfully." << std::endl; result = true; } else { std::cerr << "Failed to disable device. Error: " << ret << std::endl; } } // 关闭设备接口 (*deviceInterface)->Release(deviceInterface); IOObjectRelease(usbDevice); } IOObjectRelease(deviceIterator); if (deviceCount == 0) { std::cerr << "No device found with specified VID/PID." << std::endl; return false; } return result; }
Replies
0
Boosts
0
Views
255
Activity
Jun ’25
block keyboard and camera due to security reason
Hello, As part of developing a DLP system, I need to block input devices upon detection of data leakage. Could you advise if it's possible to temporarily disable the built-in keyboard and camera? Thank you in advance, Pavel
Replies
4
Boosts
0
Views
473
Activity
Jun ’25
get Wi-Fi controller info
Hello, I'm trying to get a list of all network devices (device audit for DLP system). CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIONetworkControllerClass); if (matchingDictionary == nullptr) { std::cerr << "IOServiceMatching() returned empty matching dictionary" << std::endl; return 1; } io_iterator_t iter; if (kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iter); kr != KERN_SUCCESS) { std::cerr << "IOServiceGetMatchingServices() failed" << std::endl; return 1; } io_service_t networkController; while ((networkController = IOIteratorNext(iter)) != IO_OBJECT_NULL) { std::cout << "network device: "; if (CFDataRef cfIOMACAddress = (CFDataRef) IORegistryEntryCreateCFProperty(networkController, CFSTR(kIOMACAddress), kCFAllocatorDefault, kNilOptions); cfIOMACAddress != nullptr) { std::vector<uint8_t> data(CFDataGetLength(cfIOMACAddress)); CFDataGetBytes(cfIOMACAddress, CFRangeMake(0, data.size()), data.data()); std::cout << std::hex << std::setfill('0') << std::setw(2) << (short)data[0] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[1] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[2] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[3] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[4] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[5]; CFRelease(cfIOMACAddress); } std::cout << std::endl; IOObjectRelease(networkController); } IOObjectRelease(iter); The Wi-Fi controller shows up in I/O Registry Explorer, but IOServiceGetMatchingServices() does not return any information about it. Any way to retrieve Wi-Fi controller info in daemon code? Thank you in advance!
Replies
3
Boosts
0
Views
192
Activity
Jun ’25
block all USB devices
Hello, I am working on app which must prevent attaching any USB devices to Mac due to security. Unfortunately I have not found any direct way to implement such blocking: Looks like IOKit does not allow to block USB (at least in user space) ES_EVENT_TYPE_AUTH_IOKIT_OPEN (Endpoint Security) does not prevent using USB device if I send response ES_AUTH_RESULT_DENY for "AppleUSBHostDeviceUserClient" I have found several similar problems on forum but no any solution: https://developer.apple.com/forums/thread/671193 (https://developer.apple.com/forums/thread/756573 https://developer.apple.com/forums/thread/741051 What is the easiest way to implement such blocking? Thank you in advance!
Replies
7
Boosts
0
Views
1.6k
Activity
Jun ’25
how to enumerate build-in media devices?
Hello, I need to enumerate built-in media devices (cameras, microphones, etc.). For this purpose, I am using the CoreAudio and CoreMediaIO frameworks. According to the table 'Daemon-Safe Frameworks' in Apple’s TN2083, CoreAudio is daemon-safe. However, the documentation does not mention CoreMediaIO. Can CoreMediaIO be used in a daemon? If not, are there any documented alternatives to detect built-in cameras in a daemon (e.g., via device classes in IOKit)? Thank you in advance, Pavel
Replies
0
Boosts
0
Views
228
Activity
May ’25