void KernelPatcher::setupKextListening() { // We have already done this if (that) return; loadedKextSummaries = reinterpret_cast<OSKextLoadedKextSummaryHeader **>(solveSymbol(KernelID, "_gLoadedKextSummaries")); if (loadedKextSummaries) { DBGLOG("patcher @ _gLoadedKextSummaries address %p", loadedKextSummaries); } else { code = Error::NoSymbolFound; return; } bool hookOuter = getKernelVersion() >= KernelVersion::Sierra; mach_vm_address_t s = solveSymbol(KernelID, hookOuter ? "__ZN6OSKext25updateLoadedKextSummariesEv" : "_OSKextLoadedKextSummariesUpdated"); if (s) { DBGLOG("patcher @ kext summaries (%d) address %llX value %llX", hookOuter, s, *reinterpret_cast<uint64_t *>(s)); } else { code = Error::NoSymbolFound; return; } if (hookOuter) { orgUpdateLoadedKextSummaries = reinterpret_cast<void(*)(void)>( routeFunction(s, reinterpret_cast<mach_vm_address_t>(onKextSummariesUpdated), true, true) ); } else { routeFunction(s, reinterpret_cast<mach_vm_address_t>(onKextSummariesUpdated)); } if (getError() == Error::NoError) { // Allow static functions to access the patcher body that = this; } }
inline T solveSymbol(size_t id, const char *symbol, mach_vm_address_t start, size_t size, bool crash=false) { auto addr = solveSymbol(id, symbol); if (addr) { if (addr >= start && addr < start + size) return (T)addr; code = Error::InvalidSymbolFound; SYSTRACE("patcher", "address " PRIKADDR " is out of range " PRIKADDR " with size %lX", CASTKADDR(addr), CASTKADDR(start), size); PANIC_COND(crash, "patcher", "address " PRIKADDR " is out of range " PRIKADDR " with size %lX", CASTKADDR(addr), CASTKADDR(start), size); } return (T)nullptr; }