示例#1
0
EXPORT extern "C" kern_return_t ADDPR(kern_start)(kmod_info_t *, void *) {
	LiluAPI::Error error = lilu.requestAccess();
	
	if (error != LiluAPI::Error::NoError) {
		SYSLOG("init @ failed to call parent %d", error);
		return KERN_FAILURE;
	}
	
	error = lilu.shouldLoad(ADDPR(config).product, ADDPR(config).disableArg, ADDPR(config).disableArgNum,
							ADDPR(config).debugArg, ADDPR(config).debugArgNum, ADDPR(config).betaArg, ADDPR(config).betaArgNum,
							ADDPR(config).minKernel, ADDPR(config).maxKernel, ADDPR(debugEnabled));
	
	if (error == LiluAPI::Error::NoError) {
		ADDPR(config).pluginStart();
	} else {
		SYSLOG("init @ parent said we should not continue %d", error);
	}
	
	lilu.releaseAccess();
	
	return KERN_SUCCESS;
}
示例#2
0
IOService *AppleALCAudio::probe(IOService *hdaService, SInt32 *score) {
	if (!ADDPR(startSuccess))
		return nullptr;

	if (!hdaService) {
		DBGLOG("audio", "received null digitial audio device");
		return nullptr;
	}

	uint32_t hdaVen, hdaDev;
	if (!WIOKit::getOSDataValue(hdaService, "vendor-id", hdaVen) ||
		!WIOKit::getOSDataValue(hdaService, "device-id", hdaDev)) {
		SYSLOG("audio", "found an unknown device");
		return nullptr;
	}

	auto hdaPlaneName = hdaService->getName();
	DBGLOG("audio", "corrects analog audio for hdef at %s with %04X:%04X",
		   safeString(hdaPlaneName), hdaVen, hdaDev);

	if (hdaVen != WIOKit::VendorID::Intel) {
		DBGLOG("audio", "unsupported hdef vendor");
		return nullptr;
	}

	// HDEF device is always named and is not named as B0D3 or HDAU.
	bool isAnalog = hdaPlaneName && strcmp(hdaPlaneName, "B0D3") && strcmp(hdaPlaneName, "HDAU");

	if (!isAnalog) {
		DBGLOG("audio", "found digital audio, ignoring.");
		return nullptr;
	}

	// AppleHDAController only recognises HDEF and HDAU.
	if (!hdaPlaneName || strcmp(hdaPlaneName, "HDEF")) {
		DBGLOG("audio", "fixing audio plane name to HDEF");
		WIOKit::renameDevice(hdaService, "HDEF");
	}

	uint32_t layout = 0;
	if (PE_parse_boot_argn("alcid", &layout, sizeof(layout))) {
		DBGLOG("audio", "found layout-id override %d", layout);
		hdaService->setProperty("layout-id", &layout, sizeof(layout));
	}

	if (!hdaService->getProperty("built-in")) {
		DBGLOG("audio", "fixing built-in in hdef");
		uint8_t builtBytes[] { 0x00 };
		hdaService->setProperty("built-in", builtBytes, sizeof(builtBytes));
	} else {
		DBGLOG("audio", "found existing built-in in hdef");
	}

	// These seem to fix AppleHDA warnings, perhaps research them later.
	// They are probably related to the current volume of the boot bell sound.
	if (!hdaService->getProperty("MaximumBootBeepVolume")) {
		DBGLOG("audio", "fixing MaximumBootBeepVolume in hdef");
		uint8_t bootBeepBytes[] { 0xEE };
		hdaService->setProperty("MaximumBootBeepVolume", bootBeepBytes, sizeof(bootBeepBytes));
	}

	if (!hdaService->getProperty("MaximumBootBeepVolumeAlt")) {
		DBGLOG("audio", "fixing MaximumBootBeepVolumeAlt in hdef");
		uint8_t bootBeepBytes[] { 0xEE };
		hdaService->setProperty("MaximumBootBeepVolumeAlt", bootBeepBytes, sizeof(bootBeepBytes));
	}

	if (!hdaService->getProperty("PinConfigurations")) {
		DBGLOG("audio", "fixing PinConfigurations in hdef");
		uint8_t pinBytes[] { 0x00 };
		hdaService->setProperty("PinConfigurations", pinBytes, sizeof(pinBytes));
	}

	return nullptr;
}
bool Configuration::getBootArguments() {
	if (readArguments) return !isDisabled;
	
	isDisabled = false;
	char tmp[16];
	
	isDisabled |= PE_parse_boot_argn(bootargOff, tmp, sizeof(tmp));
	if (!PE_parse_boot_argn(bootargForce, tmp, sizeof(tmp))) {
		isDisabled |= PE_parse_boot_argn("-s", tmp, sizeof(tmp));
		isDisabled |= PE_parse_boot_argn("-x", tmp, sizeof(tmp));
	
		
		if (!KernelPatcher::compatibleKernel(minKernel, maxKernel)) {
			if (!PE_parse_boot_argn(bootargBeta, tmp, sizeof(tmp))) {
				SYSLOG("config @ automatically disabling on an unsupported operating system");
				isDisabled = true;
			} else if (!isDisabled) {
				SYSLOG("config @ force enabling on an unsupported operating system due to beta flag");
			}
		}
	} else if (!isDisabled) {
		SYSLOG("config @ force enabling due to force flag");
	}
	
	ADDPR(debugEnabled) = PE_parse_boot_argn(bootargDebug, tmp, sizeof(tmp));
	
	allowDecompress = !PE_parse_boot_argn(bootargLowMem, tmp, sizeof(tmp));
	
	installOrRecovery |= PE_parse_boot_argn("rp0", tmp, sizeof(tmp));
	installOrRecovery |= PE_parse_boot_argn("rp", tmp, sizeof(tmp));
	installOrRecovery |= PE_parse_boot_argn("container-dmg", tmp, sizeof(tmp));
	installOrRecovery |= PE_parse_boot_argn("root-dmg", tmp, sizeof(tmp));
	installOrRecovery |= PE_parse_boot_argn("auth-root-dmg", tmp, sizeof(tmp));
	
	preferSlowMode = getKernelVersion() <= KernelVersion::Mavericks || installOrRecovery;

	if (PE_parse_boot_argn(bootargSlow, tmp, sizeof(tmp))) {
		preferSlowMode = true;
	} else if (PE_parse_boot_argn(bootargFast, tmp, sizeof(tmp))) {
		preferSlowMode = false;
	}

	if (!preferSlowMode && getKernelVersion() <= KernelVersion::Mavericks) {
		// Since vm_shared_region_map_file interface is a little different
		if (!isDisabled) SYSLOG("config @ enforcing -liluslow on Mavericks and lower");
		preferSlowMode = true;
	}
	
	if (!preferSlowMode && installOrRecovery) {
		// Since vdyld shared cache is not available
		if (!isDisabled) SYSLOG("config @ enforcing -liluslow in installer or recovery");
		preferSlowMode = true;
	}
	
	readArguments = true;
	
	DBGLOG("config @ boot arguments disabled %d, debug %d, slow %d, decompress %d", isDisabled, ADDPR(debugEnabled), preferSlowMode, allowDecompress);
	
	if (isDisabled) {
		SYSLOG("init @ found a disabling argument or no arguments, exiting");
	} else {
		// Decide on booter
		if (!preferSlowMode) {
			policyOps.mpo_cred_check_label_update_execve = reinterpret_cast<mpo_cred_check_label_update_execve_t *>(policyCredCheckLabelUpdateExecve);
		} else {
			policyOps.mpo_mount_check_remount = policyCheckRemount;
		}
	}
	
	return !isDisabled;
}
void UserPatcher::patchSharedCache(vm_map_t taskPort, uint32_t slide, cpu_type_t cpu, bool applyChanges) {
	// Save the slide for restoration
	if (applyChanges && !sharedCacheSlideStored) {
		storedSharedCacheSlide = slide;
		sharedCacheSlideStored = true;
	}
	
	for (size_t i = 0, sz = lookupStorage.size(); i < sz; i++) {
		auto &storageEntry = lookupStorage[i];
		auto &mod = storageEntry->mod;
		for (size_t j = 0, rsz = storageEntry->refs.size(); j < rsz; j++) {
			auto &ref = storageEntry->refs[j];
			auto &patch = storageEntry->mod->patches[ref->i];
			size_t offNum = ref->segOffs.size();
			
			vm_address_t modStart = 0;
			vm_address_t modEnd = 0;
			
			if (patch.segment >= FileSegment::SegmentsTextStart && patch.segment <= FileSegment::SegmentsTextEnd) {
				modStart = mod->startTEXT;
				modEnd = mod->endTEXT;
			} else if (patch.segment >= FileSegment::SegmentsDataStart && patch.segment <= FileSegment::SegmentsDataEnd) {
				modStart = mod->startDATA;
				modEnd = mod->endDATA;
			}
			
			if (modStart && modEnd && offNum && patch.cpu == cpu) {
				DBGLOG("user @ patch for %s in %lX %lX\n", mod->path, modStart, modEnd);
				auto tmp = Buffer::create<uint8_t>(patch.size);
				if (tmp) {
					for (size_t k = 0; k < offNum; k++) {
						auto place = modStart+ref->segOffs[k]+slide;
						auto r = orgVmMapReadUser(taskPort, place, tmp, patch.size);
						if (!r) {
							bool comparison = !memcmp(tmp, applyChanges? patch.find : patch.replace, patch.size);
							DBGLOG("user @ %d/%d found %X %X %X %X", applyChanges, comparison, tmp[0], tmp[1], tmp[2], tmp[3]);
							if (comparison) {
								if (vm_protect(taskPort, (place & -PAGE_SIZE), PAGE_SIZE, FALSE, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) == KERN_SUCCESS) {
									DBGLOG("user @ obtained write permssions\n");
									
									r = orgVmMapWriteUser(taskPort, applyChanges ? patch.replace : patch.find, place, patch.size);
										
									DBGLOG("user @ patching %llX -> res %d", place, r);
										
									if (vm_protect(taskPort, (place & -PAGE_SIZE), PAGE_SIZE, FALSE, VM_PROT_READ|VM_PROT_EXECUTE) == KERN_SUCCESS) {
										DBGLOG("user @ restored write permssions\n");
									}

								} else {
									SYSLOG("user @ failed to obtain write permissions for patching");
								}
							} else if (ADDPR(debugEnabled)) {
								for (size_t i = 0; i < patch.size; i++) {
									auto v = (applyChanges? patch.find : patch.replace)[i];
									if (tmp[i] != v) {
										DBGLOG("user @ miss at %zu: %0.2X vs %0.2X", i, tmp[i], v);
										break;
									}
								}
							}
						}
						
						DBGLOG("user @ done reading patches for %llX", ref->segOffs[k]);
					}
					Buffer::deleter(tmp);
				}
			}
		}
	}
}