diff --git a/QualcommWifi/QualcommWifi.cpp b/QualcommWifi/QualcommWifi.cpp index d74e35d..b7e4f4f 100644 --- a/QualcommWifi/QualcommWifi.cpp +++ b/QualcommWifi/QualcommWifi.cpp @@ -50,42 +50,46 @@ static inline void logNvramStage(const char *tag) { } } -typedef IOReturn (*addEventSource_fn)(IOWorkLoop *self, IOEventSource *event); -static addEventSource_fn sOrigAddEventSource = nullptr; -static void **sOrigWorkQueueVtable = nullptr; -static void *sWorkQueueVtable[128]; -static int sAddEventSourceCount = 0; - -static IOReturn hooked_addEventSource(IOWorkLoop *self, IOEventSource *event) { - sAddEventSourceCount++; - char tag[64]; - snprintf(tag, sizeof(tag), "cb_addEvSrc_%d", sAddEventSourceCount); - logNvramStage(tag); - IOSleep(50); - IOLog("QualcommWifi: >>> HOOK fWorkQueue->addEventSource(#%d, event=0x%p) [ENTER] <<<\n", - sAddEventSourceCount, event); - IOReturn res = sOrigAddEventSource(self, event); - char tagExit[64]; - snprintf(tagExit, sizeof(tagExit), "cb_addEvSrc_%d_ok", sAddEventSourceCount); - logNvramStage(tagExit); - IOSleep(50); - IOLog("QualcommWifi: >>> HOOK fWorkQueue->addEventSource(#%d) -> 0x%x [EXIT] <<<\n", - sAddEventSourceCount, res); - return res; -} - -// Classe simulant un FaultReporter IOKit valide (attendu par IO80211Controller::findAndAttachToFaultReporter) -// Conforme à l'ABI CCFaultReporter / IOService (267 slots de vtable, taille 0x90) -class FakeFaultReporter : public IOService { +// Classe simulant un IO80211FaultReporter IOKit conforme (attendu par IO80211Controller et IO80211PeerManager) +// - Hérite directement de OSObject (35 slots de base : 0..34) +// - Déclare les 3 méthodes virtuelles de IO80211FaultReporter : +// slot 35 (offset 0x118) : reportFault(...) +// slot 36 (offset 0x120) : registerCallbacks(...) -> appelé par IO80211PeerManager::initWithInterface (0xffffff8002247d3d) +// slot 37 (offset 0x128) : unregisterCallbacks(...) -> appelé par IO80211PeerManager::free (0xffffff80022490ac) +class FakeFaultReporter : public OSObject { OSDeclareDefaultStructors(FakeFaultReporter) private: - uint8_t _pad[0x90 - sizeof(IOService)]; + uint8_t _pad[0x80]; public: virtual bool init() override { - if (!IOService::init()) return false; + if (!OSObject::init()) return false; bzero(_pad, sizeof(_pad)); return true; } + + // slot 35 (offset 0x118): reportFault + virtual IOReturn reportFault(uint32_t a, const char *b, uint32_t c, const char *d, void *e, int f, const char *g, ...) { + return kIOReturnSuccess; + } + + // slot 36 (offset 0x120): registerCallbacks + // Invoqué par IO80211PeerManager::initWithInterface (0xffffff8002247d3d) + virtual IOReturn registerCallbacks(void *callbacks, unsigned int count, OSObject *owner, const char *owner_name) { + logNvramStage("cb_fault_reg"); + IOSleep(50); + IOLog("QualcommWifi: >>> FakeFaultReporter::registerCallbacks(count=%u, owner=%s) [SUCCESS] <<<\n", + count, owner_name ? owner_name : "null"); + return kIOReturnSuccess; + } + + // slot 37 (offset 0x128): unregisterCallbacks + // Invoqué par IO80211PeerManager::free (0xffffff80022490ac) + virtual IOReturn unregisterCallbacks(OSObject *owner) { + logNvramStage("cb_fault_unreg"); + IOLog("QualcommWifi: >>> FakeFaultReporter::unregisterCallbacks() [SUCCESS] <<<\n"); + return kIOReturnSuccess; + } + static FakeFaultReporter* create() { FakeFaultReporter *inst = new FakeFaultReporter; if (inst && !inst->init()) { @@ -95,8 +99,7 @@ public: return inst; } }; -OSDefineMetaClassAndStructors(FakeFaultReporter, IOService) -static_assert(sizeof(FakeFaultReporter) == 0x90, "FakeFaultReporter size must match CCFaultReporter ABI (0x90)"); +OSDefineMetaClassAndStructors(FakeFaultReporter, OSObject) // Buffers statiques globaux BSS : garantis alloués et mappés dès le chargement du kext, // immunisés contre tout échec de heap dynamique durant le boot précoce. @@ -254,7 +257,6 @@ bool QualcommWifi::init(OSDictionary *dictionary) { sGetFaultReporterCount = 0; sInStep6 = false; sStep6WqCount = 0; - sAddEventSourceCount = 0; logNvramStage("init_enter"); if (!super::init(dictionary)) { @@ -305,12 +307,7 @@ void QualcommWifi::free(void) { OSSafeReleaseNULL(fFaultReporter); OSSafeReleaseNULL(fLogger); OSSafeReleaseNULL(fWorkLoop); - if (fWorkQueue) { - if (sOrigWorkQueueVtable) { - *(void ***)fWorkQueue = sOrigWorkQueueVtable; - } - OSSafeReleaseNULL(fWorkQueue); - } + OSSafeReleaseNULL(fWorkQueue); if (sNvramLock) { IORecursiveLock *lock = sNvramLock; sNvramLock = nullptr; @@ -1065,13 +1062,7 @@ void QualcommWifi::stop(IOService *provider) { OSSafeReleaseNULL(fWorkLoop); } - if (fWorkQueue) { - if (sOrigWorkQueueVtable) { - *(void ***)fWorkQueue = sOrigWorkQueueVtable; - } - OSSafeReleaseNULL(fWorkQueue); - } - + OSSafeReleaseNULL(fWorkQueue); PMstop(); super::stop(provider); } @@ -1088,18 +1079,6 @@ bool QualcommWifi::createWorkQueue(void) { return false; } - // Interception chirurgicale de addEventSource sur fWorkQueue (slot 42 = offset 0x150) - sOrigWorkQueueVtable = *(void ***)fWorkQueue; - if (sOrigWorkQueueVtable && !sOrigAddEventSource) { - memcpy(&sWorkQueueVtable[2], sOrigWorkQueueVtable, sizeof(void *) * 100); - sWorkQueueVtable[0] = sOrigWorkQueueVtable[-2]; - sWorkQueueVtable[1] = sOrigWorkQueueVtable[-1]; - sOrigAddEventSource = (addEventSource_fn)sOrigWorkQueueVtable[42]; - sWorkQueueVtable[2 + 42] = (void *)&hooked_addEventSource; - *(void ***)fWorkQueue = &sWorkQueueVtable[2]; - IOLog("QualcommWifi: Vtable de fWorkQueue interceptée avec succès (addEventSource=slot 42) !\n"); - } - logNvramStage("workQueue_ok"); IOLog("QualcommWifi: IO80211WorkQueue allouee avec succes (0x%p) !\n", fWorkQueue); return true;