Skip to content

Commit

Permalink
More improvements in matching logic
Browse files Browse the repository at this point in the history
  • Loading branch information
lvs1974 committed Aug 30, 2020
1 parent e78e721 commit 087819d
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 108 deletions.
26 changes: 13 additions & 13 deletions AirportBrcmFixup/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@
<string>$(MODULE_VERSION)</string>
<key>IOKitPersonalities</key>
<dict>
<key>as.lvs1974.AirportBrcmFixup</key>
<dict>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOClass</key>
<string>$(PRODUCT_NAME:rfc1034identifier)</string>
<key>IOMatchCategory</key>
<string>$(PRODUCT_NAME:rfc1034identifier)</string>
<key>IOProviderClass</key>
<string>IOResources</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
</dict>
<key>as.lvs1974.FakeAirportBrcmFixup</key>
<dict>
<key>CFBundleIdentifier</key>
Expand Down Expand Up @@ -61,19 +74,6 @@
<key>TruePowerOff</key>
<true/>
</dict>
<key>as.lvs1974.AirportBrcmFixup</key>
<dict>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOClass</key>
<string>$(PRODUCT_NAME:rfc1034identifier)</string>
<key>IOMatchCategory</key>
<string>$(PRODUCT_NAME:rfc1034identifier)</string>
<key>IOProviderClass</key>
<string>IOResources</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
</dict>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 lvs1974. All rights reserved.</string>
Expand Down
139 changes: 64 additions & 75 deletions AirportBrcmFixup/kern_brcmfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
#include <IOKit/IOCatalogue.h>
#include <IOKit/IOTimerEventSource.h>

#define kCFBundleIdentifierKey "CFBundleIdentifier"
#define kCFBundleIdentifierKernelKey "CFBundleIdentifierKernel"
#define KIOClass "IOClass"

// Only used in apple-driven callbacks
static BRCMFX *callbackBRCMFX {nullptr};

Expand All @@ -36,6 +32,7 @@ static bool kext_handled[kextListSize] {};

bool BRCMFX::init()
{
DBGLOG("BRCMFX", "init method is called");
callbackBRCMFX = this;

lilu.onPatcherLoadForce(
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand All @@ -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)
Expand All @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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<IOCatalogue_startMatching_symbol>(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue13startMatchingEPK8OSSymbol"));
Expand All @@ -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<IOCatalogue_findDrivers>(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue11findDriversEP12OSDictionaryPi"));
if (!findDrivers)
SYSLOG("BRCMFX", "Fail to resolve IOCatalogue::findDrivers method, error = %d", patcher.getError());
}

if (!removeDrivers)
{
removeDrivers = reinterpret_cast<IOCatalogue_removeDrivers>(patcher.solveSymbol(KernelPatcher::KernelID, "__ZN11IOCatalogue13removeDriversEP12OSDictionaryb"));
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions AirportBrcmFixup/kern_brcmfx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand Down Expand Up @@ -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] {""};
Expand Down
Loading

0 comments on commit 087819d

Please sign in to comment.