Exemple #1
0
void AlcEnabler::processKext(size_t index, mach_vm_address_t address, size_t size) {
	patcher.updateRunningInfo(index, address, size);
	
	if (patcher.getError() == KernelPatcher::Error::NoError) {
		if (!(progressState & ProcessingState::ControllersLoaded)) {
			grabControllers();
			progressState |= ProcessingState::ControllersLoaded;
		} else if (!(progressState & ProcessingState::CodecsLoaded)) {
			for (size_t i = 0; i < kextListSize; i++) {
				if (kextList[i].loadIndex == index) {
					if (kextList[i].detectCodecs && grabCodecs()) {
						progressState |= ProcessingState::CodecsLoaded;
						break;
					}
					DBGLOG("alc @ failed to find a suitable codec, we have nothing to do");
					return;
				}
			}
		}
	
		if (progressState & ProcessingState::ControllersLoaded) {
			for (size_t i = 0, num = controllers.size(); i < num; i++) {
				auto &info = controllers[i]->info;
				if (!info) {
					DBGLOG("alc @ missing ControllerModInfo for %zu controller", i);
					continue;
				}
				
				applyPatches(index, info->patches, info->patchNum);
			}
		}
		
		if (progressState & ProcessingState::CodecsLoaded) {
			for (size_t i = 0, num = codecs.size(); i < num; i++) {
				auto &info = codecs[i]->info;
				if (!info) {
					SYSLOG("alc @ missing CodecModInfo for %zu codec", i);
					continue;
				}
				
				if (info->platforms > 0 && info->layoutNum > 0) {
					DBGLOG("alc @ will route callbacks resource loading callbacks");
					progressState |= ProcessingState::CallbacksWantRouting;
				}
				
				applyPatches(index, info->patches, info->patchNum);
			}
		}
		
		if ((progressState & ProcessingState::CallbacksWantRouting) && !(progressState & ProcessingState::CallbacksRouted)) {
			auto layout = patcher.solveSymbol(index, "__ZN14AppleHDADriver18layoutLoadCallbackEjiPKvjPv");
			auto platform = patcher.solveSymbol(index, "__ZN14AppleHDADriver20platformLoadCallbackEjiPKvjPv");

			if (!layout || !platform) {
				SYSLOG("alc @ failed to find AppleHDA layout or platform callback symbols (%llX, %llX)", layout, platform);
			} else if (orgLayoutLoadCallback = reinterpret_cast<t_callback>(patcher.routeFunction(layout, reinterpret_cast<mach_vm_address_t>(layoutLoadCallback), true)),
					   patcher.getError() != KernelPatcher::Error::NoError) {
				SYSLOG("alc @ failed to hook layout callback");
			} else if (orgPlatformLoadCallback = reinterpret_cast<t_callback>(patcher.routeFunction(platform, reinterpret_cast<mach_vm_address_t>(platformLoadCallback), true)),
					   patcher.getError() != KernelPatcher::Error::NoError) {
				SYSLOG("alc @ failed to hook platform callback");
			} else {
				progressState |= ProcessingState::CallbacksRouted;
			}
		}
	} else {
		SYSLOG("alc @ failed to update kext running info");
	}
	
	// Ignore all the errors for other processors
	patcher.clearError();
}
Exemple #2
0
void AlcEnabler::processKext(size_t index, mach_vm_address_t address, size_t size) {
	// We could have done some of this earlier by requiring com.apple.iokit.IOHDAFamily to load first
	// However, IOHDAFamily has insane version compatibilities over the OS X versions, I am lazy to use
	// TrustedBSD apis, and we might want to patch other kexts one day, so better to be ready asap and
	// keep this in one place...
	if (index == kextAppleHDA->loadIndex && !grabCodecs()) {
		SYSLOG("alc @ failed to find a suitable codec, we have nothing to do");
		return;
	}
	
	patcher.updateRunningInfo(index, address, size);
	
	bool routeCallbacks {false};
	
	for (size_t i = 0, num = codecs.size(); i < num; i++) {
		auto &info = codecs[i]->info;
		if (!info) {
			SYSLOG("alc @ missing CodecModInfo for %zu codec", i);
			continue;
		}
		
		if (index == kextAppleHDA->loadIndex && info->platforms > 0 && info->layoutNum > 0) {
			DBGLOG("alc @ will route callbacks resource loading callbacks");
			routeCallbacks = true;
		}
		
		for (size_t p = 0; p < info->patchNum; p++) {
			auto &patch = info->patches[p];
			if (patch.patch.kext->loadIndex == index) {
				if (patcher.compatibleKernel(patch.minKernel, patch.maxKernel)) {
					patcher.applyLookupPatch(&patch.patch);
					// Do not really care for the errors for now
					patcher.clearError();
				}
			} else if (patch.patch.kext->loadIndex == KernelPatcher::KextInfo::Unloaded) {
				auto loadIndex = patcher.loadKinfo(patch.patch.kext);
				if (patcher.getError() != KernelPatcher::Error::NoError) {
					patch.patch.kext->loadIndex = loadIndex;
					
					// A future recursion here
					auto handler = KernelPatcher::KextHandler::create(patch.patch.kext->id, patch.patch.kext->loadIndex,
						[](KernelPatcher::KextHandler *h) {
						if (h) {
							that->processKext(h->index, h->address, h->size);
						} else {
							SYSLOG("alc @ extra notification callback arrived at nowhere");
						}
					});
					
					if (handler) {
						patcher.waitOnKext(handler);
					} else {
						SYSLOG("alc @ failed to allocate an extra KextHandler");
					}
				}
				// Do not really care for the errors for now
				patcher.clearError();
			}
		}
	}
	
	if (routeCallbacks) {
		auto layout = patcher.solveSymbol(index, "__ZN14AppleHDADriver18layoutLoadCallbackEjiPKvjPv");
		auto platform = patcher.solveSymbol(index, "__ZN14AppleHDADriver20platformLoadCallbackEjiPKvjPv");
		if (!layout || !platform) {
			SYSLOG("alc @ failed to find AppleHDA layout or platform callback symbols (%llX, %llX)", layout, platform);
			return;
		}
		
		orgLayoutLoadCallback = reinterpret_cast<t_callback>(patcher.routeFunction(layout, reinterpret_cast<mach_vm_address_t>(layoutLoadCallback), true));
		if (patcher.getError() != KernelPatcher::Error::NoError) {
			SYSLOG("alc @ failed to hook layout callback");
			return;
		}
		
		orgPlatformLoadCallback = reinterpret_cast<t_callback>(patcher.routeFunction(platform, reinterpret_cast<mach_vm_address_t>(platformLoadCallback), true));
		if (patcher.getError() != KernelPatcher::Error::NoError) {
			SYSLOG("alc @ failed to hook platform callback");
			return;
		}
	}
}