Example #1
0
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;
	}