From 087819da57fd995f4d5e32c5af6e6168b0cbe8b8 Mon Sep 17 00:00:00 2001 From: lvs1974 Date: Sun, 30 Aug 2020 20:21:13 +0200 Subject: [PATCH] More improvements in matching logic --- AirportBrcmFixup/Info.plist | 26 +++--- AirportBrcmFixup/kern_brcmfx.cpp | 139 +++++++++++++---------------- AirportBrcmFixup/kern_brcmfx.hpp | 2 - AirportBrcmFixup/kern_fakebrcm.cpp | 73 +++++++++++---- AirportBrcmFixup/kern_fakebrcm.hpp | 1 + AirportBrcmFixup/kern_misc.hpp | 4 + 6 files changed, 137 insertions(+), 108 deletions(-) diff --git a/AirportBrcmFixup/Info.plist b/AirportBrcmFixup/Info.plist index e96d24f..7e44085 100644 --- a/AirportBrcmFixup/Info.plist +++ b/AirportBrcmFixup/Info.plist @@ -22,6 +22,19 @@ $(MODULE_VERSION) IOKitPersonalities + as.lvs1974.AirportBrcmFixup + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + IOClass + $(PRODUCT_NAME:rfc1034identifier) + IOMatchCategory + $(PRODUCT_NAME:rfc1034identifier) + IOProviderClass + IOResources + IOResourceMatch + IOKit + as.lvs1974.FakeAirportBrcmFixup CFBundleIdentifier @@ -61,19 +74,6 @@ TruePowerOff - as.lvs1974.AirportBrcmFixup - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - IOClass - $(PRODUCT_NAME:rfc1034identifier) - IOMatchCategory - $(PRODUCT_NAME:rfc1034identifier) - IOProviderClass - IOResources - IOResourceMatch - IOKit - NSHumanReadableCopyright Copyright © 2017 lvs1974. All rights reserved. diff --git a/AirportBrcmFixup/kern_brcmfx.cpp b/AirportBrcmFixup/kern_brcmfx.cpp index 6edecf9..a11a200 100644 --- a/AirportBrcmFixup/kern_brcmfx.cpp +++ b/AirportBrcmFixup/kern_brcmfx.cpp @@ -15,10 +15,6 @@ #include #include -#define kCFBundleIdentifierKey "CFBundleIdentifier" -#define kCFBundleIdentifierKernelKey "CFBundleIdentifierKernel" -#define KIOClass "IOClass" - // Only used in apple-driven callbacks static BRCMFX *callbackBRCMFX {nullptr}; @@ -36,6 +32,7 @@ static bool kext_handled[kextListSize] {}; bool BRCMFX::init() { + DBGLOG("BRCMFX", "init method is called"); callbackBRCMFX = this; lilu.onPatcherLoadForce( @@ -173,9 +170,9 @@ int32_t BRCMFX::siPmuFvcoPllreg(uint32_t *a1, int64_t a2, int64_t a3) bool BRCMFX::start(IOService* service, IOService* provider) { - DBGLOG("BRCMFX", "start is called, service name is %s, provider name is %s", service->getName(), provider->getName()); + DBGLOG("BRCMFX", "start is called, service name is %s, provider name is %s", safeString(service->getName()), safeString(provider->getName())); - int index = find_service_index(service->getName()); + int index = find_service_index(safeString(service->getName())); int brcmfx_driver = ADDPR(brcmfx_config).brcmfx_driver; if (brcmfx_driver == -1 && WIOKit::getOSDataValue(provider, Configuration::bootargBrcmDriver, brcmfx_driver)) { DBGLOG("BRCMFX", "%s in ioreg is set to %d", Configuration::bootargBrcmDriver, brcmfx_driver); @@ -187,7 +184,7 @@ bool BRCMFX::start(IOService* service, IOService* provider) bool disable_driver = (brcmfx_driver == -1 && index == AirPort_BrcmNIC_MFG) || (brcmfx_driver != -1 && brcmfx_driver != index); if (index < 0 || disable_driver) { - DBGLOG("BRCMFX", "start: disable service %s", service->getName()); + DBGLOG("BRCMFX", "start: disable service %s", safeString(service->getName())); return nullptr; } @@ -198,7 +195,7 @@ bool BRCMFX::start(IOService* service, IOService* provider) DBGLOG("BRCMFX", "%s in ioreg is set to %s", Configuration::bootargBrcmCountry, callbackBRCMFX->provider_country_code); } - auto name = provider->getName(); + auto name = safeString(provider->getName()); // There could be only one ARPT if (!name || strcmp(name, "ARPT") != 0) @@ -217,8 +214,8 @@ bool BRCMFX::start(IOService* service, IOService* provider) IOService* BRCMFX::probe(IOService *service, IOService * provider, SInt32 *score) { - DBGLOG("BRCMFX", "probe is called, service name is %s, provider name is %s", service->getName(), provider->getName()); - int index = find_service_index(service->getName()); + DBGLOG("BRCMFX", "probe is called, service name is %s, provider name is %s", safeString(service->getName()), safeString(provider->getName())); + int index = find_service_index(safeString(service->getName())); int brcmfx_driver = ADDPR(brcmfx_config).brcmfx_driver; if (brcmfx_driver == -1 && WIOKit::getOSDataValue(provider, Configuration::bootargBrcmDriver, brcmfx_driver)) { DBGLOG("BRCMFX", "%s in ioreg is set to %d", Configuration::bootargBrcmDriver, brcmfx_driver); @@ -230,7 +227,7 @@ IOService* BRCMFX::probe(IOService *service, IOService * provider, SInt32 *score bool disable_driver = (brcmfx_driver == -1 && index == AirPort_BrcmNIC_MFG) || (brcmfx_driver != -1 && brcmfx_driver != index); if (index < 0 || disable_driver) { - DBGLOG("BRCMFX", "probe: disable service %s", service->getName()); + DBGLOG("BRCMFX", "probe: disable service %s", safeString(service->getName())); return nullptr; } @@ -279,7 +276,7 @@ IOService* LIBKERN_RETURNS_NOT_RETAINED findService(const IORegistryPlane* plane IORegistryEntry *res {nullptr}; while ((res = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != nullptr) { - const char *resname = res->getName(); + auto resname = safeString(res->getName()); if (resname && !strncmp(service_name, resname, len)) { service = OSDynamicCast(IOService, res); @@ -298,6 +295,7 @@ IOService* LIBKERN_RETURNS_NOT_RETAINED findService(const IORegistryPlane* plane void BRCMFX::processKernel(KernelPatcher &patcher) { + DBGLOG("BRCMFX", "processKernel method is called"); if (!startMatching_symbol && !startMatching_dictionary) { startMatching_symbol = reinterpret_cast(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue13startMatchingEPK8OSSymbol")); @@ -306,13 +304,6 @@ void BRCMFX::processKernel(KernelPatcher &patcher) SYSLOG("BRCMFX", "Fail to resolve IOCatalogue::startMatching method, error = %d", patcher.getError()); } - if (!findDrivers) - { - findDrivers = reinterpret_cast(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue11findDriversEP12OSDictionaryPi")); - if (!findDrivers) - SYSLOG("BRCMFX", "Fail to resolve IOCatalogue::findDrivers method, error = %d", patcher.getError()); - } - if (!removeDrivers) { removeDrivers = reinterpret_cast(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue13removeDriversEP12OSDictionaryb")); @@ -418,40 +409,6 @@ void BRCMFX::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t ADDPR(brcmfx_config).disabled = true; - IOService *service = findService(gIOServicePlane, "FakeBrcm"); - if (service && service->getProvider()) - { - auto bundle = OSDynamicCast(OSString, service->getProperty(kCFBundleIdentifierKey)); - auto ioclass = OSDynamicCast(OSString, service->getProperty(KIOClass)); - bool success = false; - - IOService *provider = service->getProvider(); - if (provider) - { - provider->retain(); - if (service->terminate()) - success = true; - provider->release(); - DBGLOG("BRCMFX", "terminating FakeBrcm with status %d", success); - } - else - success = true; - - if (success && bundle && ioclass && removeDrivers) - { - OSDictionary * dict = OSDictionary::withCapacity(2); - if (dict) { - dict->setObject(kCFBundleIdentifierKey, bundle); - dict->setObject(KIOClass, ioclass); - if (!removeDrivers(gIOCatalogue, dict, false)) - SYSLOG("BRCMFX", "gIOCatalogue->removeDrivers failed"); - else - DBGLOG("BRCMFX", "gIOCatalogue->removeDrivers successful"); - OSSafeReleaseNULL(dict); - } - } - } - if (!matchingTimer) { if (!workLoop) workLoop = IOWorkLoop::workLoop(); @@ -484,35 +441,67 @@ void BRCMFX::startMatching() { DBGLOG("BRCMFX", "startMatching is called"); -#ifdef DEBUG - if (findDrivers) { - for (int i=0; i < kextListSize; i++) + IOService *service = findService(gIOServicePlane, "FakeBrcm"); + if (service && service->getProvider()) + { + auto bundle = OSDynamicCast(OSString, service->getProperty(kCFBundleIdentifierKey)); + auto ioclass = OSDynamicCast(OSString, service->getProperty(KIOClass)); + bool success = false; + + IOService *provider = service->getProvider(); + if (provider) { - int brcmfx_driver = checkBrcmfxDriverValue(i, true); - if (i != brcmfx_driver) - continue; - auto bundle = OSSymbol::withCStringNoCopy(idList[i]); - if (!bundle) - continue; - OSDictionary * dict = OSDictionary::withCapacity(1); + provider->retain(); + if (service->terminate()) + success = true; + provider->release(); + DBGLOG("BRCMFX", "terminating FakeBrcm with status %d", success); + } + else + success = true; + + if (success && bundle && ioclass && removeDrivers) + { + OSDictionary * dict = OSDictionary::withCapacity(2); if (dict) { dict->setObject(kCFBundleIdentifierKey, bundle); - SInt32 generation = 0; - OSOrderedSet *set = findDrivers(gIOCatalogue, dict, &generation); - if (set) { - if (set->getCount() > 0) - SYSLOG("BRCMFX", "gIOCatalogue->findDrivers() returned non-empty ordered set for bundle %s", idList[i]); - else - SYSLOG("BRCMFX", "gIOCatalogue->findDrivers() returned empty ordered set for bundle %s", idList[i]); - } - else { - SYSLOG("BRCMFX", "gIOCatalogue->findDrivers() failed for bundle %s", idList[i]); - } + dict->setObject(KIOClass, ioclass); + if (!removeDrivers(gIOCatalogue, dict, false)) + SYSLOG("BRCMFX", "gIOCatalogue->removeDrivers failed"); + else + DBGLOG("BRCMFX", "gIOCatalogue->removeDrivers successful"); OSSafeReleaseNULL(dict); - OSSafeReleaseNULL(set); } } } + +#ifdef DEBUG + for (int i=0; i < kextListSize; i++) + { + int brcmfx_driver = checkBrcmfxDriverValue(i, true); + if (i != brcmfx_driver) + continue; + auto bundle = OSSymbol::withCStringNoCopy(idList[i]); + if (!bundle) + continue; + OSDictionary * dict = OSDictionary::withCapacity(1); + if (dict) { + dict->setObject(kCFBundleIdentifierKey, bundle); + SInt32 generation = 0; + OSOrderedSet *set = gIOCatalogue->findDrivers(dict, &generation); + if (set) { + if (set->getCount() > 0) + DBGLOG("BRCMFX", "gIOCatalogue->findDrivers() returned non-empty ordered set for bundle %s", idList[i]); + else + DBGLOG("BRCMFX", "gIOCatalogue->findDrivers() returned empty ordered set for bundle %s", idList[i]); + } + else { + DBGLOG("BRCMFX", "gIOCatalogue->findDrivers() failed for bundle %s", idList[i]); + } + OSSafeReleaseNULL(dict); + OSSafeReleaseNULL(set); + } + } #endif if (startMatching_symbol) diff --git a/AirportBrcmFixup/kern_brcmfx.hpp b/AirportBrcmFixup/kern_brcmfx.hpp index 061a723..78ba397 100644 --- a/AirportBrcmFixup/kern_brcmfx.hpp +++ b/AirportBrcmFixup/kern_brcmfx.hpp @@ -51,7 +51,6 @@ class BRCMFX { */ using IOCatalogue_startMatching_symbol = bool (*)(void *that, OSSymbol const* bundle_identifier); using IOCatalogue_startMatching_dictionary = bool (*)(void *that, OSDictionary *matching); - using IOCatalogue_findDrivers = OSOrderedSet* (*)(void *that, OSDictionary *matching, SInt32 * generationCount); using IOCatalogue_removeDrivers = bool (*)(void *that, OSDictionary *matching, bool doNubMatching); /** @@ -85,7 +84,6 @@ class BRCMFX { // access to IOCatalogue methods IOCatalogue_startMatching_symbol startMatching_symbol {}; IOCatalogue_startMatching_dictionary startMatching_dictionary {}; - IOCatalogue_findDrivers findDrivers {}; IOCatalogue_removeDrivers removeDrivers {}; char provider_country_code[5] {""}; diff --git a/AirportBrcmFixup/kern_fakebrcm.cpp b/AirportBrcmFixup/kern_fakebrcm.cpp index 21458e0..5dba41e 100644 --- a/AirportBrcmFixup/kern_fakebrcm.cpp +++ b/AirportBrcmFixup/kern_fakebrcm.cpp @@ -11,7 +11,7 @@ #include "kern_fakebrcm.hpp" #include "kern_misc.hpp" #include - +#include OSDefineMetaClassAndStructors(FakeBrcm, IOService); @@ -31,7 +31,7 @@ bool PCIHookManager::isServiceSupported(IORegistryEntry* service) for (int i=0; igetName()) == 0) + if (strcmp(serviceNameList[i], safeString(service->getName())) == 0) return true; } return false; @@ -64,7 +64,7 @@ UInt16 PCIHookManager::configRead16(IORegistryEntry *service, UInt32 space, UInt } if (newResult != result) - DBGLOG("BRCMFX", "PCIHookManager::configRead16: name = %s, source value = 0x%04x replaced with value = 0x%04x", service->getName(), result, newResult); + DBGLOG("BRCMFX", "PCIHookManager::configRead16: name = %s, source value = 0x%04x replaced with value = 0x%04x", safeString(service->getName()), result, newResult); return newResult; } @@ -87,7 +87,7 @@ UInt32 PCIHookManager::configRead32(IORegistryEntry *service, UInt32 space, UInt } if (newResult != result) - DBGLOG("BRCMFX", "PCIHookManager::configRead32: name = %s, source value = 0x%08x replaced with value = 0x%08x", service->getName(), result, newResult); + DBGLOG("BRCMFX", "PCIHookManager::configRead32: name = %s, source value = 0x%08x replaced with value = 0x%08x", safeString(service->getName()), result, newResult); return newResult; } @@ -96,6 +96,8 @@ UInt32 PCIHookManager::configRead32(IORegistryEntry *service, UInt32 space, UInt void PCIHookManager::hookProvider(IOService *provider) { + awaitPublishing(provider); + auto pciDevice = OSDynamicCast(IOPCIDevice, provider); if (!pciDevice) { DBGLOG("BRCMFX", "Provider is not IOPCIDevice"); @@ -168,6 +170,32 @@ void PCIHookManager::hookProvider(IOService *provider) DBGLOG("BRCMFX", "PCIHookManager::hookProvider for configRead32 was successful"); } +//============================================================================== + +bool PCIHookManager::awaitPublishing(IORegistryEntry *obj) +{ + size_t counter = 0; + while (counter < 256) { + if (obj->inPlane(gIOServicePlane)) { + DBGLOG("BRCMFX", "pci device %s is in service plane %lu", safeString(obj->getName()), counter); + return true; + } + DBGLOG("BRCMFX", "pci device %s is not in service plane %lu, polling", safeString(obj->getName()), counter); + + if (obj->getProperty("IOPCIConfigured")) { + DBGLOG("dev", "pci bridge %s is configured %lu", safeString(obj->getName()), counter); + break; + } + DBGLOG("BRCMFX", "pci bridge %s is not configured %lu, polling", safeString(obj->getName()), counter); + ++counter; + IOSleep(20); + } + + SYSLOG("BRCMFX", "found dead pci device %s", safeString(obj->getName())); + return false; +} + + //============================================================================== bool FakeBrcm::init(OSDictionary *propTable) @@ -223,7 +251,7 @@ IOService* FakeBrcm::probe(IOService * provider, SInt32 *score) return ret; } - DBGLOG("BRCMFX", "FakeBrcm::probe(): service provider is %s", provider->getName()); + DBGLOG("BRCMFX", "FakeBrcm::probe(): service provider is %s", safeString(provider->getName())); for (int i = 0; i < kextListSize; i++) { @@ -231,20 +259,29 @@ IOService* FakeBrcm::probe(IOService * provider, SInt32 *score) if (i != brcmfx_driver) continue; - const OSMetaClass * meta_class = OSMetaClass::getMetaClassWithName(OSSymbol::withCStringNoCopy(serviceNameList[i])); - if (meta_class != nullptr) - { - DBGLOG("BRCMFX", "FakeBrcm::probe(): meta class for %s exists!", serviceNameList[i]); - - IOService *service = OSDynamicCast(IOService, meta_class->alloc()); - if (service != nullptr) - { - service->retain(); - DBGLOG("BRCMFX", "FakeBrcm: retain counter for driver %s is %d", serviceNameList[i], service->getRetainCount()); - service_found = true; + auto bundle = OSSymbol::withCStringNoCopy(idList[i]); + if (bundle) { + OSDictionary * dict = OSDictionary::withCapacity(1); + if (dict) { + dict->setObject(kCFBundleIdentifierKey, bundle); + SInt32 generation = 0; + OSOrderedSet *set = gIOCatalogue->findDrivers(dict, &generation); + if (set) { + if (set->getCount() > 0) + { + DBGLOG("BRCMFX", "FakeBrcm::probe(): gIOCatalogue->findDrivers() returned non-empty ordered set for bundle %s", idList[i]); + service_found = true; + + } + else + DBGLOG("BRCMFX", "FakeBrcm::probe(): gIOCatalogue->findDrivers() returned empty ordered set for bundle %s", idList[i]); + } + else { + SYSLOG("BRCMFX", "FakeBrcm::probe(): gIOCatalogue->findDrivers() failed for bundle %s", idList[i]); + } + OSSafeReleaseNULL(dict); + OSSafeReleaseNULL(set); } - else - SYSLOG("BRCMFX", "FakeBrcm: instance of driver %s couldn't be created", serviceNameList[i]); } } diff --git a/AirportBrcmFixup/kern_fakebrcm.hpp b/AirportBrcmFixup/kern_fakebrcm.hpp index a713fe0..44d0bb3 100644 --- a/AirportBrcmFixup/kern_fakebrcm.hpp +++ b/AirportBrcmFixup/kern_fakebrcm.hpp @@ -25,6 +25,7 @@ class EXPORT PCIHookManager public: static void hookProvider(IOService* provider); + static bool awaitPublishing(IORegistryEntry *obj); }; class EXPORT FakeBrcm : public IOService diff --git a/AirportBrcmFixup/kern_misc.hpp b/AirportBrcmFixup/kern_misc.hpp index 4b864cc..7d00bdc 100644 --- a/AirportBrcmFixup/kern_misc.hpp +++ b/AirportBrcmFixup/kern_misc.hpp @@ -10,6 +10,10 @@ #include +#define kCFBundleIdentifierKey "CFBundleIdentifier" +#define kCFBundleIdentifierKernelKey "CFBundleIdentifierKernel" +#define KIOClass "IOClass" + static const size_t kextListSize {4}; enum AirportServices {