diff --git a/ATH9KFixup.xcodeproj/project.pbxproj b/ATH9KFixup.xcodeproj/project.pbxproj
index 03ecd89..fe62890 100644
--- a/ATH9KFixup.xcodeproj/project.pbxproj
+++ b/ATH9KFixup.xcodeproj/project.pbxproj
@@ -287,6 +287,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
@@ -328,6 +329,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
};
name = Release;
@@ -356,7 +358,7 @@
MODULE_NAME = com.chunnann.ATH9KFixup;
MODULE_START = "$(PRODUCT_NAME)_kern_start";
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
- MODULE_VERSION = 1.1.0;
+ MODULE_VERSION = 1.2.6;
OTHER_CFLAGS = (
"-mmmx",
"-msse",
@@ -400,7 +402,7 @@
MODULE_NAME = com.chunnann.ATH9KFixup;
MODULE_START = "$(PRODUCT_NAME)_kern_start";
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
- MODULE_VERSION = 1.1.0;
+ MODULE_VERSION = 1.2.6;
OTHER_CFLAGS = (
"-mmmx",
"-msse",
diff --git a/ATH9KFixup.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ATH9KFixup.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/ATH9KFixup.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/ATH9KFixup.xcodeproj/project.xcworkspace/xcuserdata/nick.xcuserdatad/UserInterfaceState.xcuserstate b/ATH9KFixup.xcodeproj/project.xcworkspace/xcuserdata/nick.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..dc238da
Binary files /dev/null and b/ATH9KFixup.xcodeproj/project.xcworkspace/xcuserdata/nick.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/ATH9KFixup.xcodeproj/xcuserdata/nick.xcuserdatad/xcschemes/ATH9KFixup.xcscheme b/ATH9KFixup.xcodeproj/xcuserdata/nick.xcuserdatad/xcschemes/ATH9KFixup.xcscheme
new file mode 100644
index 0000000..75f0850
--- /dev/null
+++ b/ATH9KFixup.xcodeproj/xcuserdata/nick.xcuserdatad/xcschemes/ATH9KFixup.xcscheme
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ATH9KFixup.xcodeproj/xcuserdata/nick.xcuserdatad/xcschemes/xcschememanagement.plist b/ATH9KFixup.xcodeproj/xcuserdata/nick.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..7424cef
--- /dev/null
+++ b/ATH9KFixup.xcodeproj/xcuserdata/nick.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ SchemeUserState
+
+ ATH9KFixup.xcscheme
+
+ orderHint
+ 0
+
+
+ SuppressBuildableAutocreation
+
+ 1C748C261C21952C0024EED2
+
+ primary
+
+
+
+
+
diff --git a/ATH9KFixup/Info.plist b/ATH9KFixup/Info.plist
index 3a94af2..f2cad96 100644
--- a/ATH9KFixup/Info.plist
+++ b/ATH9KFixup/Info.plist
@@ -37,13 +37,13 @@
NSHumanReadableCopyright
- Copyright © 2017 chunnann. All rights reserved.
+ Copyright © 2017 chunnann, black.dragon74. All rights reserved.
OSBundleCompatibleVersion
1.0
OSBundleLibraries
as.vit9696.Lilu
- 1.1.6
+ 1.2.6
com.apple.kpi.bsd
12.0.0
com.apple.kpi.dsep
diff --git a/ATH9KFixup/kern_ath9k.cpp b/ATH9KFixup/kern_ath9k.cpp
index 9d75912..d8bf312 100644
--- a/ATH9KFixup/kern_ath9k.cpp
+++ b/ATH9KFixup/kern_ath9k.cpp
@@ -21,12 +21,15 @@ static const char *kextAirPortAtheros40[] {
};
static KernelPatcher::KextInfo kextList[] {
- { "com.apple.driver.AirPort.Atheros40", kextAirPortAtheros40, 1, true, {}, KernelPatcher::KextInfo::Unloaded }
+ { "com.apple.driver.AirPort.Atheros40", kextAirPortAtheros40, 1, {true,true}, {}, KernelPatcher::KextInfo::Unloaded }
};
static size_t kextListSize {1};
bool ATH9K::init() {
+ // So that user can identify successful kext injection.
+ SYSLOG("ATH9KFixup", "Kext loaded. Patching will start now.\n");
+
LiluAPI::Error error = lilu.onKextLoad(kextList, kextListSize,
[](void *user, KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
ATH9K *ath9k = static_cast(user);
@@ -34,7 +37,7 @@ bool ATH9K::init() {
}, this);
if (error != LiluAPI::Error::NoError) {
- SYSLOG("ath9k @ failed to register onPatcherLoad method %d", error);
+ SYSLOG("ath9k", "failed to register onPatcherLoad method %d", error);
return false;
}
@@ -49,7 +52,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
for (size_t i = 0; i < kextListSize; i++) {
if (kextList[i].loadIndex == index) {
if (!(progressState & ProcessingState::AirPortAtheros40Patched) && !strcmp(kextList[i].id, "com.apple.driver.AirPort.Atheros40")) {
- DBGLOG("ath9k @ found com.apple.driver.AirPort.Atheros40");
+ DBGLOG("ath9k", "found com.apple.driver.AirPort.Atheros40");
if (getKernelVersion() == KernelVersion::Mavericks){
const uint8_t find1[] = {0x66, 0x89, 0x83, 0x20, 0x02, 0x00, 0x00};
@@ -60,7 +63,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch1, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched 10.9.x start");
+ DBGLOG("ath9k", "patched 10.9.x start");
const uint8_t find2[] = {0x66, 0x83, 0xFA, 0x30};
const uint8_t replace2[] = {0x66, 0x83, 0xFA, 0x00};
@@ -70,7 +73,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch2, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched ___ath_attach");
+ DBGLOG("ath9k", "patched ___ath_attach");
}
else if (getKernelVersion() == KernelVersion::Yosemite){
const uint8_t find1[] = {0x66, 0x89, 0x83, 0x48, 0x02, 0x00, 0x00};
@@ -81,7 +84,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch1, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched 10.10.x start");
+ DBGLOG("ath9k", "patched 10.10.x start");
const uint8_t find2[] = {0x41, 0x0F, 0xB7, 0xFE, 0x83, 0xFF, 0x30};
const uint8_t replace2[] = {0x41, 0x0F, 0xB7, 0xFE, 0x83, 0xFF, 0x00};
@@ -91,7 +94,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch2, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched ___ath_attach");
+ DBGLOG("ath9k" ,"patched ___ath_attach");
}
else if (getKernelVersion() == KernelVersion::ElCapitan){
const uint8_t find1[] = {0x66, 0x89, 0x83, 0x10, 0x04, 0x00, 0x00};
@@ -102,7 +105,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch1, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched 10.11.x start");
+ DBGLOG("ath9k" ,"patched 10.11.x start");
const uint8_t find2[] = {0x0F, 0xB7, 0xF8, 0x83, 0xFF, 0x30};
const uint8_t replace2[] = {0x0F, 0xB7, 0xF8, 0x83, 0xFF, 0x00};
@@ -112,7 +115,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch2, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched ___ath_attach");
+ DBGLOG("ath9k", "patched ___ath_attach");
}
else if (getKernelVersion() == KernelVersion::Sierra){
const uint8_t find1[] = {0x66, 0x89, 0x83, 0x38, 0x04, 0x00, 0x00};
@@ -123,7 +126,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch1, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched 10.12.x start");
+ DBGLOG("ath9k", "patched 10.12.x start");
const uint8_t find2[] = {0x0F, 0xB7, 0xF8, 0x83, 0xFF, 0x30};
const uint8_t replace2[] = {0x0F, 0xB7, 0xF8, 0x83, 0xFF, 0x00};
@@ -133,7 +136,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch2, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched ___ath_attach");
+ DBGLOG("ath9k", "patched ___ath_attach");
}
else if (getKernelVersion() == KernelVersion::HighSierra){
const uint8_t find1[] = {0x66, 0x89, 0x83, 0x38, 0x04, 0x00, 0x00};
@@ -144,7 +147,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch1, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched 10.13.x start");
+ DBGLOG("ath9k", " patched 10.13.x start");
const uint8_t find2[] = {0x41, 0x0F, 0xB7, 0xFD, 0x83, 0xFF, 0x30};
const uint8_t replace2[] = {0x41, 0x0F, 0xB7, 0xFD, 0x83, 0xFF, 0x00};
@@ -154,18 +157,41 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch2, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched ___ath_attach");
+ DBGLOG("ath9k", " patched ___ath_attach");
+ }
+
+ // Patch is same as macOS High Sierra (as of now), Just adding patcher support for Mojave
+ else if (getKernelVersion() == KernelVersion::Mojave){
+ const uint8_t find1[] = {0x66, 0x89, 0x83, 0x38, 0x04, 0x00, 0x00};
+ const uint8_t replace1[] = {0xC6, 0x83, 0x38, 0x04, 0x00, 0x00, 0x30};
+ KextPatch kext_patch1 {
+ {&kextList[i], find1, replace1, sizeof(find1), 1},
+ KernelVersion::Mojave, KernelVersion::Mojave
+ };
+ applyPatches(patcher, index, &kext_patch1, 1);
+ progressState |= ProcessingState::AirPortAtheros40Patched;
+ DBGLOG("ath9k", "patched 10.14.x start");
+
+ const uint8_t find2[] = {0x41, 0x0F, 0xB7, 0xFD, 0x83, 0xFF, 0x30};
+ const uint8_t replace2[] = {0x41, 0x0F, 0xB7, 0xFD, 0x83, 0xFF, 0x00};
+ KextPatch kext_patch2 {
+ {&kextList[i], find2, replace2, sizeof(find2), 1},
+ KernelVersion::Mojave, KernelVersion::Mojave
+ };
+ applyPatches(patcher, index, &kext_patch2, 1);
+ progressState |= ProcessingState::AirPortAtheros40Patched;
+ DBGLOG("ath9k", "patched ___ath_attach");
}
const uint8_t find3[] = {0xC1, 0xE9, 0x0C, 0x81, 0xE1, 0xC0, 0xFF, 0x0F, 0x00};
const uint8_t replace3[] = {0xC1, 0xE9, 0x0C, 0x90, 0xB9, 0xC0, 0x01, 0x00, 0x00};
KextPatch kext_patch3 {
{&kextList[i], find3, replace3, sizeof(find3), 4},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch3, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300ReadRevisions");
+ DBGLOG("ath9k", " patched _ar9300ReadRevisions");
const uint8_t find4[] = {0xC1, 0xE8, 0x0C, 0x25, 0xC0, 0xFF, 0x0F, 0x00};
const uint8_t replace4[] = {0xC1, 0xE8, 0x0C, 0xB8, 0xC0, 0x01, 0x00, 0x00};
@@ -175,67 +201,67 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch4, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300ReadRevisions #1");
+ DBGLOG("ath9k", " patched _ar9300ReadRevisions #1");
const uint8_t find5[] = {0xC1, 0xE9, 0x08, 0x83, 0xE1, 0x0F};
const uint8_t replace5[] = {0x90, 0xB9, 0x02, 0x00, 0x00, 0x00};
KextPatch kext_patch5 {
{&kextList[i], find5, replace5, sizeof(find5), 5},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch5, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300ReadRevisions #2");
+ DBGLOG("ath9k", " patched _ar9300ReadRevisions #2");
const uint8_t find6[] = {0xC1, 0xE8, 0x08, 0x83, 0xE0, 0x0F};
const uint8_t replace6[] = {0x90, 0xB8, 0x02, 0x00, 0x00, 0x00};
KextPatch kext_patch6 {
{&kextList[i], find6, replace6, sizeof(find6), 3},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch6, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300ReadRevisions #3");
+ DBGLOG("ath9k", " patched _ar9300ReadRevisions #3");
const uint8_t find7[] = {0x0F, 0xB6, 0x87, 0x00, 0xB2, 0x00, 0x00, 0x83, 0xE0, 0x0F};
const uint8_t replace7[] = {0x0F, 0xB6, 0x87, 0x00, 0xB2, 0x00, 0x00, 0x90, 0x31, 0xC0};
KextPatch kext_patch7 {
{&kextList[i], find7, replace7, sizeof(find7), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch7, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300RxGainIndexGet");
+ DBGLOG("ath9k", " patched _ar9300RxGainIndexGet");
const uint8_t find8[] = {0x0F, 0xB6, 0x87, 0x00, 0xB2, 0x00, 0x00, 0xC1, 0xE8, 0x04};
const uint8_t replace8[] = {0x0F, 0xB6, 0x87, 0x00, 0xB2, 0x00, 0x00, 0x90, 0x31, 0xC0};
KextPatch kext_patch8 {
{&kextList[i], find8, replace8, sizeof(find8), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch8, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300TxGainIndexGet");
+ DBGLOG("ath9k", " patched _ar9300TxGainIndexGet");
const uint8_t find9[] = {0x66, 0x89, 0x83, 0x16, 0x09, 0x00, 0x00};
const uint8_t replace9[] = {0xC6, 0x83, 0x16, 0x09, 0x00, 0x00, 0x00};
KextPatch kext_patch9 {
{&kextList[i], find9, replace9, sizeof(find9), 4},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch9, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300FillCapabilityInfo");
+ DBGLOG("ath9k", " patched _ar9300FillCapabilityInfo");
const uint8_t find10[] = {0x48, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00};
const uint8_t replace10[] = {0x48, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00};
KextPatch kext_patch10 {
{&kextList[i], find10, replace10, sizeof(find10), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch10, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300FillCapabilityInfo #2");
+ DBGLOG("ath9k", " patched _ar9300FillCapabilityInfo #2");
char tmp[16];
if (PE_parse_boot_argn("-ath9485", tmp, sizeof(tmp))) {
@@ -243,11 +269,11 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
const uint8_t replace[] = {0x39, 0x34, 0x38, 0x35};
KextPatch kext_patch {
{&kextList[i], find, replace, sizeof(find), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched AR9485");
+ DBGLOG("ath9k", " patched AR9485");
if (getKernelVersion() == KernelVersion::Mavericks){
const uint8_t find11[] = {0xFF, 0x03, 0x00, 0x00, 0x4C, 0x89, 0xFF, 0x4C, 0x89, 0xF6, 0x89, 0xDA, 0xB9, 0xFF, 0x03, 0x00, 0x00};
@@ -258,7 +284,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch11, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300EepromRestoreInternal");
+ DBGLOG("ath9k", " patched _ar9300EepromRestoreInternal");
const uint8_t find12[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xD0};
const uint8_t replace12[] = {0xBA, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xD0};
@@ -268,7 +294,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0xFF, 0x13};
const uint8_t replace13[] = {0xBA, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x13};
@@ -278,7 +304,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
}
else {
const uint8_t find11[] = {0xFF, 0x03, 0x00, 0x00, 0xB9, 0xFF, 0x03, 0x00, 0x00};
@@ -289,7 +315,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch11, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300EepromRestoreInternal");
+ DBGLOG("ath9k", " patched _ar9300EepromRestoreInternal");
const uint8_t find12[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0xFF, 0xD0};
const uint8_t replace12[] = {0xBA, 0x01, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0xFF, 0xD0};
@@ -299,7 +325,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0x41, 0xFF, 0x55, 0x00};
const uint8_t replace13[] = {0xBA, 0x01, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0x41, 0xFF, 0x55, 0x00};
@@ -309,173 +335,173 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
}
/*
const uint8_t find12[] = {0xA2, 0x00, 0x00, 0xBA, 0x07, 0x00, 0x00, 0x00};
const uint8_t replace12[] = {0xA2, 0x00, 0x00, 0xBA, 0x01, 0x00, 0x00, 0x00};
KextPatch kext_patch12 {
{&kextList[i], find12, replace12, sizeof(find12), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0x83, 0x00, 0x00, 0xBA, 0x07, 0x00, 0x00, 0x00};
const uint8_t replace13[] = {0x83, 0x00, 0x00, 0xBA, 0x01, 0x00, 0x00, 0x00};
KextPatch kext_patch13 {
{&kextList[i], find13, replace13, sizeof(find13), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
*/
const uint8_t find14[] = {0xBE, 0x88, 0x62, 0x01, 0x00};
const uint8_t replace14[] = {0xBE, 0x84, 0x62, 0x01, 0x00};
KextPatch kext_patch14 {
{&kextList[i], find14, replace14, sizeof(find14), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch14, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300 #1");
+ DBGLOG("ath9k", " patched _ar9300 #1");
const uint8_t find15[] = {0xBE, 0x90, 0x62, 0x01, 0x00};
const uint8_t replace15[] = {0xBE, 0x8C, 0x62, 0x01, 0x00};
KextPatch kext_patch15 {
{&kextList[i], find15, replace15, sizeof(find15), 4},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch15, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300 #2");
+ DBGLOG("ath9k", " patched _ar9300 #2");
KextPatch kext_patch51 {
{&kextList[i], _ar9300_osprey_2p0_mac_core, _ar9485_osprey_2p0_mac_core, sizeof(_ar9300_osprey_2p0_mac_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch51, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_mac_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_mac_core");
KextPatch kext_patch52 {
{&kextList[i], _ar9300_osprey_2p0_mac_postamble, _ar9485_osprey_2p0_mac_postamble, sizeof(_ar9300_osprey_2p0_mac_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch52, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_mac_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_mac_postamble");
KextPatch kext_patch53 {
{&kextList[i], _ar9300_osprey_2p0_baseband_core, _ar9485_osprey_2p0_baseband_core, sizeof(_ar9300_osprey_2p0_baseband_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch53, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_baseband_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_baseband_core");
KextPatch kext_patch54 {
{&kextList[i], _ar9300_osprey_2p0_baseband_postamble, _ar9485_osprey_2p0_baseband_postamble, sizeof(_ar9300_osprey_2p0_baseband_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch54, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_baseband_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_baseband_postamble");
KextPatch kext_patch55 {
{&kextList[i], _ar9300_osprey_2p0_radio_core, _ar9485_osprey_2p0_radio_core, sizeof(_ar9300_osprey_2p0_radio_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch55, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_radio_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_radio_core");
KextPatch kext_patch56 {
{&kextList[i], _ar9300_osprey_2p0_radio_postamble, _ar9485_osprey_2p0_radio_postamble, sizeof(_ar9300_osprey_2p0_radio_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch56, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_radio_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_radio_postamble");
KextPatch kext_patch57 {
{&kextList[i], _ar9300_osprey_2p0_soc_preamble, _ar9485_osprey_2p0_soc_preamble, sizeof(_ar9300_osprey_2p0_soc_preamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch57, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_soc_preamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_soc_preamble");
KextPatch kext_patch58 {
{&kextList[i], _ar9300_osprey_2p0_soc_postamble, _ar9485_osprey_2p0_soc_postamble, sizeof(_ar9300_osprey_2p0_soc_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch58, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_soc_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_soc_postamble");
KextPatch kext_patch59 {
{&kextList[i], _ar9300Common_rx_gain_table_osprey_2p0, _ar9485Common_rx_gain_table_osprey_2p0, sizeof(_ar9300Common_rx_gain_table_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch59, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Common_rx_gain_table_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Common_rx_gain_table_osprey_2p0");
KextPatch kext_patch60 {
{&kextList[i], _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0, _ar9485Modes_lowest_ob_db_tx_gain_table_osprey_2p0, sizeof(_ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch60, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0");
KextPatch kext_patch61 {
{&kextList[i], _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0, _ar9485PciePhy_pll_on_clkreq_disable_L1_osprey_2p0, sizeof(_ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch61, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0");
KextPatch kext_patch62 {
{&kextList[i], _ar9300PciePhy_clkreq_enable_L1_osprey_2p0, _ar9485PciePhy_clkreq_enable_L1_osprey_2p0, sizeof(_ar9300PciePhy_clkreq_enable_L1_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch62, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300PciePhy_clkreq_enable_L1_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300PciePhy_clkreq_enable_L1_osprey_2p0");
KextPatch kext_patch63 {
{&kextList[i], _ar9300Modes_fast_clock_osprey_2p0, _ar9485Modes_fast_clock_osprey_2p0, sizeof(_ar9300Modes_fast_clock_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch63, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Modes_fast_clock_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Modes_fast_clock_osprey_2p0");
}
else if (PE_parse_boot_argn("-ath9565", tmp, sizeof(tmp))) {
const uint8_t find[] = {0x39, 0x33, 0x38, 0x30};
const uint8_t replace[] = {0x39, 0x35, 0x36, 0x35};
KextPatch kext_patch {
{&kextList[i], find, replace, sizeof(find), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched AR9565");
+ DBGLOG("ath9k", " patched AR9565");
const uint8_t find11[] = {0x8D, 0x90, 0x00, 0x04, 0x00, 0x00};
const uint8_t replace11[] = {0x8D, 0x90, 0x00, 0x04, 0x08, 0x00};
KextPatch kext_patch11 {
{&kextList[i], find11, replace11, sizeof(find11), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch11, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300SetRxFilter");
+ DBGLOG("ath9k", " patched _ar9300SetRxFilter");
if (getKernelVersion() == KernelVersion::Mavericks){
const uint8_t find12[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xD0};
@@ -486,7 +512,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0xFF, 0x13};
const uint8_t replace13[] = {0xBA, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x13};
@@ -496,7 +522,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
}
else {
const uint8_t find12[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0xFF, 0xD0};
@@ -507,7 +533,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0x41, 0xFF, 0x55, 0x00};
const uint8_t replace13[] = {0xBA, 0x01, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0x41, 0xFF, 0x55, 0x00};
@@ -517,173 +543,173 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
}
/*
const uint8_t find12[] = {0xA2, 0x00, 0x00, 0xBA, 0x07, 0x00, 0x00, 0x00};
const uint8_t replace12[] = {0xA2, 0x00, 0x00, 0xBA, 0x01, 0x00, 0x00, 0x00};
KextPatch kext_patch12 {
{&kextList[i], find12, replace12, sizeof(find12), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0x83, 0x00, 0x00, 0xBA, 0x07, 0x00, 0x00, 0x00};
const uint8_t replace13[] = {0x83, 0x00, 0x00, 0xBA, 0x01, 0x00, 0x00, 0x00};
KextPatch kext_patch13 {
{&kextList[i], find13, replace13, sizeof(find13), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
*/
const uint8_t find14[] = {0xBE, 0x88, 0x62, 0x01, 0x00};
const uint8_t replace14[] = {0xBE, 0x8C, 0x62, 0x01, 0x00};
KextPatch kext_patch14 {
{&kextList[i], find14, replace14, sizeof(find14), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch14, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300 #1");
+ DBGLOG("ath9k", " patched _ar9300 #1");
const uint8_t find15[] = {0xBE, 0x90, 0x62, 0x01, 0x00};
const uint8_t replace15[] = {0xBE, 0x94, 0x62, 0x01, 0x00};
KextPatch kext_patch15 {
{&kextList[i], find15, replace15, sizeof(find15), 4},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch15, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300 #2");
+ DBGLOG("ath9k", " patched _ar9300 #2");
KextPatch kext_patch51 {
{&kextList[i], _ar9300_osprey_2p0_mac_core, _ar9565_osprey_2p0_mac_core, sizeof(_ar9300_osprey_2p0_mac_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch51, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_mac_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_mac_core");
KextPatch kext_patch52 {
{&kextList[i], _ar9300_osprey_2p0_mac_postamble, _ar9565_osprey_2p0_mac_postamble, sizeof(_ar9300_osprey_2p0_mac_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch52, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_mac_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_mac_postamble");
KextPatch kext_patch53 {
{&kextList[i], _ar9300_osprey_2p0_baseband_core, _ar9565_osprey_2p0_baseband_core, sizeof(_ar9300_osprey_2p0_baseband_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch53, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_baseband_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_baseband_core");
KextPatch kext_patch54 {
{&kextList[i], _ar9300_osprey_2p0_baseband_postamble, _ar9565_osprey_2p0_baseband_postamble, sizeof(_ar9300_osprey_2p0_baseband_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch54, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_baseband_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_baseband_postamble");
KextPatch kext_patch55 {
{&kextList[i], _ar9300_osprey_2p0_radio_core, _ar9565_osprey_2p0_radio_core, sizeof(_ar9300_osprey_2p0_radio_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch55, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_radio_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_radio_core");
KextPatch kext_patch56 {
{&kextList[i], _ar9300_osprey_2p0_radio_postamble, _ar9565_osprey_2p0_radio_postamble, sizeof(_ar9300_osprey_2p0_radio_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch56, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_radio_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_radio_postamble");
KextPatch kext_patch57 {
{&kextList[i], _ar9300_osprey_2p0_soc_preamble, _ar9565_osprey_2p0_soc_preamble, sizeof(_ar9300_osprey_2p0_soc_preamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch57, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_soc_preamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_soc_preamble");
KextPatch kext_patch58 {
{&kextList[i], _ar9300_osprey_2p0_soc_postamble, _ar9565_osprey_2p0_soc_postamble, sizeof(_ar9300_osprey_2p0_soc_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch58, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_soc_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_soc_postamble");
KextPatch kext_patch59 {
{&kextList[i], _ar9300Common_rx_gain_table_osprey_2p0, _ar9565Common_rx_gain_table_osprey_2p0, sizeof(_ar9300Common_rx_gain_table_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch59, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Common_rx_gain_table_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Common_rx_gain_table_osprey_2p0");
KextPatch kext_patch60 {
{&kextList[i], _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0, _ar9565Modes_lowest_ob_db_tx_gain_table_osprey_2p0, sizeof(_ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch60, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0");
KextPatch kext_patch61 {
{&kextList[i], _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0, _ar9565PciePhy_pll_on_clkreq_disable_L1_osprey_2p0, sizeof(_ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch61, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0");
KextPatch kext_patch62 {
{&kextList[i], _ar9300PciePhy_clkreq_enable_L1_osprey_2p0, _ar9565PciePhy_clkreq_enable_L1_osprey_2p0, sizeof(_ar9300PciePhy_clkreq_enable_L1_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch62, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300PciePhy_clkreq_enable_L1_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300PciePhy_clkreq_enable_L1_osprey_2p0");
KextPatch kext_patch63 {
{&kextList[i], _ar9300Modes_fast_clock_osprey_2p0, _ar9565Modes_fast_clock_osprey_2p0, sizeof(_ar9300Modes_fast_clock_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch63, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Modes_fast_clock_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Modes_fast_clock_osprey_2p0");
}
else {
const uint8_t find[] = {0x39, 0x33, 0x38, 0x30};
const uint8_t replace[] = {0x39, 0x34, 0x36, 0x58};
KextPatch kext_patch {
{&kextList[i], find, replace, sizeof(find), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched AR946X");
+ DBGLOG("ath9k", " patched AR946X");
const uint8_t find11[] = {0x8D, 0x90, 0x00, 0x04, 0x00, 0x00};
const uint8_t replace11[] = {0x8D, 0x90, 0x00, 0x04, 0x08, 0x00};
KextPatch kext_patch11 {
{&kextList[i], find11, replace11, sizeof(find11), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch11, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300SetRxFilter");
+ DBGLOG("ath9k", " patched _ar9300SetRxFilter");
if (getKernelVersion() == KernelVersion::Mavericks){
const uint8_t find12[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xD0};
@@ -694,7 +720,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0xFF, 0x13};
const uint8_t replace13[] = {0xBA, 0x03, 0x00, 0x00, 0x00, 0xFF, 0x13};
@@ -704,7 +730,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
}
else {
const uint8_t find12[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0xFF, 0xD0};
@@ -715,7 +741,7 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0xBA, 0x07, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0x41, 0xFF, 0x55, 0x00};
const uint8_t replace13[] = {0xBA, 0x03, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xE7, 0x41, 0xFF, 0x55, 0x00};
@@ -725,152 +751,152 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
}
/*
const uint8_t find12[] = {0xA2, 0x00, 0x00, 0xBA, 0x07, 0x00, 0x00, 0x00};
const uint8_t replace12[] = {0xA2, 0x00, 0x00, 0xBA, 0x03, 0x00, 0x00, 0x00};
KextPatch kext_patch12 {
{&kextList[i], find12, replace12, sizeof(find12), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch12, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset");
+ DBGLOG("ath9k", " patched _ar9300Reset");
const uint8_t find13[] = {0x83, 0x00, 0x00, 0xBA, 0x07, 0x00, 0x00, 0x00};
const uint8_t replace13[] = {0x83, 0x00, 0x00, 0xBA, 0x03, 0x00, 0x00, 0x00};
KextPatch kext_patch13 {
{&kextList[i], find13, replace13, sizeof(find13), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch13, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Reset #2");
+ DBGLOG("ath9k", " patched _ar9300Reset #2");
*/
const uint8_t find14[] = {0xBE, 0x88, 0x62, 0x01, 0x00};
const uint8_t replace14[] = {0xBE, 0x8C, 0x62, 0x01, 0x00};
KextPatch kext_patch14 {
{&kextList[i], find14, replace14, sizeof(find14), 2},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch14, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300 #1");
+ DBGLOG("ath9k", " patched _ar9300 #1");
const uint8_t find15[] = {0xBE, 0x90, 0x62, 0x01, 0x00};
const uint8_t replace15[] = {0xBE, 0x94, 0x62, 0x01, 0x00};
KextPatch kext_patch15 {
{&kextList[i], find15, replace15, sizeof(find15), 4},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch15, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300 #2");
+ DBGLOG("ath9k", " patched _ar9300 #2");
KextPatch kext_patch51 {
{&kextList[i], _ar9300_osprey_2p0_mac_core, _ar946x_osprey_2p0_mac_core, sizeof(_ar9300_osprey_2p0_mac_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch51, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_mac_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_mac_core");
KextPatch kext_patch52 {
{&kextList[i], _ar9300_osprey_2p0_mac_postamble, _ar946x_osprey_2p0_mac_postamble, sizeof(_ar9300_osprey_2p0_mac_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch52, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_mac_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_mac_postamble");
KextPatch kext_patch53 {
{&kextList[i], _ar9300_osprey_2p0_baseband_core, _ar946x_osprey_2p0_baseband_core, sizeof(_ar9300_osprey_2p0_baseband_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch53, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_baseband_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_baseband_core");
KextPatch kext_patch54 {
{&kextList[i], _ar9300_osprey_2p0_baseband_postamble, _ar946x_osprey_2p0_baseband_postamble, sizeof(_ar9300_osprey_2p0_baseband_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch54, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_baseband_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_baseband_postamble");
KextPatch kext_patch55 {
{&kextList[i], _ar9300_osprey_2p0_radio_core, _ar946x_osprey_2p0_radio_core, sizeof(_ar9300_osprey_2p0_radio_core), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch55, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_radio_core");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_radio_core");
KextPatch kext_patch56 {
{&kextList[i], _ar9300_osprey_2p0_radio_postamble, _ar946x_osprey_2p0_radio_postamble, sizeof(_ar9300_osprey_2p0_radio_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch56, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_radio_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_radio_postamble");
KextPatch kext_patch57 {
{&kextList[i], _ar9300_osprey_2p0_soc_preamble, _ar946x_osprey_2p0_soc_preamble, sizeof(_ar9300_osprey_2p0_soc_preamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch57, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_soc_preamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_soc_preamble");
KextPatch kext_patch58 {
{&kextList[i], _ar9300_osprey_2p0_soc_postamble, _ar946x_osprey_2p0_soc_postamble, sizeof(_ar9300_osprey_2p0_soc_postamble), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch58, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300_osprey_2p0_soc_postamble");
+ DBGLOG("ath9k", " patched _ar9300_osprey_2p0_soc_postamble");
KextPatch kext_patch59 {
{&kextList[i], _ar9300Common_rx_gain_table_osprey_2p0, _ar946xCommon_rx_gain_table_osprey_2p0, sizeof(_ar9300Common_rx_gain_table_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch59, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Common_rx_gain_table_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Common_rx_gain_table_osprey_2p0");
KextPatch kext_patch60 {
{&kextList[i], _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0, _ar946xModes_lowest_ob_db_tx_gain_table_osprey_2p0, sizeof(_ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch60, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Modes_lowest_ob_db_tx_gain_table_osprey_2p0");
KextPatch kext_patch61 {
{&kextList[i], _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0, _ar946xPciePhy_pll_on_clkreq_disable_L1_osprey_2p0, sizeof(_ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch61, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300PciePhy_pll_on_clkreq_disable_L1_osprey_2p0");
KextPatch kext_patch62 {
{&kextList[i], _ar9300PciePhy_clkreq_enable_L1_osprey_2p0, _ar946xPciePhy_clkreq_enable_L1_osprey_2p0, sizeof(_ar9300PciePhy_clkreq_enable_L1_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch62, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300PciePhy_clkreq_enable_L1_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300PciePhy_clkreq_enable_L1_osprey_2p0");
KextPatch kext_patch63 {
{&kextList[i], _ar9300Modes_fast_clock_osprey_2p0, _ar946xModes_fast_clock_osprey_2p0, sizeof(_ar9300Modes_fast_clock_osprey_2p0), 1},
- KernelVersion::Mavericks, KernelVersion::HighSierra
+ KernelVersion::Mavericks, KernelVersion::Mojave
};
applyPatches(patcher, index, &kext_patch63, 1);
progressState |= ProcessingState::AirPortAtheros40Patched;
- DBGLOG("ath9k @ patched _ar9300Modes_fast_clock_osprey_2p0");
+ DBGLOG("ath9k", " patched _ar9300Modes_fast_clock_osprey_2p0");
}
}
}
@@ -882,12 +908,12 @@ void ATH9K::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t
}
void ATH9K::applyPatches(KernelPatcher &patcher, size_t index, const KextPatch *patches, size_t patchNum) {
- DBGLOG("ath9k @ applying patches for %zu kext", index);
+ DBGLOG("ath9k", " applying patches for %zu kext", index);
for (size_t p = 0; p < patchNum; p++) {
auto &patch = patches[p];
if (patch.patch.kext->loadIndex == index) {
if (patcher.compatibleKernel(patch.minKernel, patch.maxKernel)) {
- DBGLOG("ath9k @ applying %zu patch for %zu kext", p, index);
+ DBGLOG("ath9k", " applying %zu patch for %zu kext", p, index);
patcher.applyLookupPatch(&patch.patch);
// Do not really care for the errors for now
patcher.clearError();
diff --git a/ATH9KFixup/kern_start.cpp b/ATH9KFixup/kern_start.cpp
index 9480791..3027c3b 100644
--- a/ATH9KFixup/kern_start.cpp
+++ b/ATH9KFixup/kern_start.cpp
@@ -29,14 +29,15 @@ static const char *bootargBeta[] {
PluginConfiguration ADDPR(config) {
xStringify(PRODUCT_NAME),
parseModuleVersion(xStringify(MODULE_VERSION)),
+ LiluAPI::AllowNormal | LiluAPI::AllowInstallerRecovery,
bootargOff,
- sizeof(bootargOff)/sizeof(bootargOff[0]),
+ arrsize(bootargOff),
bootargDebug,
- sizeof(bootargDebug)/sizeof(bootargDebug[0]),
+ arrsize(bootargDebug),
bootargBeta,
- sizeof(bootargBeta)/sizeof(bootargBeta[0]),
+ arrsize(bootargBeta),
KernelVersion::Mavericks,
- KernelVersion::HighSierra,
+ KernelVersion::Mojave,
[]() {
ath9k.init();
}
diff --git a/ATH9KInjector.kext/Contents/Info.plist b/ATH9KInjector.kext/Contents/Info.plist
index 1cb83ca..85c0a38 100644
--- a/ATH9KInjector.kext/Contents/Info.plist
+++ b/ATH9KInjector.kext/Contents/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
KEXT
CFBundleShortVersionString
- 1.0.0
+ 1.2.6
CFBundleSignature
????
CFBundleSupportedPlatforms
@@ -23,7 +23,7 @@
MacOSX
CFBundleVersion
- 1.0.0
+ 1.2.6
DTCompiler
com.apple.compilers.llvm.clang.1_0
DTPlatformBuild
@@ -61,6 +61,6 @@
NSHumanReadableCopyright
- Copyright © 2017 chunnann. All rights reserved.
+ Copyright © 2017 chunnann, black.dragon74. All rights reserved.
diff --git a/Changelog.md b/Changelog.md
index 010c868..7520fab 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,12 @@
ATH9KFixup Changelog
====================
+#### v1.2.6
+- Added Lilu 1.2.6 compatibility
+- Added macOS Mojave support (untested)
+- Updated injector kext to be in sync with plugin version.
+
+#### v1.2.0
+- Added Lilu 1.2.0 compatibility
#### v1.1.0
- Added High Sierra compatibility
diff --git a/Lilu.kext/Contents/Info.plist b/Lilu.kext/Contents/Info.plist
index d26b6a3..91296fd 100644
--- a/Lilu.kext/Contents/Info.plist
+++ b/Lilu.kext/Contents/Info.plist
@@ -3,7 +3,7 @@
BuildMachineOSBuild
- 16G29
+ 17D102
CFBundleDevelopmentRegion
en
CFBundleExecutable
@@ -17,7 +17,7 @@
CFBundlePackageType
KEXT
CFBundleShortVersionString
- 1.1.7
+ 1.2.6
CFBundleSignature
????
CFBundleSupportedPlatforms
@@ -25,21 +25,21 @@
MacOSX
CFBundleVersion
- 1.1.7
+ 1.2.6
DTCompiler
com.apple.compilers.llvm.clang.1_0
DTPlatformBuild
- 8E3004b
+ 9F2000
DTPlatformVersion
GM
DTSDKBuild
- 16E185
+ 17E189
DTSDKName
- macosx10.12
+ macosx10.13
DTXcode
- 0833
+ 0941
DTXcodeBuild
- 8E3004b
+ 9F2000
IOKitPersonalities
as.vit9696.Lilu
@@ -59,7 +59,7 @@
NSHumanReadableCopyright
Copyright © 2016-2017 vit9696. All rights reserved.
OSBundleCompatibleVersion
- 1.1.0
+ 1.2.0
OSBundleLibraries
com.apple.kpi.bsd
diff --git a/Lilu.kext/Contents/MacOS/Lilu b/Lilu.kext/Contents/MacOS/Lilu
old mode 100644
new mode 100755
index 0327c4b..5bf4ab2
Binary files a/Lilu.kext/Contents/MacOS/Lilu and b/Lilu.kext/Contents/MacOS/Lilu differ
diff --git a/Lilu.kext/Contents/Resources/Headers/Guid/LiluVariables.h b/Lilu.kext/Contents/Resources/Headers/Guid/LiluVariables.h
new file mode 100644
index 0000000..4d23b4e
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/Guid/LiluVariables.h
@@ -0,0 +1,38 @@
+/** @file
+ Lilu specific GUIDs for UEFI Variable Storage, version 1.0.
+
+Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// 2660DD78-81D2-419D-8138-7B1F363F79A6
+// This GUID is specifically used for normal variable access by Lilu kernel extension and its plugins.
+//
+#define LILU_NORMAL_VARIABLE_GUID \
+ { 0x2660DD78, 0x81D2, 0x419D, { 0x81, 0x38, 0x7B, 0x1F, 0x36, 0x3F, 0x79, 0xA6 } }
+
+//
+// E09B9297-7928-4440-9AAB-D1F8536FBF0A
+// This GUID is specifically used for reading variables by Lilu kernel extension and its plugins.
+// Any writes to this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES.
+// The expected return code on variable write is EFI_SECURITY_VIOLATION.
+//
+#define LILU_READ_ONLY_VARIABLE_GUID \
+ { 0xE09B9297, 0x7928, 0x4440, { 0x9A, 0xAB, 0xD1, 0xF8, 0x53, 0x6F, 0xBF, 0x0A } }
+
+//
+// F0B9AF8F-2222-4840-8A37-ECF7CC8C12E1
+// This GUID is specifically used for reading variables by Lilu and plugins.
+// Any reads from this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES.
+// The expected return code on variable read is EFI_SECURITY_VIOLATION.
+//
+#define LILU_WRITE_ONLY_VARIABLE_GUID \
+ { 0xF0B9AF8F, 0x2222, 0x4840, { 0x8A, 0x37, 0xEC, 0xF7, 0xCC, 0x8C, 0x12, 0xE1 } }
diff --git a/Lilu.kext/Contents/Resources/Headers/capstone/arm64.h b/Lilu.kext/Contents/Resources/Headers/capstone/arm64.h
index 8814709..87504ba 100644
--- a/Lilu.kext/Contents/Resources/Headers/capstone/arm64.h
+++ b/Lilu.kext/Contents/Resources/Headers/capstone/arm64.h
@@ -659,8 +659,8 @@ typedef enum arm64_reg {
//> alias registers
- ARM64_REG_IP1 = ARM64_REG_X16,
- ARM64_REG_IP0 = ARM64_REG_X17,
+ ARM64_REG_IP0 = ARM64_REG_X16,
+ ARM64_REG_IP1 = ARM64_REG_X17,
ARM64_REG_FP = ARM64_REG_X29,
ARM64_REG_LR = ARM64_REG_X30,
} arm64_reg;
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_api.hpp b/Lilu.kext/Contents/Resources/Headers/kern_api.hpp
index a7919cf..15711b1 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_api.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_api.hpp
@@ -23,12 +23,12 @@ class LiluAPI {
* Initialise lilu api
*/
void init();
-
+
/**
* Deinitialise lilu api
*/
void deinit();
-
+
/**
* Errors returned by functions
*/
@@ -39,15 +39,16 @@ class LiluAPI {
UnsupportedFeature,
IncompatibleOS,
Disabled,
- TooLate
+ TooLate,
+ Offline
};
-
+
/**
* Minimal API version that guarantees forward ABI compatibility
* Present due to lack of OSBundleCompatibleVersion at kext injection
*/
- static constexpr size_t CompatibilityVersion {parseModuleVersion("1.1.0")};
-
+ static constexpr size_t CompatibilityVersion {parseModuleVersion("1.2.0")};
+
/**
* Obtains api access by holding a lock, which is required when accessing out of the main context
*
@@ -57,19 +58,43 @@ class LiluAPI {
* @return Error::NoError on success
*/
EXPORT Error requestAccess(size_t version=CompatibilityVersion, bool check=false);
-
+
/**
* Releases api lock
*
* @return Error::NoError on success
*/
EXPORT Error releaseAccess();
-
+
+ /**
+ * You are supposed declare that your plugins work in at least one of these modes
+ * It is assumed that single user mode is equal to normal, because it is generally
+ * used to continue the load of a complete OS, and by default Lilu itself ignores it.
+ */
+ enum RunningMode : uint32_t {
+ RunningNormal = 1,
+ AllowNormal = RunningNormal,
+ RunningInstallerRecovery = 2,
+ AllowInstallerRecovery = RunningInstallerRecovery,
+ RunningSafeMode = 4,
+ AllowSafeMode = RunningSafeMode
+ };
+
+ /**
+ * Obtain current run mode similarly to requirements
+ *
+ * @return run mode mask (RunningMode)
+ */
+ inline uint32_t getRunMode() {
+ return currentRunMode;
+ }
+
/**
* Decides whether you are eligible to continue
*
* @param product product name
* @param version product version
+ * @param runmode bitmask of allowed enviornments
* @param disableArg pointer to disabling boot arguments array
* @param disableArgNum number of disabling boot arguments
* @param debugArg pointer to debug boot arguments array
@@ -82,8 +107,8 @@ class LiluAPI {
*
* @return Error::NoError on success
*/
- EXPORT Error shouldLoad(const char *product, size_t version, const char **disableArg, size_t disableArgNum, const char **debugArg, size_t debugArgNum, const char **betaArg, size_t betaArgNum, KernelVersion min, KernelVersion max, bool &printDebug);
-
+ EXPORT Error shouldLoad(const char *product, size_t version, uint32_t runmode, const char **disableArg, size_t disableArgNum, const char **debugArg, size_t debugArgNum, const char **betaArg, size_t betaArgNum, KernelVersion min, KernelVersion max, bool &printDebug);
+
/**
* Kernel patcher loaded callback
*
@@ -91,7 +116,7 @@ class LiluAPI {
* @param patcher kernel patcher instance
*/
using t_patcherLoaded = void (*)(void *user, KernelPatcher &patcher);
-
+
/**
* Registers custom provided callbacks for later invocation on kernel patcher initialisation
*
@@ -101,7 +126,22 @@ class LiluAPI {
* @return Error::NoError on success
*/
EXPORT Error onPatcherLoad(t_patcherLoaded callback, void *user=nullptr);
-
+
+ /**
+ * Registers custom provided callbacks for later invocation on kernel patcher initialisation
+ * Enforced version, which panics on registration failure (assuming your code cannot continue otherwise)
+ *
+ * @param callback your callback function
+ * @param user your pointer that will be passed to the callback function
+ *
+ * @return Error::NoError on success
+ */
+ inline void onPatcherLoadForce(t_patcherLoaded callback, void *user=nullptr) {
+ auto err = onPatcherLoad(callback, user);
+ if (err != Error::NoError)
+ PANIC("api", "onPatcherLoad failed with code %d", err);
+ }
+
/**
* Kext loaded callback
* Note that you will get notified of all the requested kexts for speed reasons
@@ -113,21 +153,53 @@ class LiluAPI {
* @param size loaded memory size
*/
using t_kextLoaded = void (*)(void *user, KernelPatcher &patcher, size_t id, mach_vm_address_t slide, size_t size);
-
+
/**
* Registers custom provided callbacks for later invocation on kext load
*
* @param infos your kext list (make sure to point to const memory)
* @param num number of provided kext entries
- * @param callback your callback function
+ * @param callback your callback function (optional)
+ * @param user your pointer that will be passed to the callback function (optional)
+ *
+ * @return Error::NoError on success
+ */
+ EXPORT Error onKextLoad(KernelPatcher::KextInfo *infos, size_t num=1, t_kextLoaded callback=nullptr, void *user=nullptr);
+
+ /**
+ * Registers custom provided callbacks for later invocation on kext load
+ * Enforced version, which panics on registration failure (assuming your code cannot continue otherwise)
+ *
+ * @param infos your kext list (make sure to point to const memory)
+ * @param num number of provided kext entries
+ * @param callback your callback function (optional)
+ * @param user your pointer that will be passed to the callback function (optional)
+ *
+ * @return Error::NoError on success
+ */
+ inline void onKextLoadForce(KernelPatcher::KextInfo *infos, size_t num=1, t_kextLoaded callback=nullptr, void *user=nullptr) {
+ auto err = onKextLoad(infos, num, callback, user);
+ if (err != Error::NoError)
+ PANIC("api", "onKextLoad failed with code %d", err);
+ }
+
+ /**
+ * Registers custom provided callbacks for later invocation on binary load
+ *
+ * @param infos your binary list (make sure to point to const memory)
+ * @param num number of provided binary entries
+ * @param callback your callback function (could be null)
* @param user your pointer that will be passed to the callback function
+ * @param mods optional mod list (make sure to point to const memory)
+ * @param modnum number of provided mod entries
*
* @return Error::NoError on success
*/
- EXPORT Error onKextLoad(KernelPatcher::KextInfo *infos, size_t num, t_kextLoaded callback, void *user=nullptr);
-
+ EXPORT Error onProcLoad(UserPatcher::ProcInfo *infos, size_t num=1, UserPatcher::t_BinaryLoaded callback=nullptr, void *user=nullptr, UserPatcher::BinaryModInfo *mods=nullptr, size_t modnum=0);
+
/**
* Registers custom provided callbacks for later invocation on binary load
+ * Enforced version, which panics on registration failure (assuming your code cannot continue otherwise)
*
* @param infos your binary list (make sure to point to const memory)
* @param num number of provided binary entries
@@ -138,7 +210,47 @@ class LiluAPI {
*
* @return Error::NoError on success
*/
- EXPORT Error onProcLoad(UserPatcher::ProcInfo *infos, size_t num, UserPatcher::t_BinaryLoaded callback, void *user=nullptr, UserPatcher::BinaryModInfo *mods=nullptr, size_t modnum=0);
+ inline void onProcLoadForce(UserPatcher::ProcInfo *infos, size_t num=1, UserPatcher::t_BinaryLoaded callback=nullptr, void *user=nullptr, UserPatcher::BinaryModInfo *mods=nullptr, size_t modnum=0) {
+ auto err = onProcLoad(infos, num, callback, user, mods, modnum);
+ if (err != Error::NoError)
+ PANIC("api", "onProcLoad failed with code %d", err);
+ }
+
+ /**
+ * Kext loaded callback
+ * Note that you will get notified of all the requested kexts for speed reasons
+ *
+ * @param user user provided pointer at registering
+ * @param task task
+ * @param entitlement loaded kinfo id
+ * @param original original entitlement value
+ */
+ using t_entitlementRequested = void (*)(void *user, task_t task, const char *entitlement, OSObject *&original);
+
+ /**
+ * Registers custom provided callbacks for later invocation on entitlement registration
+ *
+ * @param callback your callback function
+ * @param user your pointer that will be passed to the callback function
+ *
+ * @return Error::NoError on success
+ */
+ EXPORT Error onEntitlementRequest(t_entitlementRequested callback, void *user=nullptr);
+
+ /**
+ * Registers custom provided callbacks for later invocation on entitlement registration
+ * Enforced version, which panics on registration failure (assuming your code cannot continue otherwise)
+ *
+ * @param callback your callback function
+ * @param user your pointer that will be passed to the callback function
+ *
+ * @return Error::NoError on success
+ */
+ inline void onEntitlementRequestForce(t_entitlementRequested callback, void *user=nullptr) {
+ auto err = onEntitlementRequest(callback, user);
+ if (err != Error::NoError)
+ PANIC("api", "onEntitlementRequest failed with code %d", err);
+ }
/**
* Processes all the registered patcher load callbacks
@@ -157,14 +269,14 @@ class LiluAPI {
* @param reloadable kinfo could be unloaded
*/
void processKextLoadCallbacks(KernelPatcher &patcher, size_t id, mach_vm_address_t slide, size_t size, bool reloadable);
-
+
/**
* Processes all the registered user patcher load callbacks
*
* @param patcher user patcher instance
*/
void processUserLoadCallbacks(UserPatcher &patcher);
-
+
/**
* Processes all the registered binary load callbacks
*
@@ -174,7 +286,7 @@ class LiluAPI {
* @param len path length excluding null terminator
*/
void processBinaryLoadCallbacks(UserPatcher &patcher, vm_map_t map, const char *path, size_t len);
-
+
/**
* Activates patchers
*
@@ -182,60 +294,85 @@ class LiluAPI {
* @param upatcher user patcher instance
*/
void activate(KernelPatcher &kpatcher, UserPatcher &upatcher);
-
+
private:
-
+
/**
* Api lock
*/
IOLock *access {nullptr};
-
+
+ /**
+ * Defines current running modes
+ */
+ uint32_t currentRunMode {};
+
/**
* No longer accept any requests
*/
bool apiRequestsOver {false};
-
+
/**
* Stores call function and user pointer
*/
template
using stored_pair = ppair;
-
+
/**
* Stores multiple callbacks
*/
template
using stored_vector = evector *, stored_pair::deleter>;
-
+
/**
* List of patcher callbacks
*/
stored_vector patcherLoadedCallbacks;
-
+
/**
* List of kext callbacks
*/
stored_vector kextLoadedCallbacks;
-
+
/**
* List of binary callbacks
*/
stored_vector binaryLoadedCallbacks;
-
+
+ /**
+ * List of entitlement callbacks
+ */
+ stored_vector entitlementRequestedCallbacks;
+
/**
* List of processed kexts
*/
stored_vector storedKexts;
-
+
/**
* List of processed procs
*/
evector storedProcs;
-
+
/**
* List of processed binary mods
*/
evector storedBinaryMods;
+
+ /**
+ * Copy client entitlement type (see IOUserClient)
+ */
+ using t_copyClientEntitlement = OSObject *(*)(task_t, const char *);
+
+ /**
+ * Hooked entitlement copying method
+ */
+ static OSObject *copyClientEntitlement(task_t task, const char *entitlement);
+
+ /**
+ * Trampoline for original entitlement copying method
+ */
+ t_copyClientEntitlement orgCopyClientEntitlement {nullptr};
};
EXPORT extern LiluAPI lilu;
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_compat.hpp b/Lilu.kext/Contents/Resources/Headers/kern_compat.hpp
new file mode 100644
index 0000000..7c0d49b
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_compat.hpp
@@ -0,0 +1,78 @@
+//
+// kern_compat.hpp
+// Lilu
+//
+// Copyright © 2016-2017 vit9696. All rights reserved.
+//
+
+#ifndef kern_compat_hpp
+#define kern_compat_hpp
+
+#include
+//Actually do not include to catch real errors
+//#include
+#include
+
+// Please do not use memcpy and similar functions, since they compile
+// to macros unsupported by any other system with 10.13 SDK unless
+// Availability.h header is included.
+#define lilu_os_memcpy(...) (memcpy)(__VA_ARGS__)
+#define lilu_os_memmove(...) (memmove)(__VA_ARGS__)
+#define lilu_os_strncpy(...) (strncpy)(__VA_ARGS__)
+#define lilu_os_strncat(...) (strncat)(__VA_ARGS__)
+#define lilu_os_strlcat(...) (strlcat)(__VA_ARGS__)
+#define lilu_os_strlcpy(...) (strlcpy)(__VA_ARGS__)
+#define lilu_os_strcat(...) (strcat)(__VA_ARGS__)
+#define lilu_os_bcopy(...) (bcopy)(__VA_ARGS__)
+
+// Additionally disallow the use of the original functions
+#ifndef LILU_DISABLE_MEMFUNC_REDEFINE
+
+#ifdef memcpy
+#undef memcpy
+#define memcpy(...) _Pragma("GCC error \"Avoid memcpy due to 10.13 SDK bugs!\"")
+#endif
+
+#ifdef memmove
+#undef memmove
+#define memmove(...) _Pragma("GCC error \"Avoid memmove due to 10.13 SDK bugs!\"")
+#endif
+
+#ifdef strncpy
+#undef strncpy
+#define strncpy(...) _Pragma("GCC error \"Avoid strncpy due to 10.13 SDK bugs!\"")
+#endif
+
+#ifdef strncat
+#undef strncat
+#define strncat(...) _Pragma("GCC error \"Avoid strncat due to 10.13 SDK bugs!\"")
+#endif
+
+#ifdef strlcat
+#undef strlcat
+#define strlcat(...) _Pragma("GCC error \"Avoid strlcat due to 10.13 SDK bugs!\"")
+#endif
+
+#ifdef strlcpy
+#undef strlcpy
+#define strlcpy(...) _Pragma("GCC error \"Avoid strlcpy due to 10.13 SDK bugs!\"")
+#endif
+
+#ifdef strcat
+#undef strcat
+#define strcat(...) _Pragma("GCC error \"Avoid strcat due to 10.13 SDK bugs!\"")
+#endif
+
+#ifdef bcopy
+#undef bcopy
+#define bcopy(...) _Pragma("GCC error \"Avoid bcopy due to 10.13 SDK bugs!\"")
+#endif
+
+#endif /* LILU_DISABLE_MEMFUNC_REDEFINE */
+
+// This may not be nice but will protect users from changes in KernInfo strcture.
+#ifndef LILU_DISABLE_BRACE_WARNINGS
+#pragma clang diagnostic error "-Wmissing-braces"
+#endif
+
+#endif /* kern_compat_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_compression.hpp b/Lilu.kext/Contents/Resources/Headers/kern_compression.hpp
index a656914..4e4fba9 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_compression.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_compression.hpp
@@ -15,38 +15,56 @@
#include
#include
-/**
- * CompressedHeader constants
- */
-static constexpr uint32_t CompressedMagic {0x706D6F63}; //comp
-static constexpr uint32_t CompressionLZVN {0x6E767A6C}; //lzvn
-static constexpr uint32_t CompressionLZSS {0x73737A6C}; //lzss
-
-/**
- * CompressedHeader structure
- */
-struct CompressedHeader {
- uint32_t magic;
- uint32_t compression;
- uint32_t hash; // adler32
- uint32_t decompressed;
- uint32_t compressed;
- uint32_t version;
- uint32_t padding[90];
-};
-
-/**
- * Typed decompressing function
- *
- * @param compression compression type
- * @param dstlen decompression buffer size
- * @param src compressed data
- * @param srclen compressed data size
- *
- * @return decompressed buffer
- */
-EXPORT uint8_t *decompressData(uint32_t compression, uint32_t dstlen, uint8_t *src, uint32_t srclen);
+namespace Compression {
+ /**
+ * Compression constants and modes
+ */
+ static constexpr uint32_t Magic {0x706D6F63}; //comp
+ static constexpr uint32_t ModeLZVN {0x6E767A6C}; //lzvn
+ static constexpr uint32_t ModeLZSS {0x73737A6C}; //lzss
+
+ /**
+ * Compressed header structure
+ */
+ struct Header {
+ uint32_t magic;
+ uint32_t compression;
+ uint32_t hash; // adler32
+ uint32_t decompressed;
+ uint32_t compressed;
+ uint32_t version;
+ uint32_t padding[90];
+ };
+
+ /**
+ * Typed decompressing function (currently for lzvn and lzss)
+ *
+ * @param compression compression type
+ * @param dstlen decompression buffer size
+ * @param src compressed data
+ * @param srclen compressed data size
+ * @param buffer preallocated buffer to use
+ *
+ * @return decompressed buffer (must be freeded by Buffer::deleter if not preallocated)
+ */
+ EXPORT uint8_t *decompress(uint32_t compression, uint32_t dstlen, const uint8_t *src, uint32_t srclen, uint8_t *buffer=nullptr);
+
+ /**
+ * Typed compressing function (currently for lzss)
+ *
+ * @param compression compression type
+ * @param dstlen maximum compression buffer size
+ * @param src uncompressed data
+ * @param srclen uncompressed data size
+ * @param buffer preallocated buffer to use
+ *
+ * @return compressed buffer with its actual size in dstlen (must be freeded by Buffer::deleter if not preallocated)
+ */
+ EXPORT uint8_t *compress(uint32_t compression, uint32_t &dstlen, const uint8_t *src, uint32_t srclen, uint8_t *buffer=nullptr);
+
+}
+
#endif /* LILU_COMPRESSION_SUPPORT */
#endif /* kern_compression_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_config.hpp b/Lilu.kext/Contents/Resources/Headers/kern_config.hpp
index fe4116a..d5cdbf2 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_config.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_config.hpp
@@ -8,11 +8,25 @@
#ifndef kern_config_hpp
#define kern_config_hpp
-// As for now claim to support all the features
+/**
+ * Enable kext patching support
+ */
#define LILU_KEXTPATCH_SUPPORT 1
+
+/**
+ * Enable compression and decompression support
+ */
#define LILU_COMPRESSION_SUPPORT 1
-// Use these in plugins in Xcode Project Preprocessor Macros section
+/**
+ * Enable advanced disassembly API based on capstone
+ */
+// #define LILU_ADVANCED_DISASSEMBLY 1
+
+/**
+ * Specify custom initialisation code
+ * Use these in plugins in Xcode Project Preprocessor Macros section.
+ */
// #define LILU_CUSTOM_IOKIT_INIT 1
// #define LILU_CUSTOM_KMOD_INIT 1
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_cpu.hpp b/Lilu.kext/Contents/Resources/Headers/kern_cpu.hpp
new file mode 100644
index 0000000..31e4d70
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_cpu.hpp
@@ -0,0 +1,409 @@
+//
+// kern_cpu.hpp
+// Lilu
+//
+// Copyright © 2018 vit9696. All rights reserved.
+//
+
+#ifndef kern_cpu_h
+#define kern_cpu_h
+
+#include
+#include
+#include
+
+#include
+
+/**
+ * XNU CPU-related exports missing from headers
+ */
+extern "C" {
+ int cpu_number(void);
+ void mp_rendezvous_no_intrs(void (*action_func)(void *), void *arg);
+};
+
+namespace CPUInfo {
+ /**
+ * Keep this in sync to XNU MAX_CPUS from osfmk/i386/mp.h
+ */
+ static constexpr size_t MaxCpus {64};
+
+ /**
+ * Contents of CPUID(1) eax register contents describing model version
+ */
+ struct CpuVersion {
+ uint32_t stepping : 4;
+ uint32_t model : 4;
+ uint32_t family : 4;
+ uint32_t type : 2;
+ uint32_t reserved1 : 2;
+ uint32_t extendedModel : 4;
+ uint32_t extendedFamily : 8;
+ uint32_t reserved2 : 4;
+ };
+
+ static_assert(sizeof(CpuVersion) == sizeof(uint32_t), "CpuVersion size mismatch!");
+
+ /**
+ * Intel CPU models as returned by CPUID
+ * The list is synchronised and updated with XNU source code (osfmk/i386/cpuid.h).
+ * Names are altered to avoid conflicts just in case.
+ * Last update: xnu-4570.41.2
+ * Some details could be found on http://instlatx64.atw.hu and https://en.wikichip.org/wiki/64-bit_architecture#x86
+ */
+ enum CpuModel {
+ CPU_MODEL_UNKNOWN = 0x00,
+ CPU_MODEL_PENRYN = 0x17,
+ CPU_MODEL_NEHALEM = 0x1A,
+ CPU_MODEL_FIELDS = 0x1E, /* Lynnfield, Clarksfield */
+ CPU_MODEL_DALES = 0x1F, /* Havendale, Auburndale */
+ CPU_MODEL_NEHALEM_EX = 0x2E,
+ CPU_MODEL_DALES_32NM = 0x25, /* Clarkdale, Arrandale */
+ CPU_MODEL_WESTMERE = 0x2C, /* Gulftown, Westmere-EP/-WS */
+ CPU_MODEL_WESTMERE_EX = 0x2F,
+ CPU_MODEL_SANDYBRIDGE = 0x2A,
+ CPU_MODEL_JAKETOWN = 0x2D,
+ CPU_MODEL_IVYBRIDGE = 0x3A,
+ CPU_MODEL_IVYBRIDGE_EP = 0x3E,
+ CPU_MODEL_CRYSTALWELL = 0x46,
+ CPU_MODEL_HASWELL = 0x3C,
+ CPU_MODEL_HASWELL_EP = 0x3F,
+ CPU_MODEL_HASWELL_ULT = 0x45,
+ CPU_MODEL_BROADWELL = 0x3D,
+ CPU_MODEL_BROADWELL_ULX = 0x3D,
+ CPU_MODEL_BROADWELL_ULT = 0x3D,
+ CPU_MODEL_BRYSTALWELL = 0x47,
+ CPU_MODEL_SKYLAKE = 0x4E,
+ CPU_MODEL_SKYLAKE_ULT = 0x4E,
+ CPU_MODEL_SKYLAKE_ULX = 0x4E,
+ CPU_MODEL_SKYLAKE_DT = 0x5E,
+ CPU_MODEL_SKYLAKE_W = 0x55,
+ CPU_MODEL_KABYLAKE = 0x8E,
+ CPU_MODEL_KABYLAKE_ULT = 0x8E,
+ CPU_MODEL_KABYLAKE_ULX = 0x8E,
+ CPU_MODEL_KABYLAKE_DT = 0x9E,
+ CPU_MODEL_COFFEELAKE = 0x9E,
+ CPU_MODEL_COFFEELAKE_ULT = 0x9E,
+ CPU_MODEL_COFFEELAKE_ULX = 0x9E,
+ CPU_MODEL_COFFEELAKE_DT = 0x9E,
+ CPU_MODEL_CANNONLAKE = 0x66,
+ CPU_MODEL_ICELAKE = 0x7E
+ };
+
+ /**
+ * Known CPU vendors
+ */
+ enum class CpuVendor {
+ Unknown,
+ AMD,
+ Intel
+ /* Add more processors here if needed */
+ };
+
+ /**
+ * Intel CPU generations (starting from 0)
+ */
+ enum class CpuGeneration {
+ Unknown,
+ Penryn,
+ Nehalem,
+ Westmere,
+ SandyBridge,
+ IvyBridge,
+ Haswell,
+ Broadwell,
+ Skylake,
+ KabyLake,
+ CoffeeLake,
+ CannonLake,
+ IceLake,
+ MaxGeneration
+ };
+
+ /* Responses identification request with %eax 0 */
+ /* AMD: "AuthenticAMD" */
+ static constexpr uint32_t signature_AMD_ebx = 0x68747541;
+ static constexpr uint32_t signature_AMD_edx = 0x69746e65;
+ static constexpr uint32_t signature_AMD_ecx = 0x444d4163;
+ /* CENTAUR: "CentaurHauls" */
+ static constexpr uint32_t signature_CENTAUR_ebx = 0x746e6543;
+ static constexpr uint32_t signature_CENTAUR_edx = 0x48727561;
+ static constexpr uint32_t signature_CENTAUR_ecx = 0x736c7561;
+ /* CYRIX: "CyrixInstead" */
+ static constexpr uint32_t signature_CYRIX_ebx = 0x69727943;
+ static constexpr uint32_t signature_CYRIX_edx = 0x736e4978;
+ static constexpr uint32_t signature_CYRIX_ecx = 0x64616574;
+ /* INTEL: "GenuineIntel" */
+ static constexpr uint32_t signature_INTEL_ebx = 0x756e6547;
+ static constexpr uint32_t signature_INTEL_edx = 0x49656e69;
+ static constexpr uint32_t signature_INTEL_ecx = 0x6c65746e;
+ /* TM1: "TransmetaCPU" */
+ static constexpr uint32_t signature_TM1_ebx = 0x6e617254;
+ static constexpr uint32_t signature_TM1_edx = 0x74656d73;
+ static constexpr uint32_t signature_TM1_ecx = 0x55504361;
+ /* TM2: "GenuineTMx86" */
+ static constexpr uint32_t signature_TM2_ebx = 0x756e6547;
+ static constexpr uint32_t signature_TM2_edx = 0x54656e69;
+ static constexpr uint32_t signature_TM2_ecx = 0x3638784d;
+ /* NSC: "Geode by NSC" */
+ static constexpr uint32_t signature_NSC_ebx = 0x646f6547;
+ static constexpr uint32_t signature_NSC_edx = 0x43534e20;
+ static constexpr uint32_t signature_NSC_ecx = 0x79622065;
+ /* NEXGEN: "NexGenDriven" */
+ static constexpr uint32_t signature_NEXGEN_ebx = 0x4778654e;
+ static constexpr uint32_t signature_NEXGEN_edx = 0x72446e65;
+ static constexpr uint32_t signature_NEXGEN_ecx = 0x6e657669;
+ /* RISE: "RiseRiseRise" */
+ static constexpr uint32_t signature_RISE_ebx = 0x65736952;
+ static constexpr uint32_t signature_RISE_edx = 0x65736952;
+ static constexpr uint32_t signature_RISE_ecx = 0x65736952;
+ /* SIS: "SiS SiS SiS " */
+ static constexpr uint32_t signature_SIS_ebx = 0x20536953;
+ static constexpr uint32_t signature_SIS_edx = 0x20536953;
+ static constexpr uint32_t signature_SIS_ecx = 0x20536953;
+ /* UMC: "UMC UMC UMC " */
+ static constexpr uint32_t signature_UMC_ebx = 0x20434d55;
+ static constexpr uint32_t signature_UMC_edx = 0x20434d55;
+ static constexpr uint32_t signature_UMC_ecx = 0x20434d55;
+ /* VIA: "VIA VIA VIA " */
+ static constexpr uint32_t signature_VIA_ebx = 0x20414956;
+ static constexpr uint32_t signature_VIA_edx = 0x20414956;
+ static constexpr uint32_t signature_VIA_ecx = 0x20414956;
+ /* VORTEX: "Vortex86 SoC" */
+ static constexpr uint32_t signature_VORTEX_ebx = 0x74726f56;
+ static constexpr uint32_t signature_VORTEX_edx = 0x36387865;
+ static constexpr uint32_t signature_VORTEX_ecx = 0x436f5320;
+
+ /* Features in %ecx for leaf 1 */
+ static constexpr uint32_t bit_SSE3 = 0x00000001;
+ static constexpr uint32_t bit_PCLMULQDQ = 0x00000002;
+ static constexpr uint32_t bit_DTES64 = 0x00000004;
+ static constexpr uint32_t bit_MONITOR = 0x00000008;
+ static constexpr uint32_t bit_DSCPL = 0x00000010;
+ static constexpr uint32_t bit_VMX = 0x00000020;
+ static constexpr uint32_t bit_SMX = 0x00000040;
+ static constexpr uint32_t bit_EIST = 0x00000080;
+ static constexpr uint32_t bit_TM2 = 0x00000100;
+ static constexpr uint32_t bit_SSSE3 = 0x00000200;
+ static constexpr uint32_t bit_CNXTID = 0x00000400;
+ static constexpr uint32_t bit_FMA = 0x00001000;
+ static constexpr uint32_t bit_CMPXCHG16B = 0x00002000;
+ static constexpr uint32_t bit_xTPR = 0x00004000;
+ static constexpr uint32_t bit_PDCM = 0x00008000;
+ static constexpr uint32_t bit_PCID = 0x00020000;
+ static constexpr uint32_t bit_DCA = 0x00040000;
+ static constexpr uint32_t bit_SSE41 = 0x00080000;
+ static constexpr uint32_t bit_SSE42 = 0x00100000;
+ static constexpr uint32_t bit_x2APIC = 0x00200000;
+ static constexpr uint32_t bit_MOVBE = 0x00400000;
+ static constexpr uint32_t bit_POPCNT = 0x00800000;
+ static constexpr uint32_t bit_TSCDeadline = 0x01000000;
+ static constexpr uint32_t bit_AESNI = 0x02000000;
+ static constexpr uint32_t bit_XSAVE = 0x04000000;
+ static constexpr uint32_t bit_OSXSAVE = 0x08000000;
+ static constexpr uint32_t bit_AVX = 0x10000000;
+ static constexpr uint32_t bit_F16C = 0x20000000;
+ static constexpr uint32_t bit_RDRND = 0x40000000;
+
+ /* Features in %edx for leaf 1 */
+ static constexpr uint32_t bit_FPU = 0x00000001;
+ static constexpr uint32_t bit_VME = 0x00000002;
+ static constexpr uint32_t bit_DE = 0x00000004;
+ static constexpr uint32_t bit_PSE = 0x00000008;
+ static constexpr uint32_t bit_TSC = 0x00000010;
+ static constexpr uint32_t bit_MSR = 0x00000020;
+ static constexpr uint32_t bit_PAE = 0x00000040;
+ static constexpr uint32_t bit_MCE = 0x00000080;
+ static constexpr uint32_t bit_CX8 = 0x00000100;
+ static constexpr uint32_t bit_APIC = 0x00000200;
+ static constexpr uint32_t bit_SEP = 0x00000800;
+ static constexpr uint32_t bit_MTRR = 0x00001000;
+ static constexpr uint32_t bit_PGE = 0x00002000;
+ static constexpr uint32_t bit_MCA = 0x00004000;
+ static constexpr uint32_t bit_CMOV = 0x00008000;
+ static constexpr uint32_t bit_PAT = 0x00010000;
+ static constexpr uint32_t bit_PSE36 = 0x00020000;
+ static constexpr uint32_t bit_PSN = 0x00040000;
+ static constexpr uint32_t bit_CLFSH = 0x00080000;
+ static constexpr uint32_t bit_DS = 0x00200000;
+ static constexpr uint32_t bit_ACPI = 0x00400000;
+ static constexpr uint32_t bit_MMX = 0x00800000;
+ static constexpr uint32_t bit_FXSR = 0x01000000;
+ static constexpr uint32_t bit_SSE = 0x02000000;
+ static constexpr uint32_t bit_SSE2 = 0x04000000;
+ static constexpr uint32_t bit_SS = 0x08000000;
+ static constexpr uint32_t bit_HTT = 0x10000000;
+ static constexpr uint32_t bit_TM = 0x20000000;
+ static constexpr uint32_t bit_PBE = 0x80000000;
+
+ /* Features in %ebx for leaf 7 sub-leaf 0 */
+ static constexpr uint32_t bit_FSGSBASE = 0x00000001;
+ static constexpr uint32_t bit_SGX = 0x00000004;
+ static constexpr uint32_t bit_BMI = 0x00000008;
+ static constexpr uint32_t bit_HLE = 0x00000010;
+ static constexpr uint32_t bit_AVX2 = 0x00000020;
+ static constexpr uint32_t bit_SMEP = 0x00000080;
+ static constexpr uint32_t bit_BMI2 = 0x00000100;
+ static constexpr uint32_t bit_ENH_MOVSB = 0x00000200;
+ static constexpr uint32_t bit_RTM = 0x00000800;
+ static constexpr uint32_t bit_MPX = 0x00004000;
+ static constexpr uint32_t bit_AVX512F = 0x00010000;
+ static constexpr uint32_t bit_AVX512DQ = 0x00020000;
+ static constexpr uint32_t bit_RDSEED = 0x00040000;
+ static constexpr uint32_t bit_ADX = 0x00080000;
+ static constexpr uint32_t bit_AVX512IFMA = 0x00200000;
+ static constexpr uint32_t bit_CLFLUSHOPT = 0x00800000;
+ static constexpr uint32_t bit_CLWB = 0x01000000;
+ static constexpr uint32_t bit_AVX512PF = 0x04000000;
+ static constexpr uint32_t bit_AVX51SER = 0x08000000;
+ static constexpr uint32_t bit_AVX512CD = 0x10000000;
+ static constexpr uint32_t bit_SHA = 0x20000000;
+ static constexpr uint32_t bit_AVX512BW = 0x40000000;
+ static constexpr uint32_t bit_AVX512VL = 0x80000000;
+
+ /* Features in %ecx for leaf 7 sub-leaf 0 */
+ static constexpr uint32_t bit_PREFTCHWT1 = 0x00000001;
+ static constexpr uint32_t bit_AVX512VBMI = 0x00000002;
+ static constexpr uint32_t bit_PKU = 0x00000004;
+ static constexpr uint32_t bit_OSPKE = 0x00000010;
+ static constexpr uint32_t bit_AVX512VPOPCNTDQ = 0x00004000;
+ static constexpr uint32_t bit_RDPID = 0x00400000;
+
+ /* Features in %edx for leaf 7 sub-leaf 0 */
+ static constexpr uint32_t bit_AVX5124VNNIW = 0x00000004;
+ static constexpr uint32_t bit_AVX5124FMAPS = 0x00000008;
+
+ /* Features in %eax for leaf 13 sub-leaf 1 */
+ static constexpr uint32_t bit_XSAVEOPT = 0x00000001;
+ static constexpr uint32_t bit_XSAVEC = 0x00000002;
+ static constexpr uint32_t bit_XSAVES = 0x00000008;
+
+ /* Features in %ecx for leaf = 0x80000001 */;
+ static constexpr uint32_t bit_LAHF_LM = 0x00000001;
+ static constexpr uint32_t bit_ABM = 0x00000020;
+ static constexpr uint32_t bit_SSE4a = 0x00000040;
+ static constexpr uint32_t bit_PRFCHW = 0x00000100;
+ static constexpr uint32_t bit_XOP = 0x00000800;
+ static constexpr uint32_t bit_LWP = 0x00008000;
+ static constexpr uint32_t bit_FMA4 = 0x00010000;
+ static constexpr uint32_t bit_TBM = 0x00200000;
+ static constexpr uint32_t bit_MWAITX = 0x20000000;
+
+ /* Features in %edx for leaf = 0x80000001 */;
+ static constexpr uint32_t bit_MMXEXT = 0x00400000;
+ static constexpr uint32_t bit_LM = 0x20000000;
+ static constexpr uint32_t bit_3DNOWP = 0x40000000;
+ static constexpr uint32_t bit_3DNOW = 0x80000000;
+
+ /* Features in %ebx for leaf = 0x80000001 */;
+ static constexpr uint32_t bit_CLZERO = 0x00000001;
+
+ /**
+ * Reads CPU information and other data.
+ */
+ void loadCpuInformation();
+
+ /**
+ * Installed CPU information mapping
+ */
+ struct CpuTopology {
+ /**
+ * Number of physical processors installed
+ */
+ uint8_t packageCount {0};
+
+ /**
+ * Number of physical cores per package
+ */
+ uint8_t physicalCount[MaxCpus] {};
+
+ /**
+ * Number of logical cores per package
+ */
+ uint8_t logicalCount[MaxCpus] {};
+
+ /**
+ * Total number of physical cores
+ */
+ inline uint8_t totalPhysical() {
+ uint8_t count = physicalCount[0];
+ for (uint8_t i = 1; i < packageCount; i++)
+ count += physicalCount[i];
+ return count;
+ }
+
+ /**
+ * Total number of logical cores
+ */
+ inline uint8_t totalLogical() {
+ uint8_t count = logicalCount[0];
+ for (uint8_t i = 1; i < packageCount; i++)
+ count += logicalCount[i];
+ return count;
+ }
+
+ /**
+ * Mapping of cpu_number() to CPU package from 0 to packageCount
+ */
+ uint8_t numberToPackage[MaxCpus] {};
+
+ /**
+ * Mapping of cpu_number() to physical core from 0 to physicalCount in package
+ */
+ uint8_t numberToPhysical[MaxCpus] {};
+
+ /**
+ * Mapping of cpu_number() to physical cores from 0 to totalPhysical.
+ */
+ inline uint8_t numberToPhysicalUnique(uint8_t i) {
+ uint8_t num = 0;
+ uint8_t package = numberToPackage[i];
+ for (uint8_t i = 0; i < package; i++)
+ num += physicalCount[i];
+ return num + numberToPhysical[i];
+ }
+
+ /**
+ * Mapping of cpu_number() to logical thread from 0 to logicalCount in package
+ * Note, that the list is sorted, and the first physicalCount logical threads
+ * correspond to their corresponding physical cores.
+ */
+ uint8_t numberToLogical[MaxCpus] {};
+ };
+
+ /**
+ * Get running CPU generation.
+ *
+ * @param ofamily a pointer to store CPU family in
+ * @param omodel a pointer to store CPU model in
+ * @param ostepping a pointer to store CPU stepping in
+ *
+ * @return detected Intel CPU generation
+ */
+ EXPORT CpuGeneration getGeneration(uint32_t *ofamily=nullptr, uint32_t *omodel=nullptr, uint32_t *ostepping=nullptr);
+
+ /**
+ * Obtain CPU topology.
+ *
+ * @param topology parsed cpu topology, must be passed zeroed.
+ *
+ * @return true on success
+ */
+ EXPORT bool getCpuTopology(CpuTopology &topology);
+
+ /**
+ * Obtain cpuid registers
+ *
+ * @param no cpuid number
+ * @param count cpuid count
+ * @param a eax output pointer (optional)
+ * @param b ebx output pointer (optional)
+ * @param c ecx output pointer (optional)
+ * @param d edx output pointer (optional)
+ *
+ * @return true if supported
+ */
+ EXPORT bool getCpuid(uint32_t no, uint32_t count, uint32_t *a, uint32_t *b=nullptr, uint32_t *c=nullptr, uint32_t *d=nullptr);
+}
+
+#endif /* kern_cpu_h */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_crypto.hpp b/Lilu.kext/Contents/Resources/Headers/kern_crypto.hpp
new file mode 100644
index 0000000..d8fc594
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_crypto.hpp
@@ -0,0 +1,111 @@
+//
+// kern_crypto.hpp
+// Lilu
+//
+// Copyright © 2017 vit9696. All rights reserved.
+//
+
+#ifndef kern_crypto_h
+#define kern_crypto_h
+
+#include
+#include
+#include
+
+namespace Crypto {
+ /**
+ * Currently this is equal to both key size and block size
+ */
+ static constexpr uint32_t BlockSize = 16;
+
+ /**
+ * Currently this is guaranteed hash size
+ */
+ static constexpr uint32_t MinDigestSize = 32;
+
+ /**
+ * Encrypted data format
+ */
+ struct PACKED Encrypted {
+ uint8_t iv[BlockSize]; // Initialisation vector
+ struct PACKED Data {
+ uint32_t size; // Actual encrypted buffer size
+ uint8_t buf[BlockSize - sizeof(uint32_t)]; // Encrypted buffer >= BlockSize
+ };
+
+ union {
+ Data enc;
+ uint8_t buf[BlockSize];
+ };
+ };
+
+ /**
+ * Securely erase memory buffer
+ * Based off cc_clear from corecrypto (src/cc_clear.c)
+ *
+ * @param len buffer length
+ * @param dst buffer pointer
+ */
+ inline void zeroMemory(size_t len, void *dst) {
+ auto vptr = reinterpret_cast(dst);
+ while (len--)
+ *vptr++ = '\0';
+ }
+
+ /**
+ * Generates a platform specific encryption key to be used for later encryption/decryption.
+ * Use very cautiously, this generates a key that should be reproducible on the same hardware.
+ * This means that the key is NOT meant protect the data from decryption on the same machine,
+ * but it only tries to circumvent cases when some blobs containing sensitive information
+ * (e.g. nvram dumps) were accidentally shared.
+ *
+ * This is currently UNIMPLEMENTED
+ *
+ * @param seed prefixed data blob used for key generation
+ * @param size seed size
+ *
+ * @return generated key of at least BlockSize bits long (must be freeded by Buffer::deleter) or nullptr
+ */
+ EXPORT uint8_t *genPlatformKey(const uint8_t *seed=nullptr, uint32_t size=0);
+
+ /**
+ * Generates cryptographically secure encryption key (from /dev/random)
+ *
+ * @return generated key of at least BlockSize bits long (must be freeded by Buffer::deleter) or nullptr
+ */
+ EXPORT uint8_t *genUniqueKey(uint32_t size=BlockSize);
+
+ /**
+ * Encrypts data of specified size and stores in Encrypted format
+ *
+ * @param key encryption key returned by genUniqueKey, genPlatformKey (default if null)
+ * @param src source data
+ * @param size data size, encrypted size is returned on success
+ *
+ * @param encrypted data in Encrypted format (must be freeded by Buffer::deleter) or nullptr
+ */
+ EXPORT uint8_t *encrypt(const uint8_t *key, const uint8_t *src, uint32_t &size);
+
+ /**
+ * Decrypts data of specified size stored in Encrypted format
+ *
+ * @param key encryption key returned by genUniqueKey, genPlatformKey (default if null)
+ * @param src source data
+ * @param size data size, decrypted size is returned on success
+ *
+ * @param decrypted data (must be freeded by Buffer::deleter) or nullptr
+ */
+ EXPORT uint8_t *decrypt(const uint8_t *key, const uint8_t *src, uint32_t &size);
+
+ /**
+ * Calculate digest of given size
+ *
+ * @param src source data
+ * @param size data size
+ *
+ * @return digest hash of at least MinDigestSize bytes (must be freeded by Buffer::deleter) or nullptr
+ */
+ EXPORT uint8_t *hash(const uint8_t *src, uint32_t size);
+}
+
+#endif /* kern_crypto_h */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_devinfo.hpp b/Lilu.kext/Contents/Resources/Headers/kern_devinfo.hpp
new file mode 100644
index 0000000..ab22669
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_devinfo.hpp
@@ -0,0 +1,255 @@
+//
+// kern_devinfo.hpp
+// Lilu
+//
+// Copyright © 2018 vit9696. All rights reserved.
+//
+
+#ifndef kern_devinfo_h
+#define kern_devinfo_h
+
+#include
+#include
+#include
+
+/**
+ * Obtain installed devices split into categories.
+ * Should be used from onPatcherLoad and onwards.
+ */
+class DeviceInfo {
+ /**
+ * Updates reportedLayoutId
+ */
+ void updateLayoutId();
+
+ /**
+ * Updates reportedFramebufferId
+ */
+ void updateFramebufferId();
+
+ /**
+ * Updates firmwareVendor
+ */
+ void updateFirmwareVendor();
+
+ /**
+ * Obtains devices from PCI root
+ *
+ * @param pciRoot PCI root instance (commonly PCI0@0 device)
+ */
+ void grabDevicesFromPciRoot(IORegistryEntry *pciRoot);
+
+public:
+ /**
+ * Obtains autodetected legacy framebuffer if applicable
+ *
+ * @return framebuffer or 0xFFFFFFFF
+ */
+ static uint32_t getLegacyFramebufferId();
+
+ /**
+ * Checks whether the framebuffer has connectors or not.
+ *
+ * @return true if the framebuffer has no connectors
+ */
+ static bool isConnectorLessPlatformId(uint32_t id);
+
+ /**
+ * Common external GPU parameter list
+ */
+ struct ExternalVideo {
+ /**
+ * Aka GFX0 device
+ */
+ IORegistryEntry *video {nullptr};
+
+ /**
+ * Aka HDAU device
+ */
+ IORegistryEntry *audio {nullptr};
+
+ /**
+ * External GPU vendor
+ */
+ uint32_t vendor {0};
+ };
+
+ /**
+ * Aka HDEF device
+ */
+ IORegistryEntry *audioBuiltinAnalog {nullptr};
+
+ /**
+ * Aka HDAU device for builtin GPU
+ */
+ IORegistryEntry *audioBuiltinDigital {nullptr};
+
+ /**
+ * Aka IGPU device
+ */
+ IORegistryEntry *videoBuiltin {nullptr};
+
+ /**
+ * Aka IMEI device
+ */
+ IORegistryEntry *managementEngine {nullptr};
+
+ /**
+ * Aka GFX0 devices (kept in sync with audioExternal)
+ */
+ evector videoExternal;
+
+private:
+ /**
+ * This is the default reported layout-id passed to reportedLayoutId.
+ * The reason for choosing 7 is its presence in 10.14 and the fact
+ * Apple frameworks still communicate to the files present on disk.
+ * For information purposes only! Use reportedLayoutId!
+ */
+ static constexpr uint32_t DefaultReportedLayoutId = 7;
+
+ /**
+ * The boot-arg to override the reported layout-id to AppleHDA.
+ * For user configuration only! Use reportedLayoutId!
+ */
+ static constexpr const char *ReportedLayoutIdArg = "alcapplid";
+
+ /**
+ * The property to override the reported layout-id to AppleHDA.
+ * For user configuration only! Use reportedLayoutId!
+ */
+ static constexpr const char *ReportedLayoutIdName = "apple-layout-id";
+
+public:
+ /**
+ * Layout id to be reported by all audio devices (you must update it yourself).
+ * This follows the standard convention initially found in AppleALC:
+ * alcapplid=X boot-arg has highest priority and overrides any other value.
+ * apple-layout-id HDEF prop has normal priority, you may use it if you need.
+ * DefaultReportedLayoutId will be used if both of the above are not set.
+ */
+ uint32_t reportedLayoutId {0};
+
+private:
+ /**
+ * The boot-arg to override the reported AAPL,ig-platform-id to Intel drivers.
+ * For user configuration only! Use reportedFramebufferId!
+ */
+ static constexpr const char *ReportedFrameIdArg = "igfxframe";
+
+ /**
+ * The boot-arg to override the reported AAPL,ig-platform-id to Intel drivers.
+ * Sets VESA framebuffer id (0xFFFFFFFF).
+ * For user configuration only! Use reportedFramebufferId!
+ */
+ static constexpr const char *ReportedVesaIdArg = "-igfxvesa";
+
+ /**
+ * The property to set your platform id for Intel drivers (Ivy and newer).
+ * For user configuration only! Use reportedFramebufferName!
+ */
+ static constexpr const char *ReportedFrameIdName = "AAPL,ig-platform-id";
+
+ /**
+ * The property to set your platform id for Intel drivers (Sandy).
+ * For user configuration only! Use reportedFramebufferName!
+ */
+ static constexpr const char *ReportedFrameIdLegacyName = "AAPL,snb-platform-id";
+
+ /**
+ * Known platform ids used by Intel GPU kexts
+ * For user configuration only!
+ */
+ static constexpr uint32_t DefaultAppleSkylakePlatformId {0x19120000};
+ static constexpr uint32_t DefaultAppleKabyLakePlatformId {0x59160000};
+ static constexpr uint32_t DefaultAppleCoffeeLakePlatformId {0x3EA50000};
+ static constexpr uint32_t DefaultAppleCannonLakePlatformId {0x5A520000};
+ static constexpr uint32_t DefaultAppleIceLakeRealPlatformId {0x8A520000};
+ static constexpr uint32_t DefaultAppleIceLakeSimulatorPlatformId {0xFF050000};
+
+ /**
+ * Framebuffers without any ports used for hardware acceleration only
+ * Note 1: Broadwell framebuffers all have connectors added.
+ * Note 2: Coffee Lake framebuffers without connectors are only present in 10.14.
+ * Note 3: prerelease Cannon Lake and Ice Lake framebuffers are without connectors.
+ * For user configuration only!
+ */
+ static constexpr uint32_t ConnectorLessSandyBridgePlatformId1 {0x00030030};
+ static constexpr uint32_t ConnectorLessSandyBridgePlatformId2 {0x00050000};
+ static constexpr uint32_t ConnectorLessIvyBridgePlatformId1 {0x01620006};
+ static constexpr uint32_t ConnectorLessIvyBridgePlatformId2 {0x01620007};
+ static constexpr uint32_t ConnectorLessHaswellPlatformId1 {0x04120004};
+ static constexpr uint32_t ConnectorLessHaswellPlatformId2 {0x0412000B};
+ static constexpr uint32_t ConnectorLessSkylakePlatformId1 {0x19020001};
+ static constexpr uint32_t ConnectorLessSkylakePlatformId2 {0x19170001};
+ static constexpr uint32_t ConnectorLessSkylakePlatformId3 {0x19120001};
+ static constexpr uint32_t ConnectorLessSkylakePlatformId4 {0x19320001};
+ static constexpr uint32_t ConnectorLessKabyLakePlatformId1 {0x59180002};
+ static constexpr uint32_t ConnectorLessKabyLakePlatformId2 {0x59120003};
+ static constexpr uint32_t ConnectorLessCoffeeLakePlatformId1 {0x3E920003};
+ static constexpr uint32_t ConnectorLessCoffeeLakePlatformId2 {0x3E910003};
+
+public:
+ /**
+ * Vesa framebuffer identifier
+ */
+ static constexpr uint32_t DefaultVesaPlatformId {0xFFFFFFFF};
+
+ /**
+ * Framebuffer id to be reported to IGPU.
+ * This follows the standard convention initially found in IntelGraphicsFixup:
+ * igfxframe=X boot-arg has highest priority and overrides any other value.
+ * -igfxvesa forces 0xFFFFFFFF frame to get into VESA mode.
+ * Manually specified AAPL,ig-platform-id or AAPL,snb-platform-id go next.
+ * On Sandy Bridge processors a default AAPL,snb-platform-id will be tried afterwards.
+ * On Skylake and Kaby Lake processors some default id will be tried afterwards.
+ */
+ uint32_t reportedFramebufferId {0};
+
+ /**
+ * Compatible platform id property name for this IGPU
+ */
+ const char *reportedFramebufferName {nullptr};
+
+ /**
+ * Set to true if the framebuffer has no connectors
+ */
+ bool reportedFramebufferIsConnectorLess {false};
+
+ /**
+ * Known variants of firmware vendors
+ * Please note, that it may not be possible to always detect the right vendor
+ */
+ enum class FirmwareVendor {
+ Unknown,
+ Apple,
+ VMware,
+ EDKII,
+ Parallels,
+ AMI,
+ Insyde,
+ Phoenix,
+ HP
+ };
+
+ /**
+ * Firmware vendor manufacturer
+ */
+ FirmwareVendor firmwareVendor {FirmwareVendor::Unknown};
+
+ /**
+ * Allocate and initialise the device list.
+ *
+ * @return device list or nullptr
+ */
+ EXPORT static DeviceInfo *create();
+
+ /**
+ * Release initialised device list.
+ *
+ * @param d device list
+ */
+ EXPORT static void deleter(DeviceInfo *d);
+};
+
+#endif /* kern_devinfo_h */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_disasm.hpp b/Lilu.kext/Contents/Resources/Headers/kern_disasm.hpp
index 2243217..fbabac7 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_disasm.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_disasm.hpp
@@ -8,18 +8,21 @@
#ifndef kern_disasm_hpp
#define kern_disasm_hpp
+#include
+#include
+
+#ifdef LILU_ADVANCED_DISASSEMBLY
#ifndef CAPSTONE_HAS_OSXKERNEL
#define CAPSTONE_HAS_OSXKERNEL 1
#endif
-
-#include
-#include
#include
+#endif /* LILU_ADVANCED_DISASSEMBLY */
#include
#include
class Disassembler {
+#ifdef LILU_ADVANCED_DISASSEMBLY
/**
* Because captsone handle can be 0
*/
@@ -28,7 +31,8 @@ class Disassembler {
/**
* Internal capstone handle
*/
- size_t handle;
+ size_t handle {};
+#endif
/**
* Max instruction size
@@ -36,23 +40,10 @@ class Disassembler {
static constexpr size_t MaxInstruction {15};
public:
- /**
- * Initialise dissassembling framework
- *
- * @param detailed debugging output necessity
- *
- * @return true on success
- */
- EXPORT bool init(bool detailed=false);
-
- /**
- * Deinitialise dissassembling framework, must be called regardless of the init error
- */
- EXPORT void deinit();
-
/**
* Return the real instruction size contained within min bytes
* Unlike instructionSize this uses HDE engine and at the cost of reduced compatibility it is much faster
+ * Note: instruction pointer should point to at least min + 32 valid bytes.
*
* @param ptr instruction pointer
* @param min minimal possible size
@@ -60,7 +51,23 @@ class Disassembler {
* @return instruction size >= min on success or 0
*/
EXPORT static size_t quickInstructionSize(mach_vm_address_t ptr, size_t min);
+
+#ifdef LILU_ADVANCED_DISASSEMBLY
+
+ /**
+ * Initialise advanced dissassembling framework
+ *
+ * @param detailed debugging output necessity
+ *
+ * @return true on success
+ */
+ EXPORT bool init(bool detailed=false);
+ /**
+ * Deinitialise advanced dissassembling framework, must be called regardless of the init error
+ */
+ EXPORT void deinit();
+
/**
* Reads size bytes from addr and disassembles them.
*
@@ -148,6 +155,8 @@ class Disassembler {
* @return direct address of pattern start on success, else 0
*/
EXPORT mach_vm_address_t disasmSig(mach_vm_address_t addr, evector &sig, size_t num, size_t lookup_size);
+
+#endif /* LILU_ADVANCED_DISASSEMBLY */
};
#endif /* kern_disasm_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_efi.hpp b/Lilu.kext/Contents/Resources/Headers/kern_efi.hpp
new file mode 100644
index 0000000..48c6fa5
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_efi.hpp
@@ -0,0 +1,86 @@
+//
+// kern_efi.hpp
+// Lilu
+//
+// Copyright © 2018 vit9696. All rights reserved.
+//
+
+#ifndef kern_efi_h
+#define kern_efi_h
+
+#include
+
+#include
+
+/**
+ * Convert 32-bit EFI errors provided by Apple to 64-bit EFI errors
+ */
+#define EFI_ERROR64(x) (((x) & ~(1ULL << 31)) | (1ULL << 63))
+static_assert(EFI_LOAD_ERROR == 0x80000001 && EFI_ERROR64(EFI_LOAD_ERROR) == 0x8000000000000001,
+ "Apple has finally upgraded EFI headers!");
+
+class EfiRuntimeServices {
+ IOLock *accessLock {nullptr};
+ static EfiRuntimeServices *instance;
+public:
+ /**
+ * Activates EFI Runtime Services
+ */
+ static void activate();
+
+ /**
+ * Lilu custom GUIDs exports, see Headers/Guid/LiluVariables.h
+ */
+ EXPORT static const EFI_GUID LiluNormalGuid;
+ EXPORT static const EFI_GUID LiluReadOnlyGuid;
+ EXPORT static const EFI_GUID LiluWriteOnlyGuid;
+
+ /**
+ * Get EFI Runtime Services wrapper if supported
+ *
+ * @param lock lock instance during the run, must be put back
+ *
+ * @return wrapper instance
+ */
+ EXPORT static EfiRuntimeServices *get(bool lock=false);
+
+ /**
+ * Put EFI Runtime Services wrapper to unlock
+ */
+ EXPORT void put();
+
+ /**
+ * Perform system reset (does not return on success)
+ *
+ * @param type reset type
+ */
+ EXPORT void resetSystem(EFI_RESET_TYPE type);
+
+ /**
+ * Obtain EFI variable, invokes EFI_RUNTIME_SERVICES::GetVariable.
+ *
+ * @param name variable name
+ * @param guid vendor guid
+ * @param attr variable attributes
+ * @param size data buffer size updated on read
+ * @param data read data
+ *
+ * @return EFI_STATUS code
+ */
+ EXPORT uint64_t getVariable(const char16_t *name, const EFI_GUID *guid, uint32_t *attr, uint64_t *size, void *data);
+
+ /**
+ * Set EFI variable, invokes EFI_RUNTIME_SERVICES::SetVariable.
+ *
+ * @param name variable name
+ * @param guid vendor guid
+ * @param attr variable attributes
+ * @param size data buffer size
+ * @param data data to write
+ *
+ * @return EFI_STATUS code
+ */
+ EXPORT uint64_t setVariable(const char16_t *name, const EFI_GUID *guid, uint32_t attr, uint64_t size, void *data);
+};
+
+#endif /* kern_efi_h */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_iokit.hpp b/Lilu.kext/Contents/Resources/Headers/kern_iokit.hpp
index b37953b..6c753dd 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_iokit.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_iokit.hpp
@@ -34,42 +34,82 @@ namespace WIOKit {
* @return true on success
*/
template
- bool getOSDataValue(const OSObject *obj, const char *name, T &value) {
+ inline bool getOSDataValue(const OSObject *obj, const char *name, T &value) {
if (obj) {
auto data = OSDynamicCast(OSData, obj);
if (data && data->getLength() == sizeof(T)) {
value = *static_cast(data->getBytesNoCopy());
- DBGLOG("iokit @ getOSData %s has %llX value", name, static_cast(value));
+ DBGLOG("iokit", "getOSData %s has %llX value", name, static_cast(value));
return true;
} else {
- SYSLOG("iokit @ getOSData %s has unexpected format", name);
+ SYSLOG("iokit", "getOSData %s has unexpected format", name);
}
} else {
- DBGLOG("iokit @ getOSData %s was not found", name);
+ DBGLOG("iokit", "getOSData %s was not found", name);
}
return false;
}
-
+
+ /**
+ * Read typed OSData through a temp type
+ *
+ * @param obj read object
+ * @param value read value
+ * @param name propert name
+ *
+ * @return true on success
+ */
+ template
+ inline bool getOSDataValue(const OSObject *obj, const char *name, T &value) {
+ AS tmp;
+ if (getOSDataValue(obj, name, tmp)) {
+ value = static_cast(tmp);
+ return true;
+ }
+
+ return false;
+ }
+
/**
* Read typed OSData from IORegistryEntry
*
* @see getOSDataValue
*/
template
- bool getOSDataValue(const IORegistryEntry *sect, const char *name, T &value) {
+ inline bool getOSDataValue(const IORegistryEntry *sect, const char *name, T &value) {
return getOSDataValue(sect->getProperty(name), name, value);
}
-
+
+ /**
+ * Read typed OSData from IORegistryEntry
+ *
+ * @see getOSDataValue
+ */
+ template
+ inline bool getOSDataValue(const IORegistryEntry *sect, const char *name, T &value) {
+ return getOSDataValue(sect->getProperty(name), name, value);
+ }
+
/**
* Read typed OSData from IORegistryEntry
*
* @see getOSDataValue
*/
template
- bool getOSDataValue(const OSDictionary *dict, const char *name, T &value) {
+ inline bool getOSDataValue(const OSDictionary *dict, const char *name, T &value) {
return getOSDataValue(dict->getObject(name), name, value);
}
+ /**
+ * Read typed OSData from IORegistryEntry
+ *
+ * @see getOSDataValue
+ */
+ template
+ inline bool getOSDataValue(const OSDictionary *dict, const char *name, T &value) {
+ return getOSDataValue(dict->getObject(name), name, value);
+ }
+
/**
* Retrieve property object
*
@@ -79,26 +119,132 @@ namespace WIOKit {
* @return property object (must be released) or nullptr
*/
EXPORT OSSerialize *getProperty(IORegistryEntry *entry, const char *property);
-
+
/**
* Model variants
*/
struct ComputerModel {
enum {
ComputerInvalid = 0x0,
- ComputerLaptop = 0x1,
+ ComputerLaptop = 0x1,
ComputerDesktop = 0x2,
ComputerAny = ComputerLaptop | ComputerDesktop
};
};
-
+
+ /**
+ * PCI GPU Vendor identifiers
+ */
+ struct VendorID {
+ enum : uint16_t {
+ ATIAMD = 0x1002,
+ NVIDIA = 0x10de,
+ Intel = 0x8086
+ };
+ };
+
+ /**
+ * PCI class codes
+ */
+ struct ClassCode {
+ enum : uint32_t {
+ VGAController = 0x30000,
+ DisplayController = 0x38000,
+ PCIBridge = 0x60400,
+ HDADevice = 0x040300,
+ // This does not seem to be documented. It works on Haswell at least.
+ IMEI = 0x78000
+ };
+ };
+
+ /**
+ * Definitions of PCI Config Registers
+ */
+ enum PCIRegister : uint8_t {
+ kIOPCIConfigVendorID = 0x00,
+ kIOPCIConfigDeviceID = 0x02,
+ kIOPCIConfigCommand = 0x04,
+ kIOPCIConfigStatus = 0x06,
+ kIOPCIConfigRevisionID = 0x08,
+ kIOPCIConfigClassCode = 0x09,
+ kIOPCIConfigCacheLineSize = 0x0C,
+ kIOPCIConfigLatencyTimer = 0x0D,
+ kIOPCIConfigHeaderType = 0x0E,
+ kIOPCIConfigBIST = 0x0F,
+ kIOPCIConfigBaseAddress0 = 0x10,
+ kIOPCIConfigBaseAddress1 = 0x14,
+ kIOPCIConfigBaseAddress2 = 0x18,
+ kIOPCIConfigBaseAddress3 = 0x1C,
+ kIOPCIConfigBaseAddress4 = 0x20,
+ kIOPCIConfigBaseAddress5 = 0x24,
+ kIOPCIConfigCardBusCISPtr = 0x28,
+ kIOPCIConfigSubSystemVendorID = 0x2C,
+ kIOPCIConfigSubSystemID = 0x2E,
+ kIOPCIConfigExpansionROMBase = 0x30,
+ kIOPCIConfigCapabilitiesPtr = 0x34,
+ kIOPCIConfigInterruptLine = 0x3C,
+ kIOPCIConfigInterruptPin = 0x3D,
+ kIOPCIConfigMinimumGrant = 0x3E,
+ kIOPCIConfigMaximumLatency = 0x3F
+ };
+
+ /**
+ * Fixed offsets for PCI Config I/O virtual methods
+ */
+ struct PCIConfigOffset {
+ enum : size_t {
+ ConfigRead32 = 0x10A,
+ ConfigWrite32 = 0x10B,
+ ConfigRead16 = 0x10C,
+ ConfigWrite16 = 0x10D,
+ ConfigRead8 = 0x10E,
+ ConfigWrite8 = 0x10F,
+ GetBusNumber = 0x11D,
+ GetDeviceNumber = 0x11E,
+ GetFunctionNumber = 0x11F
+ };
+ };
+
+ /**
+ * PCI Config I/O method prototypes
+ */
+ using t_PCIConfigRead32 = uint32_t (*)(IORegistryEntry *service, uint32_t space, uint8_t offset);
+ using t_PCIConfigRead16 = uint16_t (*)(IORegistryEntry *service, uint32_t space, uint8_t offset);
+ using t_PCIConfigRead8 = uint8_t (*)(IORegistryEntry *service, uint32_t space, uint8_t offset);
+ using t_PCIConfigWrite32 = void (*)(IORegistryEntry *service, uint32_t space, uint8_t offset, uint32_t data);
+ using t_PCIConfigWrite16 = void (*)(IORegistryEntry *service, uint32_t space, uint8_t offset, uint16_t data);
+ using t_PCIConfigWrite8 = void (*)(IORegistryEntry *service, uint32_t space, uint8_t offset, uint8_t data);
+ using t_PCIGetBusNumber = uint8_t (*)(IORegistryEntry *service);
+ using t_PCIGetDeviceNumber = uint8_t (*)(IORegistryEntry *service);
+ using t_PCIGetFunctionNumber = uint8_t (*)(IORegistryEntry *service);
+
+ /**
+ * Read PCI Config register
+ *
+ * @param service IOPCIDevice-compatible service.
+ * @param reg PCI config register
+ * @param space adress space
+ * @param size read size for reading custom registers
+ */
+ EXPORT uint32_t readPCIConfigValue(IORegistryEntry *service, uint32_t reg, uint32_t space = 0, uint32_t size = 0);
+
+ /**
+ * Retrieve PCI device address
+ *
+ * @param service IOPCIDevice-compatible service.
+ * @param bus bus address
+ * @param device device address
+ * @param function function address
+ */
+ EXPORT void getDeviceAddress(IORegistryEntry *service, uint8_t &bus, uint8_t &device, uint8_t &function);
+
/**
* Retrieve the computer type
*
* @return valid computer type or ComputerAny
*/
EXPORT int getComputerModel();
-
+
/**
* Retrieve computer model and/or board-id properties
*
@@ -110,7 +256,7 @@ namespace WIOKit {
* @return true if relevant properties already are available, otherwise buffers are unchanged
*/
EXPORT bool getComputerInfo(char *model, size_t modelsz, char *board, size_t boardsz);
-
+
/**
* Retrieve an ioreg entry by path/prefix
*
@@ -124,7 +270,7 @@ namespace WIOKit {
* @return entry pointer (must NOT be released) or nullptr (on failure or in proc mode)
*/
EXPORT IORegistryEntry *findEntryByPrefix(const char *path, const char *prefix, const IORegistryPlane *plane, bool (*proc)(void *, IORegistryEntry *)=nullptr, bool brute=false, void *user=nullptr);
-
+
/**
* Retrieve an ioreg entry by path/prefix
*
@@ -138,6 +284,24 @@ namespace WIOKit {
* @return entry pointer (must NOT be released) or nullptr (on failure or in proc mode)
*/
EXPORT IORegistryEntry *findEntryByPrefix(IORegistryEntry *entry, const char *prefix, const IORegistryPlane *plane, bool (*proc)(void *, IORegistryEntry *)=nullptr, bool brute=false, void *user=nullptr);
+
+ /**
+ * Check if we are using prelinked kernel/kexts or not
+ *
+ * @return true when confirmed that we definitely are
+ */
+ EXPORT bool usingPrelinkedCache();
+
+ /**
+ * Properly rename the device
+ *
+ * @param entry device to rename
+ * @param name new name
+ * @param compat correct compatible
+ *
+ * @return true on success
+ */
+ EXPORT bool renameDevice(IORegistryEntry *entry, const char *name, bool compat=true);
}
#endif /* kern_iokit_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_mach.hpp b/Lilu.kext/Contents/Resources/Headers/kern_mach.hpp
index aa16c9b..329ee08 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_mach.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_mach.hpp
@@ -18,14 +18,17 @@
#include
#include
#include
+#include
class MachInfo {
mach_vm_address_t running_text_addr {0}; // the address of running __TEXT segment
mach_vm_address_t disk_text_addr {0}; // the same address at from a file
mach_vm_address_t kaslr_slide {0}; // the kernel aslr slide, computed as the difference between above's addresses
-#ifdef LILU_COMPRESSION_SUPPORT
- uint8_t *file_buf {nullptr}; // read file data if decompression was used
-#endif /* LILU_COMPRESSION_SUPPORT */
+ uint8_t *file_buf {nullptr}; // read file data
+ OSDictionary *prelink_dict {nullptr}; // read prealinked kext dictionary
+ uint8_t *prelink_addr {nullptr}; // prelink text base address
+ mach_vm_address_t prelink_vmaddr {0}; // prelink text base vm address (for kexts this is their actual slide)
+ uint32_t file_buf_size {0}; // read file data size
uint8_t *linkedit_buf {nullptr}; // pointer to __LINKEDIT buffer containing symbols to solve
uint64_t linkedit_fileoff {0}; // __LINKEDIT file offset so we can read
uint64_t linkedit_size {0};
@@ -37,45 +40,34 @@ class MachInfo {
size_t memory_size {HeaderSize}; // memory size
bool kaslr_slide_set {false}; // kaslr can be null, used for disambiguation
bool allow_decompress {true}; // allows mach decompression
-
- /**
- * 16 byte IDT descriptor, used for 32 and 64 bits kernels (64 bit capable cpus!)
- */
- struct descriptor_idt {
- uint16_t offset_low;
- uint16_t seg_selector;
- uint8_t reserved;
- uint8_t flag;
- uint16_t offset_middle;
- uint32_t offset_high;
- uint32_t reserved2;
- };
-
+ bool prelink_slid {false}; // assume kaslr-slid kext addresses
+ uint64_t self_uuid[2] {}; // saved uuid of the loaded kext or kernel
+
/**
- * retrieve the address of the IDT
- *
- * @return always returns the IDT address
+ * Kernel slide is aligned by 20 bits
*/
- mach_vm_address_t getIDTAddress();
-
+ static constexpr size_t KASLRAlignment {0x100000};
+
/**
- * calculate the address of the kernel int80 handler
+ * Retrieve LC_UUID command value from a mach header
*
- * @return always returns the int80 handler address
+ * @param header mach header pointer
+ *
+ * @return UUID or nullptr
*/
- mach_vm_address_t calculateInt80Address();
-
+ uint64_t *getUUID(void *header);
+
/**
- * retrieve LC_UUID command value from a mach header
+ * Retrieve and preserve LC_UUID command value from a mach header
*
* @param header mach header pointer
*
- * @return UUID or nullptr
+ * @return true on success
*/
- uint64_t *getUUID(void *header);
+ bool loadUUID(void *header);
/**
- * enable/disable the Write Protection bit in CR0 register
+ * Enable/disable the Write Protection bit in CR0 register
*
* @param enable the desired value
*
@@ -84,8 +76,8 @@ class MachInfo {
static kern_return_t setWPBit(bool enable);
/**
- * retrieve the first pages of a binary at disk into a buffer
- * version that uses KPI VFS functions and a ripped uio_createwithbuffer() from XNU
+ * Retrieve the first pages of a binary at disk into a buffer
+ * Version that uses KPI VFS functions and a ripped uio_createwithbuffer() from XNU
*
* @param buffer allocated buffer sized no less than HeaderSize
* @param vnode file node
@@ -98,7 +90,7 @@ class MachInfo {
kern_return_t readMachHeader(uint8_t *buffer, vnode_t vnode, vfs_context_t ctxt, off_t off=0);
/**
- * retrieve the whole linkedit segment into target buffer from kernel binary at disk
+ * Retrieve the whole linkedit segment into target buffer from kernel binary at disk
*
* @param vnode file node
* @param ctxt filesystem context
@@ -108,18 +100,54 @@ class MachInfo {
kern_return_t readLinkedit(vnode_t vnode, vfs_context_t ctxt);
/**
- * retrieve necessary mach-o header information from the mach header
+ * Retrieve necessary mach-o header information from the mach header
*
* @param header read header sized no less than HeaderSize
*/
void processMachHeader(void *header);
+
+ /**
+ * Load kext info dictionary and addresses if they were not loaded previously
+ */
+ void updatePrelinkInfo();
+
+ /**
+ * Lookup mach image in prelinked image
+ *
+ * @param identifier identifier
+ * @param imageSize size of the returned buffer
+ * @param slide actual slide for symbols (normally kaslr or 0)
+ * @param missing set to true on successful prelink parsing when image is not needed
+ *
+ * @return pointer to const buffer on success or nullptr
+ */
+ uint8_t *findImage(const char *identifier, uint32_t &imageSize, mach_vm_address_t &slide, bool &missing);
MachInfo(bool asKernel, const char *id) : isKernel(asKernel), objectId(id) {
- DBGLOG("mach @ MachInfo asKernel %d object constructed", asKernel);
+ DBGLOG("mach", "MachInfo asKernel %d object constructed", asKernel);
}
MachInfo(const MachInfo &) = delete;
MachInfo &operator =(const MachInfo &) = delete;
-
+
+ /**
+ * Resolve mach data in the kernel via prelinked cache
+ *
+ * @param prelink prelink information source (i.e. Kernel MachInfo)
+ *
+ * @return KERN_SUCCESS if loaded
+ */
+ kern_return_t initFromPrelinked(MachInfo *prelink);
+
+ /**
+ * Resolve mach data in the kernel via filesystem access
+ *
+ * @param paths filesystem paths for lookup
+ * @param num the number of paths passed
+ *
+ * @return KERN_SUCCESS if loaded
+ */
+ kern_return_t initFromFileSystem(const char * const paths[], size_t num);
+
public:
/**
@@ -135,12 +163,13 @@ class MachInfo {
/**
* Specified file identifier
*/
- const char *objectId {nullptr};
+ EXPORT const char *objectId {nullptr};
/**
* MachInfo object generator
*
* @param asKernel this MachInfo represents a kernel
+ * @param id kinfo identifier (e.g. CFBundleIdentifier)
*
* @return MachInfo object or nullptr
*/
@@ -150,12 +179,14 @@ class MachInfo {
/**
* Resolve mach data in the kernel
*
- * @param paths filesystem paths for lookup
- * @param num the number of paths passed
+ * @param paths filesystem paths for lookup
+ * @param num the number of paths passed
+ * @param prelink prelink information source (i.e. Kernel MachInfo)
+ * @param fsfallback fallback to reading from filesystem if prelink failed
*
* @return KERN_SUCCESS if loaded
*/
- EXPORT kern_return_t init(const char * const paths[], size_t num = 1);
+ EXPORT kern_return_t init(const char * const paths[], size_t num = 1, MachInfo *prelink=nullptr, bool fsfallback=false);
/**
* Release the allocated memory, must be called regardless of the init error
@@ -163,7 +194,7 @@ class MachInfo {
EXPORT void deinit();
/**
- * retrieve the mach header and __TEXT addresses
+ * Retrieve the mach header and __TEXT addresses
*
* @param slide load slide if calculating for kexts
* @param size memory size
@@ -184,7 +215,7 @@ class MachInfo {
EXPORT kern_return_t setRunningAddresses(mach_vm_address_t slide=0, size_t size=0);
/**
- * retrieve running mach positions
+ * Retrieve running mach positions
*
* @param header pointer to header
* @param size file size
@@ -192,7 +223,7 @@ class MachInfo {
EXPORT void getRunningPosition(uint8_t * &header, size_t &size);
/**
- * solve a mach symbol (running addresses must be calculated)
+ * Solve a mach symbol (running addresses must be calculated)
*
* @param symbol symbol to solve
*
@@ -201,41 +232,40 @@ class MachInfo {
EXPORT mach_vm_address_t solveSymbol(const char *symbol);
/**
- * find the kernel base address (mach-o header)
- * by searching backwards using the int80 handler as starting point
+ * Find the kernel base address (mach-o header)
*
* @return kernel base address or 0
*/
EXPORT mach_vm_address_t findKernelBase();
/**
- * enable/disable interrupt handling
- * this is similar to ml_set_interrupts_enabled except the return value
+ * Compare the loaded kernel with the current UUID (see loadUUID)
*
- * @param enable the desired value
+ * @param base image base, pass 0 to use kernel base
*
- * @return true if changed the value and false if it is unchanged
+ * @return true if image uuids match
*/
- EXPORT static bool setInterrupts(bool enable);
-
+ EXPORT bool isCurrentBinary(mach_vm_address_t base=0);
+
/**
- * enable/disable kernel memory write protection
+ * Enable/disable interrupt handling
+ * this is similar to ml_set_interrupts_enabled except the return value
*
* @param enable the desired value
- * @param sync for synchronous execution, calls in the middle will be ignored
*
- * @return KERN_SUCCESS if succeeded
+ * @return true if changed the value and false if it is unchanged
*/
- EXPORT static kern_return_t setKernelWriting(bool enable, bool sync=false);
+ EXPORT static bool setInterrupts(bool enable);
/**
- * Compare the loaded kernel with the passed kernel header
+ * Enable/disable kernel memory write protection
*
- * @param kernel_header 64-bit mach header of at least HeaderSize size
+ * @param enable the desired value
+ * @param lock use spinlock to disable cpu preemption (see KernelPatcher::kernelWriteLock)
*
- * @return true if the kernel uuids match
+ * @return KERN_SUCCESS if succeeded
*/
- EXPORT bool isCurrentKernel(void *kernelHeader);
+ EXPORT static kern_return_t setKernelWriting(bool enable, IOSimpleLock *lock);
/**
* Find section bounds in a passed binary for provided cpu
@@ -250,6 +280,11 @@ class MachInfo {
* @param cpu cpu to look for in case of fat binaries
*/
EXPORT static void findSectionBounds(void *ptr, vm_address_t &vmsegment, vm_address_t &vmsection, void *§ionptr, size_t &size, const char *segmentName="__TEXT", const char *sectionName="__text", cpu_type_t cpu=CPU_TYPE_X86_64);
+
+ /**
+ * Request to free file buffer resources (not including linkedit symtable)
+ */
+ void freeFileBufferResources();
};
#endif /* kern_mach_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_nvram.hpp b/Lilu.kext/Contents/Resources/Headers/kern_nvram.hpp
new file mode 100644
index 0000000..2dcb07d
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_nvram.hpp
@@ -0,0 +1,198 @@
+//
+// kern_nvram.hpp
+// Lilu
+//
+// Copyright © 2017 vit9696. All rights reserved.
+//
+
+#ifndef kern_nvram_hpp
+#define kern_nvram_hpp
+
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * Some of the most common GUIDs used for variable storage on macOS
+ */
+#define NVRAM_GLOBAL_GUID "8BE4DF61-93CA-11D2-AA0D-00E098032B8C"
+#define NVRAM_APPLE_BOOT_GUID "7C436110-AB2A-4BBB-A880-FE41995C9F82"
+#define NVRAM_APPLE_VENDOR_GUID "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14"
+#define NVRAM_APPLE_FILEVAULT_GUID "8D63D4FE-BD3C-4AAD-881D-86FD974BC1DF"
+#define NVRAM_APPLE_PASSWORD_UI_GUID "9EBA2D25-BBE3-4AC2-A2C6-C87F44A1278C"
+
+/**
+ * Custom GUIDs used for Lilu preferences
+ * Must be kept in sync to Headers/Guid/LiluVariables.h
+ */
+#define LILU_NORMAL_GUID "2660DD78-81D2-419D-8138-7B1F363F79A6"
+#define LILU_READ_ONLY_GUID "E09B9297-7928-4440-9AAB-D1F8536FBF0A"
+#define LILU_WRITE_ONLY_GUID "F0B9AF8F-2222-4840-8A37-ECF7CC8C12E1"
+
+/**
+ * Prefix variable name with a GUID
+ */
+#define NVRAM_PREFIX(x, y) x ":" y
+
+class NVStorage {
+ /**
+ * Local nvram controller reference
+ */
+ IORegistryEntry *dtEntry {nullptr};
+
+public:
+ /**
+ * Compress data with a default compression algorithm
+ *
+ * @param src source data
+ * @param size data size (updated with new size)
+ * @param sensitive contains sensitive data
+ *
+ * @return compressed data (must be freed with Buffer::deleter) or nullptr
+ */
+ EXPORT uint8_t *compress(const uint8_t *src, uint32_t &size, bool sensitive=false);
+
+ /**
+ * Decompress data compressed with compress
+ *
+ * @param src compressed data
+ * @param size data size (updated with new size)
+ * @param sensitive contains sensitive data
+ *
+ * @return decompressed data (must be freed with Buffer::deleter) or nullptr
+ */
+ EXPORT uint8_t *decompress(const uint8_t *src, uint32_t &size, bool sensitive=false);
+
+ /**
+ * Value storage options
+ */
+ enum Options {
+ OptAuto = 0, // Default options
+ OptRaw = 1, // i/o as raw buffer
+ OptCompressed = 2, // Apply compression (see kern_compression.hpp)
+ OptEncrypted = 4, // Apply encryption with device-unique key (see kern_crypto.hpp)
+ OptChecksum = 8, // Append CRC32 checksum to the end
+ OptSensitive = 16 // Value contains sensitive data
+ };
+
+ /**
+ * Prepended value header unless OptRaw is used
+ * After the header the following fields should go:
+ * uint8_t iv[16]; aes initialisation vector (if OptEncrypted is set)
+ * uint32_t size; decryption size (if OptEncrypted is set, encrypted)
+ * uint32_t size; decompression size (if OptCompressed is set, encrypted if OptEncrypted)
+ * uint8_t data[]; content data (encrypted if OptEncrypted)
+ * uint32_t crc32; CRC32 cheksum (if OptChecksum is set)
+ */
+ struct PACKED Header {
+ static constexpr uint16_t Magic = 0xC717;
+ static constexpr uint8_t MaxVer = 1;
+ using Checksum = uint32_t;
+
+ uint16_t magic {Magic};
+ uint8_t version {MaxVer};
+ uint8_t opts {OptAuto};
+ };
+
+ /**
+ * Attempt to connect to active nvram, may fail at early stages
+ *
+ * @return true on success
+ */
+ EXPORT bool init();
+
+ /**
+ * Relinquish resources used, must be called regardless of the init error
+ */
+ EXPORT void deinit();
+
+ /**
+ * Read data from nvram
+ *
+ * @param key key name
+ * @param size amount of data read
+ * @param opts bitmask of Options, may set option requirements
+ * @param enckey encryption key (platform-defined if OptEncrypted is set)
+ *
+ * @return pointer to data (must be freed via Buffer::deleter), nullptr on failure
+ */
+ EXPORT uint8_t *read(const char *key, uint32_t &size, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
+
+ /**
+ * Read data from nvram
+ *
+ * @param key key name
+ * @param opts bitmask of Options, may set option requirements
+ * @param enckey encryption key (platform-defined if OptEncrypted is set)
+ *
+ * @return pointer to data (must be freed via OSData::release), nullptr on failure
+ */
+ EXPORT OSData *read(const char *key, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
+
+ /**
+ * Write data to nvram
+ *
+ * @param key key name
+ * @param src source buffer
+ * @param size buffer size
+ * @param opts bitmask of Options
+ * @param enckey encryption key (platform-defined if OptEncrypted is set)
+ *
+ * @return true on success
+ */
+ EXPORT bool write(const char *key, const uint8_t *src, uint32_t sz, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
+
+ /**
+ * Write data to nvram
+ *
+ * @param key key name
+ * @param data data object to write
+ * @param opts bitmask of Options
+ * @param enckey encryption key (platform-defined if OptEncrypted is set)
+ *
+ * @return true on success
+ */
+ EXPORT bool write(const char *key, const OSData *data, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
+
+ /**
+ * Delete key from nvram
+ *
+ * @param key key name
+ * @param sensitive sensitive data
+ *
+ * @return true on successful deletion or if key is missing
+ */
+ EXPORT bool remove(const char *key, bool sensitive=false);
+
+ /**
+ * Synchronize with nvram controller
+ * This method might fail if synchronisation was done recently.
+ *
+ * @return true if synchronised
+ */
+ EXPORT bool sync();
+
+ /**
+ * Exports nvram to a plist file
+ *
+ * @param filename file path
+ * @oaram max max output size
+ * @param sensitive contains sensitive data
+ *
+ * @return true if saved
+ */
+ EXPORT bool save(const char *filename, uint32_t max=0x20000, bool sensitive=false);
+
+ /**
+ * Check whether key exists
+ *
+ * @param key key name
+ *
+ * @return true if key exists
+ */
+ EXPORT bool exists(const char *key);
+};
+
+#endif /* kern_nvram_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_patcher.hpp b/Lilu.kext/Contents/Resources/Headers/kern_patcher.hpp
index 684981b..1ca78e1 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_patcher.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_patcher.hpp
@@ -9,6 +9,7 @@
#define kern_patcher_hpp
#include
+#include
#include
#include
#include
@@ -38,7 +39,10 @@ class KernelPatcher {
MemoryIssue,
MemoryProtection,
PointerRange,
- AlreadyDone
+ AlreadyDone,
+ LockError,
+ Unsupported,
+ InvalidSymbolFound
};
/**
@@ -63,6 +67,12 @@ class KernelPatcher {
*/
void deinit();
+ /**
+ * Kernel write lock used for performing kernel & kext writes to disable cpu preemption
+ * See MachInfo::setKernelWriting
+ */
+ EXPORT static IOSimpleLock *kernelWriteLock;
+
/**
* Kext information
*/
@@ -71,27 +81,49 @@ class KernelPatcher {
#ifdef LILU_KEXTPATCH_SUPPORT
struct KextInfo {
static constexpr size_t Unloaded {0};
- const char *id;
- const char **paths;
- size_t pathNum;
- bool loaded; // invoke for kext if it is already loaded
- bool reloadable; // allow the kext to unload and get patched again
- bool user[6];
- size_t loadIndex; // Updated after loading
+ enum SysFlags : size_t {
+ Loaded, // invoke for kext if it is already loaded
+ Reloadable, // allow the kext to unload and get patched again
+ Disabled, // do not load this kext (formerly achieved pathNum = 0, this no longer works)
+ FSOnly, // do not use prelinkedkernel (kextcache) as a symbol source
+ FSFallback, // perform fs fallback if kextcache failed
+ Reserved,
+ SysFlagNum,
+ };
+ static constexpr size_t UserFlagNum {sizeof(size_t)-SysFlagNum};
+ static_assert(UserFlagNum > 0, "There should be at least one user flag");
+ const char *id {nullptr};
+ const char **paths {nullptr};
+ size_t pathNum {0};
+ bool sys[SysFlagNum] {};
+ bool user[UserFlagNum] {};
+ size_t loadIndex {Unloaded}; // Updated after loading
+
+ /**
+ * Disable this info from being used
+ * May be called from onPatcherLoad callbacks to disable certain kexts
+ */
+ void switchOff() {
+ sys[KernelPatcher::KextInfo::Disabled] = true;
+ }
};
+
+ static_assert(sizeof(KextInfo) == 5 * sizeof(size_t), "KextInfo is no longer ABI compatible");
#endif /* LILU_KEXTPATCH_SUPPORT */
/**
* Loads and stores kinfo information locally
*
- * @param id kernel item identifier
- * @param paths item filesystem path array
- * @param num number of path entries
- * @param isKernel kinfo is kernel info
+ * @param id kernel item identifier
+ * @param paths item filesystem path array
+ * @param num number of path entries
+ * @param isKernel kinfo is kernel info
+ * @param fsonly avoid using prelinkedkernel for kexts
+ * @param fsfallback fallback to reading from filesystem if prelink failed
*
* @return loaded kinfo id
*/
- EXPORT size_t loadKinfo(const char *id, const char * const paths[], size_t num=1, bool isKernel=false);
+ EXPORT size_t loadKinfo(const char *id, const char * const paths[], size_t num=1, bool isKernel=false, bool fsonly=false, bool fsfallback=false);
#ifdef LILU_KEXTPATCH_SUPPORT
/**
@@ -143,12 +175,46 @@ class KernelPatcher {
* @return running symbol address or 0
*/
EXPORT mach_vm_address_t solveSymbol(size_t id, const char *symbol);
-
+
+ /**
+ * Solve a kinfo symbol in range with designated type
+ *
+ * @param id loaded kinfo id
+ * @param symbol symbol to solve
+ * @param start start address range
+ * @param size address range size
+ * @param crash kernel panic on invalid non-zero address
+ *
+ * @return running symbol address or 0 casted to type T (mach_vm_address_t)
+ */
+ template
+ 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;
+ }
+
/**
* Hook kext loading and unloading to access kexts at early stage
*/
EXPORT void setupKextListening();
-
+
+ /**
+ * Free file buffer resources and effectively make prelinked kext loading impossible
+ */
+ void freeFileBufferResources();
+
/**
* Activates monitoring functions if necessary
*/
@@ -211,6 +277,15 @@ class KernelPatcher {
* @param patch patch to apply
*/
EXPORT void applyLookupPatch(const LookupPatch *patch);
+
+ /**
+ * Apply a find/replace patch with additional constraints
+ *
+ * @param patch patch to apply
+ * @param startingAddress start with this address (or kext/kernel lowest address)
+ * @param maxSize maximum size to look for (or kext/kernel max size)
+ */
+ EXPORT void applyLookupPatch(const LookupPatch *patch, uint8_t *startingAddress, size_t maxSize);
#endif /* LILU_KEXTPATCH_SUPPORT */
/**
@@ -220,10 +295,11 @@ class KernelPatcher {
* @param to routed function
* @param buildWrapper create entrance wrapper
* @param kernelRoute kernel change requiring memory protection changes and patch reverting at unload
+ * @param revertible patches could be reverted
*
* @return wrapper pointer or 0 on success
*/
- EXPORT mach_vm_address_t routeFunction(mach_vm_address_t from, mach_vm_address_t to, bool buildWrapper=false, bool kernelRoute=true);
+ EXPORT mach_vm_address_t routeFunction(mach_vm_address_t from, mach_vm_address_t to, bool buildWrapper=false, bool kernelRoute=true, bool revertible=true);
/**
* Route block at assembly level
@@ -238,6 +314,98 @@ class KernelPatcher {
*/
EXPORT mach_vm_address_t routeBlock(mach_vm_address_t from, const uint8_t *opcodes, size_t opnum, bool buildWrapper=false, bool kernelRoute=true);
+ /**
+ * Route virtual function to function
+ *
+ * @param obj OSObject-compatible instance
+ * @param off function offset in a virtual table (arch-neutral, i.e. divided by sizeof(uintptr_t)
+ * @param func function to replace with
+ * @param orgFunc pointer to store the original function
+ *
+ * @return true on success
+ */
+ template
+ static inline bool routeVirtual(void *obj, size_t off, T func, T *orgFunc=nullptr) {
+ // First OSObject (and similar) field is its virtual table.
+ auto vt = obj ? reinterpret_cast(obj)[0] : nullptr;
+ if (vt) {
+ // Do not try to replace twice!
+ if (vt[off] == func)
+ return false;
+ if (orgFunc) *orgFunc = vt[off];
+ vt[off] = func;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Route request to simplify casting and error handling
+ * See routeMultiple.
+ *
+ * symbol symbol to lookup
+ * from solved symbol (assigned by routeMultiple)
+ * to destination address
+ * org trampoline storage to the original symbol
+ */
+ struct RouteRequest {
+ const char *symbol {nullptr};
+ mach_vm_address_t from {0};
+ const mach_vm_address_t to {0};
+ mach_vm_address_t *org {nullptr};
+
+ /**
+ * Construct RouteRequest for wrapping a function
+ * @param s symbol to lookup
+ * @param t destination address
+ * @param o trampoline storage to the original symbol
+ */
+ template
+ RouteRequest(const char *s, T t, mach_vm_address_t &o) :
+ symbol(s), to(reinterpret_cast(t)), org(&o) { }
+
+ /**
+ * Construct RouteRequest for routing a function
+ * @param s symbol to lookup
+ * @param t destination address
+ */
+ template
+ RouteRequest(const char *s, T t) :
+ symbol(s), to(reinterpret_cast(t)) { }
+ };
+
+ /**
+ * Simple route multiple functions with basic error handling
+ *
+ * @param id kernel item identifier
+ * @param requests an array of requests to replace
+ * @param num requests array size
+ * @param start start address range
+ * @param size address range size
+ * @param kernelRoute kernel change requiring memory protection changes and patch reverting at unload
+ * @param force continue on first error
+ *
+ * @return false if it at least one error happened
+ */
+ EXPORT bool routeMultiple(size_t id, RouteRequest *requests, size_t num, mach_vm_address_t start=0, size_t size=0, bool kernelRoute=true, bool force=false);
+
+ /**
+ * Simple route multiple functions with basic error handling
+ *
+ * @param id kernel item identifier
+ * @param requests an array of requests to replace
+ * @param start start address range
+ * @param size address range size
+ * @param kernelRoute kernel change requiring memory protection changes and patch reverting at unload
+ * @param force continue on first error
+ *
+ * @return false if it at least one error happened
+ */
+ template
+ inline bool routeMultiple(size_t id, RouteRequest (&requests)[N], mach_vm_address_t start=0, size_t size=0, bool kernelRoute=true, bool force=false) {
+ return routeMultiple(id, requests, N, start, size, kernelRoute, force);
+ }
+
private:
/**
@@ -253,7 +421,7 @@ class KernelPatcher {
/**
* Offset to tempExecutableMemory that is safe to use
*/
- off_t tempExecutableMemoryOff {0};
+ size_t tempExecutableMemoryOff {0};
/**
* Patcher status
@@ -299,9 +467,9 @@ class KernelPatcher {
#endif /* LILU_KEXTPATCH_SUPPORT */
/**
- * Local disassmebler instance, initialised on demand
+ * Kernel prelink image in case prelink is used
*/
- Disassembler disasm;
+ MachInfo *prelinkInfo {nullptr};
/**
* Loaded kernel items
@@ -341,26 +509,28 @@ class KernelPatcher {
* Jump instruction sizes
*/
static constexpr size_t SmallJump {1 + sizeof(int32_t)};
- static constexpr size_t LongJump {2 * sizeof(uint64_t)};
+ static constexpr size_t LongJump {6 + sizeof(uint64_t)};
/**
* Possible kernel paths
*/
#ifdef LILU_COMPRESSION_SUPPORT
- static constexpr size_t kernelPathsNum {6};
-#else
- static constexpr size_t kernelPathsNum {4};
-#endif /* LILU_COMPRESSION_SUPPORT */
- const char *kernelPaths[kernelPathsNum] {
- "/mach_kernel",
- "/System/Library/Kernels/kernel", //since 10.10
- "/System/Library/Kernels/kernel.debug",
- "/System/Library/Kernels/kernel.development",
-#ifdef LILU_COMPRESSION_SUPPORT
+ const char *prelinkKernelPaths[6] {
+ // This is the usual kernel cache place, which often the best thing to use
"/System/Library/Caches/com.apple.kext.caches/Startup/kernelcache",
- "/System/Library/PrelinkedKernels/prelinkedkernel"
-#endif /* LILU_COMPRESSION_SUPPORT */
-
+ // Otherwise fallback to one of the prelinked kernels
+ // Since we always verify the LC_UUID value, trying the kernels could be done in any order.
+ "/System/Library/PrelinkedKernels/prelinkedkernel", // normal
+ "/macOS Install Data/Locked Files/Boot Files/prelinkedkernel", // 10.13 installer
+ "/com.apple.boot.R/prelinkedkernel", // 10.12+ fusion drive installer
+ "/com.apple.boot.S/System/Library/PrelinkedKernels/prelinkedkernel", // 10.11 fusion drive installer
+ "/com.apple.recovery.boot/prelinkedkernel" // recovery
+ };
+#endif
+
+ const char *kernelPaths[2] {
+ "/System/Library/Kernels/kernel", //since 10.10
+ "/mach_kernel"
};
};
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_policy.hpp b/Lilu.kext/Contents/Resources/Headers/kern_policy.hpp
index ec17f3d..6f61320 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_policy.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_policy.hpp
@@ -34,7 +34,7 @@ class Policy {
* @param conf policy configuration
*/
static void dummyPolicyInitBSD(mac_policy_conf *conf) {
- DBGLOG("policy @ init bsd");
+ DBGLOG("policy", "init bsd");
}
/**
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_rtc.hpp b/Lilu.kext/Contents/Resources/Headers/kern_rtc.hpp
new file mode 100644
index 0000000..c4bd831
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_rtc.hpp
@@ -0,0 +1,229 @@
+//
+// kern_rtc.hpp
+// Lilu
+//
+// Copyright © 2018 vit9696. All rights reserved.
+//
+
+#ifndef kern_rtc_h
+#define kern_rtc_h
+
+#include
+#include
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#include
+#pragma clang diagnostic pop
+
+class RTCStorage {
+ /**
+ * General access RTC ports on x86 systems.
+ */
+ static constexpr uint8_t R_PCH_RTC_INDEX = 0x70;
+ static constexpr uint8_t R_PCH_RTC_TARGET = 0x71;
+ static constexpr uint8_t R_PCH_RTC_EXT_INDEX = 0x72;
+ static constexpr uint8_t R_PCH_RTC_EXT_TARGET = 0x73;
+
+ /**
+ * RTC has N banks (we support up to 2) of memory.
+ */
+ static constexpr uint8_t RTC_BANK_SIZE = 0x80;
+
+ /**
+ * Non-ext RTC index register uses higher bit for nmi.
+ */
+ static constexpr uint8_t RTC_DATA_MASK = 0x7F;
+ static constexpr uint8_t RTC_NMI_MASK = 0x80;
+
+ /**
+ * Apple-specific RTC checksum addresses
+ */
+ static constexpr uint8_t APPLERTC_HASHED_ADDR = 0x0E;
+ static constexpr uint8_t APPLERTC_CHECKSUM_ADDR1 = 0x58;
+ static constexpr uint8_t APPLERTC_CHECKSUM_ADDR2 = 0x59;
+
+ /**
+ * AppleRTC service handle
+ */
+ IOService *rtcSrv {nullptr};
+
+ /**
+ * Low-level RTC read (does not check memory availability).
+ *
+ * @param dev RTC ACPI device
+ * @param offset offset
+ *
+ * @result read value
+ */
+ static uint8_t readByte(IOACPIPlatformDevice *dev, uint8_t offset);
+
+ /**
+ * Low-level RTC write (does not check memory availability).
+ *
+ * @param dev RTC ACPI device
+ * @param offset offset
+ * @param value value
+ */
+ static void writeByte(IOACPIPlatformDevice *dev, uint8_t offset, uint8_t value);
+public:
+ /**
+ * Attempt to connect to active RTC service
+ *
+ * @param wait wait for service availability
+ *
+ * @return true on success
+ */
+ EXPORT bool init(bool wait=true);
+
+ /**
+ * Release obtained RTC service
+ */
+ EXPORT void deinit();
+
+ /**
+ * Check whether extended (higher 128 bytes) is available
+ *
+ * @return true on success
+ */
+ EXPORT bool checkExtendedMemory();
+
+ /**
+ * Read memory from RTC
+ *
+ * @param off offset to read data from
+ * @param size data size
+ * @param buffer data buffer to read to
+ *
+ * @return true on success
+ */
+ EXPORT bool read(uint64_t off, uint32_t size, uint8_t *buffer);
+
+ /**
+ * Write memory to RTC
+ *
+ * @param off offset to write data to
+ * @param size data size
+ * @param buffer data buffer to write from
+ *
+ * @return true on success
+ */
+ EXPORT bool write(uint64_t off, uint32_t size, uint8_t *buffer);
+
+ /**
+ * Obtain RTC device for direct writing.
+ * Written as inline to avoid IOACPIPlatformDevice dependency.
+ *
+ * @param name device name
+ *
+ * @return RTC ACPI device for I/O access, must be released
+ */
+ static inline IOACPIPlatformDevice *getRTCDevice(const char *name = "PNP0B00") {
+ IOService *rtcDev = nullptr;
+ auto matching = IOService::nameMatching(name);
+ if (matching) {
+ rtcDev = IOService::waitForMatchingService(matching);
+ matching->release();
+ } else {
+ SYSLOG("rtc", "failed to allocate rtc device matching");
+ }
+
+ if (rtcDev) {
+ DBGLOG("rtc", "got rtc device");
+ auto acpiDev = OSDynamicCast(IOACPIPlatformDevice, rtcDev);
+ if (acpiDev) {
+ DBGLOG("rtc", "got rtc acpi device");
+ return acpiDev;
+ } else {
+ SYSLOG("rtc", "failed to obtain rtc acpi device");
+ rtcDev->release();
+ }
+ }
+
+ SYSLOG("rtc", "failed to get rtc device");
+ return nullptr;
+ }
+
+ /**
+ * Directly read RTC memory (UNSAFE, usage with caution!)
+ *
+ * @param dev RTC device
+ * @param off offset to read data from
+ * @param size data size
+ * @param buffer data buffer to read to
+ * @param introff turn interrupts off
+ *
+ * @return true on success
+ */
+ EXPORT static void readDirect(IOACPIPlatformDevice *dev, uint8_t off, uint16_t size, uint8_t *buffer, bool introff);
+
+ /**
+ * Directly write RTC memory (UNSAFE, usage with caution!)
+ *
+ * @param dev RTC device
+ * @param off offset to read data from
+ * @param size data size
+ * @param buffer data buffer to read to
+ * @param updatecrc recalculate crc on write
+ * @param introff turn interrupts off
+ *
+ * @return true on success
+ */
+ EXPORT static void writeDirect(IOACPIPlatformDevice *dev, uint8_t off, uint16_t size, uint8_t *buffer, bool updatecrc, bool introff);
+
+
+ /**
+ * Directly read RTC memory (UNSAFE, usage with caution!), this is just a compatibility function.
+ *
+ * @param off offset to read data from
+ * @param size data size
+ * @param buffer data buffer to read to
+ * @param introff turn interrupts off
+ *
+ * @return true on success
+ */
+ static inline bool readDirect(uint8_t off, uint16_t size, uint8_t *buffer, bool introff) {
+ if (size > RTC_BANK_SIZE*2 - off) {
+ SYSLOG("rtc", "reading unsupported size");
+ return false;
+ }
+
+ auto rtc = getRTCDevice();
+ if (rtc) {
+ readDirect(rtc, off, size, buffer, introff);
+ rtc->release();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Directly write RTC memory (UNSAFE, usage with caution!), this is just a compatibility function.
+ *
+ * @param off offset to read data from
+ * @param size data size
+ * @param buffer data buffer to read to
+ * @param updatecrc recalculate crc on write
+ * @param introff turn interrupts off
+ *
+ * @return true on success
+ */
+ static inline bool writeDirect(uint8_t off, uint16_t size, uint8_t *buffer, bool updatecrc, bool introff) {
+ if (size > RTC_BANK_SIZE*2 - off) {
+ SYSLOG("rtc", "writing unsupported size");
+ return false;
+ }
+
+ auto rtc = getRTCDevice();
+ if (rtc) {
+ writeDirect(rtc, off, size, buffer, updatecrc, introff);
+ rtc->release();
+ return true;
+ }
+
+ return false;
+ }
+};
+
+#endif /* kern_rtc_h */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_time.hpp b/Lilu.kext/Contents/Resources/Headers/kern_time.hpp
new file mode 100644
index 0000000..41d2f91
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Headers/kern_time.hpp
@@ -0,0 +1,135 @@
+//
+// kern_time.hpp
+// Lilu
+//
+// Copyright © 2018 vit9696. All rights reserved.
+//
+
+#ifndef kern_time_hpp
+#define kern_time_hpp
+
+#include
+
+/**
+ * Obtain current system time in nanoseconds
+ *
+ * @return current time
+ */
+inline uint64_t getCurrentTimeNs() {
+ uint64_t currt = 0;
+ absolutetime_to_nanoseconds(mach_absolute_time(), &currt);
+ return currt;
+}
+
+/**
+ * Obtain current calendar system time in nanoseconds
+ *
+ * @return current time
+ */
+inline uint64_t getCalendarTimeNs() {
+ clock_sec_t sc;
+ clock_nsec_t ns;
+ clock_get_calendar_nanotime(&sc, &ns);
+ return static_cast(sc) * NSEC_PER_SEC + ns;
+}
+
+/**
+ * Obtain time passed since some timestamp in nanoseconds
+ *
+ * @param start starting timestamp
+ * @param current timestamp to check against (pass 0 for current time)
+ *
+ * @return delta or 0 (if current time equals or precedeces the start)
+ */
+inline uint64_t getTimeSinceNs(uint64_t start, uint64_t current = 0) {
+ if (current == 0)
+ current = getCurrentTimeNs();
+ if (current > start)
+ return current - start;
+ return 0;
+}
+
+/**
+ * Obtain time left till a timestamp in the future in nanoseconds
+ *
+ * @param start starting timestamp
+ * @param timeout timeout for the event
+ * @param current timestamp to check against (pass 0 for current time)
+ *
+ * @return delta or 0 (if the timeout is over)
+ */
+inline uint64_t getTimeLeftNs(uint64_t start, uint64_t timeout, uint64_t current = 0) {
+ if (current == 0)
+ current = getCurrentTimeNs();
+ if (start + timeout > current)
+ return start + timeout - current;
+ return 0;
+}
+
+/**
+ * Convert from nanoseconds to milliseconds
+ *
+ * @param t timestamp in ns
+ *
+ * @return timestamp in ms
+ */
+constexpr uint64_t convertNsToMs(uint64_t t) {
+ return t / 1000000;
+}
+
+/**
+ * Convert from nanoseconds to seconds
+ *
+ * @param t timestamp in ns
+ *
+ * @return timestamp in s
+ */
+constexpr uint64_t convertNsToSc(uint64_t t) {
+ return t / 1000000000;
+}
+
+/**
+ * Convert from milliseconds to seconds
+ *
+ * @param t timestamp in ms
+ *
+ * @return timestamp in s
+ */
+constexpr uint64_t convertMsToSc(uint64_t t) {
+ return t / 1000;
+}
+
+/**
+ * Convert from milliseconds to nanoseconds
+ *
+ * @param t timestamp in ms
+ *
+ * @return timestamp in ns
+ */
+constexpr uint64_t convertMsToNs(uint64_t t) {
+ return t * 1000000;
+}
+
+/**
+ * Convert from seconds to nanoseconds
+ *
+ * @param t timestamp in s
+ *
+ * @return timestamp in ns
+ */
+constexpr uint64_t convertScToNs(uint64_t t) {
+ return t * 1000000000;
+}
+
+/**
+ * Convert from seconds to milliseconds
+ *
+ * @param t timestamp in s
+ *
+ * @return timestamp in ms
+ */
+constexpr uint64_t convertScToMs(uint64_t t) {
+ return t * 1000;
+}
+
+#endif /* kern_time_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_user.hpp b/Lilu.kext/Contents/Resources/Headers/kern_user.hpp
index 0816828..26df5a0 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_user.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_user.hpp
@@ -114,14 +114,31 @@ class UserPatcher {
vm_address_t startDATA;
vm_address_t endDATA;
};
-
+
/**
* Structure describing relevant processes run
*/
struct ProcInfo {
- const char *path;
- uint32_t len;
- uint32_t section;
+ /**
+ * Process matching flags
+ */
+ enum ProcFlags {
+ MatchExact = 0,
+ MatchAny = 1,
+ MatchPrefix = 2,
+ MatchSuffix = 4,
+ MatchMask = MatchExact | MatchAny | MatchPrefix | MatchSuffix
+ };
+
+ /**
+ * Unused (aka disabled) proc info section
+ */
+ static constexpr uint32_t SectionDisabled {0};
+
+ const char *path {nullptr};
+ uint32_t len {0};
+ uint32_t section {SectionDisabled};
+ uint32_t flags {MatchExact};
};
/**
@@ -146,7 +163,51 @@ class UserPatcher {
* @param user pointer that will be passed to the callback function
*/
bool registerPatches(ProcInfo **procs, size_t procNum, BinaryModInfo **mods, size_t modNum, t_BinaryLoaded callback, void *user);
-
+
+ /**
+ * Reads current process header
+ *
+ * @param map vm map
+ * @param header Mach-O header
+ *
+ * @return false on failure
+ */
+ EXPORT bool getTaskHeader(vm_map_t map, mach_header_64 &header);
+
+ /**
+ * Disables dyld_shared_cache for the current process
+ *
+ * @param map vm map
+ *
+ * @return false on mach image failure
+ */
+ EXPORT bool injectRestrict(vm_map_t map);
+
+ /**
+ * Injects payload into the process right after the header with EP replacement.
+ *
+ * @param map vm map
+ * @param payload code
+ * @param size code size (up to PAGE_SIZE)
+ * @param ep original entrypoint (may be written to code before copying)
+ *
+ * @return false on mach image failure
+ */
+ EXPORT bool injectPayload(vm_map_t map, uint8_t *payload, size_t size, void *ep=nullptr);
+
+ /**
+ * Allocates a new segment in the process.
+ *
+ * @param map vm map
+ * @param addr allocation address (e.g. a little below SHARED_REGION_BASE_X86_64)
+ * @param payload code
+ * @param size code size (must be PAGE_SIZE-aligned)
+ * @param prot segment protection
+ *
+ * @return allocated address or 0 on failure
+ */
+ EXPORT vm_address_t injectSegment(vm_map_t taskPort, vm_address_t addr, uint8_t *payload, size_t size, vm_prot_t prot);
+
/**
* Activates monitoring functions if necessary
*/
@@ -163,6 +224,7 @@ class UserPatcher {
using t_codeSignValidateRangeWrapper = boolean_t (*)(void *, memory_object_t, memory_object_offset_t, const void *, memory_object_size_t, unsigned *);
using t_vmSharedRegionMapFile = kern_return_t (*)(vm_shared_region_t, unsigned int, shared_file_mapping_np *, memory_object_control_t, memory_object_size_t, void *, uint32_t, user_addr_t slide_start, user_addr_t);
using t_vmSharedRegionSlide = int (*)(uint32_t, mach_vm_offset_t, mach_vm_size_t, mach_vm_offset_t, mach_vm_size_t, memory_object_control_t);
+ using t_vmSharedRegionSlideMojave = int (*)(uint32_t, mach_vm_offset_t, mach_vm_size_t, mach_vm_offset_t, mach_vm_size_t, mach_vm_offset_t, memory_object_control_t);
using t_currentMap = vm_map_t (*)(void);
using t_getTaskMap = vm_map_t (*)(task_t);
using t_getMapMin = vm_map_offset_t (*)(vm_map_t);
@@ -178,6 +240,7 @@ class UserPatcher {
t_codeSignValidateRangeWrapper orgCodeSignValidateRangeWrapper {nullptr};
t_vmSharedRegionMapFile orgVmSharedRegionMapFile {nullptr};
t_vmSharedRegionSlide orgVmSharedRegionSlide {nullptr};
+ t_vmSharedRegionSlideMojave orgVmSharedRegionSlideMojave {nullptr};
t_currentMap orgCurrentMap {nullptr};
t_getMapMin orgGetMapMin {nullptr};
t_getTaskMap orgGetTaskMap {nullptr};
@@ -196,6 +259,7 @@ class UserPatcher {
static kern_return_t vmSharedRegionMapFile(vm_shared_region_t shared_region, unsigned int mappings_count, shared_file_mapping_np *mappings, memory_object_control_t file_control, memory_object_size_t file_size, void *root_dir, uint32_t slide, user_addr_t slide_start, user_addr_t slide_size);
static void execsigs(proc_t p, thread_t thread);
static int vmSharedRegionSlide(uint32_t slide, mach_vm_offset_t entry_start_address, mach_vm_size_t entry_size, mach_vm_offset_t slide_start, mach_vm_size_t slide_size, memory_object_control_t sr_file_control);
+ static int vmSharedRegionSlideMojave(uint32_t slide, mach_vm_offset_t entry_start_address, mach_vm_size_t entry_size, mach_vm_offset_t slide_start, mach_vm_size_t slide_size, mach_vm_offset_t slid_mapping, memory_object_control_t sr_file_control);
static proc_t procExecSwitchTask(proc_t p, task_t current_task, task_t new_task, thread_t new_thread);
/**
@@ -293,7 +357,7 @@ class UserPatcher {
/**
* Provided global callback for on proc invocation
*/
- ppair userCallback;
+ ppair userCallback {};
/**
* Applies dyld shared cache patches
@@ -351,7 +415,7 @@ class UserPatcher {
};
struct Lookup {
- uint32_t offs[4];
+ uint32_t offs[4] {};
static constexpr size_t matchNum {4};
evector c[matchNum];
};
@@ -367,7 +431,7 @@ class UserPatcher {
sizeof(segment_command_64),
"__RESTRICT",
SHARED_REGION_BASE_X86_64,
- 1
+ 1, 0, 0, 0, 0, 0, 0
};
/**
@@ -378,14 +442,14 @@ class UserPatcher {
sizeof(segment_command),
"__RESTRICT",
SHARED_REGION_BASE_I386,
- 1
+ 1, 0, 0, 0, 0, 0, 0
};
/**
- * Temporary header for reading data
+ * Temporary buffer for reading image data
*/
- mach_header_64 tmpHeader;
-
+ uint8_t tmpBufferData[PAGE_SIZE*3] {};
+
/**
* Kernel auth listener handle
*/
@@ -399,7 +463,7 @@ class UserPatcher {
/**
* Validation cookie
*/
- void *cookie = {reinterpret_cast(0xB16B00B5)};
+ void *cookie {nullptr};
/**
* Exec callback
@@ -451,16 +515,7 @@ class UserPatcher {
* @return true on success
*/
bool hookMemoryAccess();
-
- /**
- * Disables dyld_shared_cache for the current process
- *
- * @param map vm map
- *
- * @return false on mach image failure
- */
- bool injectRestrict(vm_map_t map);
-
+
/**
* Peforms the actual binary patching
*
@@ -471,13 +526,14 @@ class UserPatcher {
void patchBinary(vm_map_t map, const char *path, uint32_t len);
/**
- * Possible dyld shared cache map paths
+ * Dyld shared cache map path for 10.10+ on Haswell
*/
- static constexpr size_t sharedCacheMapPathsNum {2};
- const char *sharedCacheMap[sharedCacheMapPathsNum] {
- "/private/var/db/dyld/dyld_shared_cache_x86_64h.map", //since 10.10
- "/private/var/db/dyld/dyld_shared_cache_x86_64.map"
- };
+ static constexpr const char *SharedCacheMapHaswell {"/private/var/db/dyld/dyld_shared_cache_x86_64h.map"};
+
+ /**
+ * Dyld shared cache map path for all other systems and older CPUs
+ */
+ static constexpr const char *SharedCacheMapLegacy {"/private/var/db/dyld/dyld_shared_cache_x86_64.map"};
};
diff --git a/Lilu.kext/Contents/Resources/Headers/kern_util.hpp b/Lilu.kext/Contents/Resources/Headers/kern_util.hpp
index ddc64bb..727f086 100644
--- a/Lilu.kext/Contents/Resources/Headers/kern_util.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/kern_util.hpp
@@ -9,10 +9,13 @@
#define kern_util_hpp
#include
+#include
#include
+#include
#include
#include
+#include
#include
#define xStringify(a) Stringify(a)
@@ -21,30 +24,212 @@
#define xConcat(a, b) Concat(a, b)
#define Concat(a, b) a ## b
+/**
+ * Prefix name with your plugin name (to ease symbolication and avoid conflicts)
+ */
#define ADDPR(a) xConcat(xConcat(PRODUCT_NAME, _), a)
+/**
+ * Debugging state exported for your plugin
+ */
extern bool ADDPR(debugEnabled);
-// Kernel version major
+
+/**
+ * Debugging print delay used as an ugly hack around printf bufferisation,
+ * which results in messages not appearing in the boot log.
+ * Use liludelay=1000 (1 second) boot-arg to put a second after each message.
+ */
+extern uint32_t ADDPR(debugPrintDelay);
+
+/**
+ * Kernel version major
+ */
extern const int version_major;
-// Kernel version minor
+
+/**
+ * Kernel version minor
+ */
extern const int version_minor;
-// Kernel map
+
+/**
+ * Kernel map
+ */
extern vm_map_t kernel_map;
-#define SYSLOG(str, ...) IOLog( xStringify(PRODUCT_NAME) ": " str "\n", ## __VA_ARGS__)
+/**
+ * Kernel proc
+ */
+extern proc_t kernproc;
+
+/**
+ * For noreturn failures
+ */
+#define UNREACHABLE() do { __builtin_unreachable(); } while (0)
+
+/**
+ * Conditional logging to system log prefixed with you plugin name
+ *
+ * @param cond precondition
+ * @param str printf-like string
+ */
+#define SYSLOG_COND(cond, module, str, ...) \
+ do { \
+ if (cond) { \
+ IOLog( "%s%10s" str "\n", xStringify(PRODUCT_NAME) ": ", module " @ ", ## __VA_ARGS__); \
+ if (ADDPR(debugPrintDelay) > 0) IOSleep(ADDPR(debugPrintDelay)); \
+ } \
+ } while (0)
+
+/**
+ * Write to system log prefixed with you plugin name
+ *
+ * @param module log module
+ * @param str printf-like string
+ */
+#define SYSLOG(module, str, ...) SYSLOG_COND(true, module, str, ## __VA_ARGS__)
+
+/**
+ * Conditional tracing to system log prefixed with you plugin name
+ *
+ * @param cond precondition
+ * @param module log module
+ * @param str printf-like string
+ */
+#define SYSTRACE_COND(cond, module, str, ...) \
+ do { \
+ if (cond) { \
+ SYSLOG(module, str, ## __VA_ARGS__); \
+ OSReportWithBacktrace( "%s%10s" str "\n", xStringify(PRODUCT_NAME) ": ", module " @ ", ## __VA_ARGS__); \
+ } \
+ } while (0)
+
+/**
+ * Write call trace to system log prefixed with you plugin name
+ *
+ * @param module log module
+ * @param str printf-like string
+ */
+#define SYSTRACE(module, str, ...) SYSTRACE_COND(true, module, str, ## __VA_ARGS__)
+
+/**
+ * Conditional panic prefixed with you plugin name
+ *
+ * @param cond precondition
+ * @param module log module
+ * @param str printf-like string
+ */
+#define PANIC_COND(cond, module, str, ...) \
+ do { \
+ if (cond) { \
+ (panic)( "%s%10s" str "\n", xStringify(PRODUCT_NAME) ": ", module " @ ", ## __VA_ARGS__); \
+ UNREACHABLE(); \
+ } \
+ } while (0)
+
+/**
+ * Cause immediate kernel panic prefixed with you plugin name
+ *
+ * @param module log module
+ * @param str printf-like string
+ */
+#define PANIC(module, str, ...) PANIC_COND(true, module, str, ## __VA_ARGS__)
#ifdef DEBUG
-#define DBGLOG(str, ...) \
- do { \
- if (ADDPR(debugEnabled)) \
- SYSLOG( "(DEBUG) " str, ## __VA_ARGS__); \
- } while(0)
-#else
-#define DBGLOG(str, ...) do { } while(0)
+
+/**
+ * Conditional debug logging to system log prefixed with you plugin name
+ *
+ * @param cond precondition
+ * @param module log module
+ * @param str printf-like string
+ */
+#define DBGLOG_COND(cond, module, str, ...) \
+ do { \
+ SYSLOG_COND(ADDPR(debugEnabled) && (cond), module, "%s" str, "(DBG) ", ## __VA_ARGS__); \
+ } while (0)
+
+/**
+ * Write debug message to system log prefixed with you plugin name
+ *
+ * @param module log module
+ * @param str printf-like string
+ */
+#define DBGLOG(module, str, ...) DBGLOG_COND(true, module, str, ## __VA_ARGS__)
+
+/**
+ * Conditional debug tracing to system log prefixed with you plugin name
+ *
+ * @param cond precondition
+ * @param module log module
+ * @param str printf-like string
+ */
+#define DBGTRACE_COND(cond, module, str, ...) \
+ do { \
+ SYSTRACE_COND(ADDPR(debugEnabled) && (cond), module, "%s" str, "(DBG) ", ## __VA_ARGS__); \
+ } while (0)
+
+/**
+ * Write debug call trace to system log prefixed with you plugin name
+ *
+ * @param module log module
+ * @param str printf-like string
+ */
+#define DBGTRACE(module, str, ...) DBGTRACE_COND(true, module, str, ## __VA_ARGS__)
+
+#else /* DEBUG */
+
+#define DBGLOG_COND(module, str, ...) do { } while (0)
+#define DBGLOG(module, str, ...) do { } while (0)
+#define DBGTRACE_COND(module, str, ...) do { } while (0)
+#define DBGTRACE(module, str, ...) do { } while (0)
+
#endif
+/**
+ * Deprecate the interface
+ */
+#define DEPRECATE(x) __attribute__((deprecated(x)))
+
+/**
+ * Macros to bypass kernel address printing protection
+ */
+#define PRIKADDR "0x%08X%08X"
+#define CASTKADDR(x) \
+ static_cast(reinterpret_cast(x) >> 32), \
+ static_cast(reinterpret_cast(x))
+
+/**
+ * Macros to print the UUID
+ */
+#define PRIUUID "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X"
+#define CASTUUID(uuid) \
+ reinterpret_cast(uuid)[0], \
+ reinterpret_cast(uuid)[1], \
+ reinterpret_cast(uuid)[2], \
+ reinterpret_cast(uuid)[3], \
+ reinterpret_cast(uuid)[4], \
+ reinterpret_cast(uuid)[5], \
+ reinterpret_cast(uuid)[6], \
+ reinterpret_cast(uuid)[7], \
+ reinterpret_cast(uuid)[8], \
+ reinterpret_cast(uuid)[9], \
+ reinterpret_cast(uuid)[10], \
+ reinterpret_cast(uuid)[11], \
+ reinterpret_cast(uuid)[12], \
+ reinterpret_cast(uuid)[13], \
+ reinterpret_cast(uuid)[14], \
+ reinterpret_cast(uuid)[15]
+
+/**
+ * Export function or symbol for linking
+ */
#define EXPORT __attribute__((visibility("default")))
+/**
+ * Remove padding between fields
+ */
+#define PACKED __attribute__((packed))
+
/**
* Two-way substring search
*
@@ -66,6 +251,16 @@ EXPORT const char *strstr(const char *stack, const char *needle, size_t len=0);
*/
EXPORT char *strrchr(const char *stack, int ch);
+/**
+ * XNU kernel implementation of a C-standard qsort function normally not exported by the kernel.
+ *
+ * @param a array to sort
+ * @param n array length
+ * @param es array element size
+ * @param cmp array element comparator
+ */
+EXPORT void qsort(void *a, size_t n, size_t es, int (*cmp)(const void *, const void *));
+
/**
* Count array elements
*
@@ -85,22 +280,24 @@ extern "C" {
void *kern_os_malloc(size_t size);
void *kern_os_calloc(size_t num, size_t size);
void kern_os_free(void *addr);
- void kern_os_cfree(void *addr);
void *kern_os_realloc(void *addr, size_t nsize);
+ // kern_os_free does not check its argument for nullptr
+ EXPORT void lilu_os_free(void *addr);
}
/**
* Known kernel versions
*/
enum KernelVersion {
- SnowLeopard = 10,
- Lion = 11,
- MountainLion = 12,
- Mavericks = 13,
- Yosemite = 14,
- ElCapitan = 15,
- Sierra = 16,
- HighSierra = 17
+ SnowLeopard = 10,
+ Lion = 11,
+ MountainLion = 12,
+ Mavericks = 13,
+ Yosemite = 14,
+ ElCapitan = 15,
+ Sierra = 16,
+ HighSierra = 17,
+ Mojave = 18,
};
/**
@@ -126,6 +323,18 @@ inline KernelMinorVersion getKernelMinorVersion() {
return static_cast(version_minor);
}
+/**
+ * Check whether kernel boot argument is passed ignoring the value (e.g. -arg or arg).
+ *
+ * @param name argument name
+ *
+ * @return true if argument was passed
+ */
+inline bool checkKernelArgument(const char *name) {
+ int val[16];
+ return PE_parse_boot_argn(name, val, sizeof(val));
+}
+
/**
* Parse apple version at compile time
*
@@ -137,18 +346,149 @@ constexpr size_t parseModuleVersion(const char *version) {
return (version[0] - '0') * 100 + (version[2] - '0') * 10 + (version[4] - '0');
}
+/**
+ * Access struct member by its offset
+ *
+ * @param T pointer to the field you need
+ * @param that pointer to struct
+ * @param off offset in bytes to the member
+ *
+ * @return reference to the struct member
+ */
+template
+inline T &getMember(void *that, size_t off) {
+ return *reinterpret_cast(static_cast(that) + off);
+}
+
+/**
+ * Align value by align (page size by default)
+ *
+ * @param size value
+ *
+ * @return algined value
+ */
+template
+inline T alignValue(T size, T align = 4096) {
+ return (size + align - 1) & (~(align - 1));
+}
+
+/**
+ * Obtain bit value of size sizeof(T)
+ * Warning, you are suggested to always pass the type explicitly!
+ *
+ * @param n bit no
+ *
+ * @return bit value
+ */
+template
+constexpr T getBit(T n) {
+ return static_cast(1U) << n;
+}
+
+/**
+ * Obtain bit mask of size sizeof(T)
+ * Warning, you are suggested to always pass the type explicitly!
+ *
+ * @param hi starting high bit
+ * @param lo ending low bit
+ *
+ * @return bit mask
+ */
+template
+constexpr T getBitMask(T hi, T lo) {
+ return (getBit(hi)|(getBit(hi)-1U)) & ~(getBit(lo)-1U);
+}
+
+/**
+ * Obtain bit field of size sizeof(T)
+ * Warning, you are suggested to always pass the type explicitly!
+ *
+ * @param so source
+ * @param hi starting high bit
+ * @param lo ending low bit
+ *
+ * @return bit field value
+ */
+template
+constexpr T getBitField(T so, T hi, T lo) {
+ return (so & getBitMask(hi, lo)) >> lo;
+}
+
+/**
+ * Set bit field of size sizeof(T)
+ * Warning, you are suggested to always pass the type explicitly!
+ *
+ * @param va value
+ * @param hi starting high bit
+ * @param lo ending low bit
+ *
+ * @return bit field value
+ */
+template
+constexpr T setBitField(T so, T hi, T lo) {
+ return (so << lo) & getBitMask(hi, lo);
+}
+
+/**
+ * This is an ugly replacement to std::find_if, allowing you
+ * to check whether a container consists only of value values.
+ *
+ * @param in container
+ * @param size container size
+ * @param value value to look for
+ *
+ * @return true if an element different from value was found
+ */
+template
+inline bool findNotEquals(T &in, size_t size, Y value) {
+ for (size_t i = 0; i < size; i++)
+ if (in[i] != value)
+ return true;
+ return false;
+}
+
+/**
+ * Returns non-null string when they can be null
+ *
+ * @param str original string
+ *
+ * @return non-null string
+ */
+inline const char *safeString(const char *str) {
+ return str ? str : "(null)";
+}
+
+/**
+ * A shorter form of writing reinterpret_cast(ptr)
+ */
+template
+inline T FunctionCast(T org, mach_vm_address_t ptr) {
+ return reinterpret_cast(ptr);
+}
+
/**
* Typed buffer allocator
*/
namespace Buffer {
template
- T *create(size_t size) {
- return new T[size];
+ inline T *create(size_t size) {
+ return static_cast(kern_os_malloc(sizeof(T) * size));
}
template
- void deleter(T *buf) {
- delete[] buf;
+ inline bool resize(T *&buf, size_t size) {
+ auto nbuf = static_cast(kern_os_realloc(buf, sizeof(T) * size));
+ if (nbuf) {
+ buf = nbuf;
+ return true;
+ }
+
+ return false;
+ }
+
+ template
+ inline void deleter(T *buf) {
+ lilu_os_free(buf);
}
}
@@ -217,6 +557,7 @@ struct ppair {
/**
* Embedded vector-like container
* You muse call deinit before destruction
+ * Ugh, someone, please, port libc++ to XNU...
*
* @param T held type
* @param deleter type destructor
@@ -225,13 +566,14 @@ template >
class evector {
T *ptr {nullptr};
size_t cnt {0};
+ size_t rsvd {0};
public:
/**
* Return evector size
*
* @return element count
*/
- const size_t size() const {
+ size_t size() const {
return cnt;
}
@@ -250,7 +592,7 @@ class evector {
*
* @return element id
*/
- const size_t last() const {
+ size_t last() const {
return cnt-1;
}
@@ -276,6 +618,27 @@ class evector {
return ptr[index];
}
+ /**
+ * Reserve memory for at least N elements
+ *
+ * @param num amount of elements
+ *
+ * @return elements ptr or null
+ */
+ T *reserve(size_t num) {
+ if (rsvd < num) {
+ T *nPtr = static_cast(kern_os_realloc(ptr, num * sizeof(T)));
+ if (nPtr) {
+ ptr = nPtr;
+ rsvd = num;
+ } else {
+ return nullptr;
+ }
+ }
+
+ return ptr;
+ }
+
/**
* Erase evector element
*
@@ -283,23 +646,15 @@ class evector {
*
* @return true on success
*/
- bool erase(size_t index) {
- // Free the memory
+ bool erase(size_t index, bool free=true) {
deleter(ptr[index]);
- // Shift the items
- for (size_t i = index+1; i < cnt; i++) ptr[i-1] = ptr[i];
- // Reduce the memory used
- cnt--;
- if (cnt == 0) {
+ if (--cnt != index)
+ lilu_os_memmove(&ptr[index], &ptr[index + 1], (cnt - index) * sizeof(T));
+
+ if (free && cnt == 0) {
kern_os_free(ptr);
ptr = nullptr;
- } else {
- T *nPtr = static_cast(kern_os_realloc(ptr, (cnt)*sizeof(T)));
- if (nPtr) {
- ptr = nPtr;
- } else {
- return false;
- }
+ rsvd = 0;
}
return true;
@@ -313,15 +668,13 @@ class evector {
* @return true on success
*/
bool push_back(T &element) {
- T *nPtr = static_cast(kern_os_realloc(ptr, (cnt+1)*sizeof(T)));
- if (nPtr) {
- ptr = nPtr;
+ if (reserve(cnt+1)) {
ptr[cnt] = element;
cnt++;
return true;
}
- SYSLOG("evector @ insertion failure");
+ SYSLOG("evector", "insertion failure");
return false;
}
@@ -333,15 +686,13 @@ class evector {
* @return true on success
*/
bool push_back(T &&element) {
- T *nPtr = static_cast(kern_os_realloc(ptr, (cnt+1)*sizeof(T)));
- if (nPtr) {
- ptr = nPtr;
+ if (reserve(cnt+1)) {
ptr[cnt] = element;
cnt++;
return true;
}
- SYSLOG("evector @ insertion failure");
+ SYSLOG("evector", "insertion failure");
return false;
}
@@ -354,14 +705,64 @@ class evector {
*/
void deinit() {
if (ptr) {
- for (size_t i = 0; i < cnt; i++) {
+ for (size_t i = 0; i < cnt; i++)
deleter(ptr[i]);
- }
kern_os_free(ptr);
ptr = nullptr;
- cnt = 0;
+ cnt = rsvd = 0;
}
}
};
+/**
+ * Slightly non-standard helpers to get the date in a YYYY-MM-DD format.
+ */
+template
+inline constexpr char getBuildYear() {
+ static_assert(i < 4, "Year consists of four digits");
+ return __DATE__[7+i];
+}
+
+template
+inline constexpr char getBuildMonth() {
+ static_assert(i < 2, "Month consists of two digits");
+ auto mon = *reinterpret_cast(__DATE__);
+ switch (mon) {
+ case ' naJ':
+ return "01"[i];
+ case ' beF':
+ return "02"[i];
+ case ' raM':
+ return "03"[i];
+ case ' rpA':
+ return "04"[i];
+ case ' yaM':
+ return "05"[i];
+ case ' nuJ':
+ return "06"[i];
+ case ' luJ':
+ return "07"[i];
+ case ' guA':
+ return "08"[i];
+ case ' peS':
+ return "09"[i];
+ case ' tcO':
+ return "10"[i];
+ case ' voN':
+ return "11"[i];
+ case ' ceD':
+ return "12"[i];
+ }
+
+ return '0';
+}
+
+template
+inline constexpr char getBuildDay() {
+ static_assert(i < 2, "Day consists of two digits");
+ if (i == 0 && __DATE__[4+i] == ' ')
+ return '0';
+ return __DATE__[4+i];
+}
+
#endif /* kern_util_hpp */
diff --git a/Lilu.kext/Contents/Resources/Headers/plugin_start.hpp b/Lilu.kext/Contents/Resources/Headers/plugin_start.hpp
index 731b5e8..7920882 100644
--- a/Lilu.kext/Contents/Resources/Headers/plugin_start.hpp
+++ b/Lilu.kext/Contents/Resources/Headers/plugin_start.hpp
@@ -14,23 +14,26 @@
#include
struct PluginConfiguration {
- const char *product; // Product name (e.g. xStringify(PRODUCT_NAME))
- size_t version; // Product version (e.g. parseModuleVersion(xStringify(MODULE_VERSION)))
- const char **disableArg; // Pointer to disabling boot arguments array
- size_t disableArgNum; // Number of disabling boot arguments
- const char **debugArg; // Pointer to debug boot arguments array
- size_t debugArgNum; // Number of debug boot arguments
- const char **betaArg; // Pointer to beta boot arguments array
- size_t betaArgNum; // Number of beta boot arguments
- KernelVersion minKernel; // Minimal required kernel version
- KernelVersion maxKernel; // Maximum supported kernel version
- void (*pluginStart)(); // Main function
+ const char *product; // Product name (e.g. xStringify(PRODUCT_NAME))
+ size_t version; // Product version (e.g. parseModuleVersion(xStringify(MODULE_VERSION)))
+ uint32_t runmode; // Product supported environments (e.g. LiluAPI::AllowNormal)
+ const char **disableArg; // Pointer to disabling boot arguments array
+ size_t disableArgNum; // Number of disabling boot arguments
+ const char **debugArg; // Pointer to debug boot arguments array
+ size_t debugArgNum; // Number of debug boot arguments
+ const char **betaArg; // Pointer to beta boot arguments array
+ size_t betaArgNum; // Number of beta boot arguments
+ KernelVersion minKernel; // Minimal required kernel version
+ KernelVersion maxKernel; // Maximum supported kernel version
+ void (*pluginStart)(); // Main function
};
#ifndef LILU_CUSTOM_KMOD_INIT
extern PluginConfiguration ADDPR(config);
+extern bool ADDPR(startSuccess);
+
#endif /* LILU_CUSTOM_KMOD_INIT */
#ifndef LILU_CUSTOM_IOKIT_INIT
@@ -38,11 +41,13 @@ extern PluginConfiguration ADDPR(config);
class EXPORT PRODUCT_NAME : public IOService {
OSDeclareDefaultStructors(PRODUCT_NAME)
public:
- bool init(OSDictionary *dict) override;
+ IOService *probe(IOService *provider, SInt32 *score) override;
bool start(IOService *provider) override;
void stop(IOService *provider) override;
};
+extern PRODUCT_NAME *ADDPR(selfInstance);
+
#endif /* LILU_CUSTOM_IOKIT_INIT */
#endif /* kern_start_hpp */
diff --git a/Lilu.kext/Contents/Resources/Library/plugin_start.cpp b/Lilu.kext/Contents/Resources/Library/plugin_start.cpp
index 37d8c19..db14db0 100644
--- a/Lilu.kext/Contents/Resources/Library/plugin_start.cpp
+++ b/Lilu.kext/Contents/Resources/Library/plugin_start.cpp
@@ -9,65 +9,89 @@
#include
#include
+#ifndef LILU_CUSTOM_KMOD_INIT
+bool ADDPR(startSuccess) = false;
+#else
+// Workaround custom kmod code and enable by default
+bool ADDPR(startSuccess) = true;
+#endif
+
+bool ADDPR(debugEnabled) = false;
+uint32_t ADDPR(debugPrintDelay) = 0;
+
#ifndef LILU_CUSTOM_IOKIT_INIT
+static const char kextVersion[] {
+#ifdef DEBUG
+ 'D', 'B', 'G', '-',
+#else
+ 'R', 'E', 'L', '-',
+#endif
+ xStringify(MODULE_VERSION)[0], xStringify(MODULE_VERSION)[2], xStringify(MODULE_VERSION)[4], '-',
+ getBuildYear<0>(), getBuildYear<1>(), getBuildYear<2>(), getBuildYear<3>(), '-',
+ getBuildMonth<0>(), getBuildMonth<1>(), '-', getBuildDay<0>(), getBuildDay<1>(), '\0'
+};
+
OSDefineMetaClassAndStructors(PRODUCT_NAME, IOService)
-bool PRODUCT_NAME::init(OSDictionary *dict) {
- if (!IOService::init(dict)) {
- SYSLOG("init @ failed to initalise the parent");
- return false;
- }
-
- return true;
+PRODUCT_NAME *ADDPR(selfInstance) = nullptr;
+
+IOService *PRODUCT_NAME::probe(IOService *provider, SInt32 *score) {
+ ADDPR(selfInstance) = this;
+ setProperty("VersionInfo", kextVersion);
+ auto service = IOService::probe(provider, score);
+ return ADDPR(startSuccess) ? service : nullptr;
}
bool PRODUCT_NAME::start(IOService *provider) {
+ ADDPR(selfInstance) = this;
if (!IOService::start(provider)) {
- SYSLOG("init @ failed to start the parent");
+ SYSLOG("init", "failed to start the parent");
return false;
}
- return true;
+ return ADDPR(startSuccess);
}
void PRODUCT_NAME::stop(IOService *provider) {
+ ADDPR(selfInstance) = nullptr;
IOService::stop(provider);
}
#endif /* LILU_CUSTOM_IOKIT_INIT */
-bool ADDPR(debugEnabled) = false;
-
#ifndef LILU_CUSTOM_KMOD_INIT
EXPORT extern "C" kern_return_t ADDPR(kern_start)(kmod_info_t *, void *) {
- kern_return_t ret = KERN_FAILURE;
- LiluAPI::Error error = lilu.requestAccess();
-
+ // This is an ugly hack necessary on some systems where buffering kills most of debug output.
+ PE_parse_boot_argn("liludelay", &ADDPR(debugPrintDelay), sizeof(ADDPR(debugPrintDelay)));
+
+ auto error = lilu.requestAccess();
if (error == LiluAPI::Error::NoError) {
- error = lilu.shouldLoad(ADDPR(config).product, ADDPR(config).version, 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));
+ error = lilu.shouldLoad(ADDPR(config).product, ADDPR(config).version, ADDPR(config).runmode, 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(startSuccess) = true;
ADDPR(config).pluginStart();
- ret = KERN_SUCCESS;
} else {
- SYSLOG("init @ parent said we should not continue %d", error);
+ SYSLOG("init", "parent said we should not continue %d", error);
}
lilu.releaseAccess();
} else {
- SYSLOG("init @ failed to call parent %d", error);
+ SYSLOG("init", "failed to call parent %d", error);
}
-
- return ret;
+
+ // Report success but actually do not start and let I/O Kit unload us.
+ // This works better and increases boot speed in some cases.
+ return KERN_SUCCESS;
}
EXPORT extern "C" kern_return_t ADDPR(kern_stop)(kmod_info_t *, void *) {
- // It is not safe to unload Lilu plugins!
- return KERN_FAILURE;
+ // It is not safe to unload Lilu plugins unless they were disabled!
+ return ADDPR(startSuccess) ? KERN_FAILURE : KERN_SUCCESS;
}
#endif /* LILU_CUSTOM_KMOD_INIT */
diff --git a/Lilu.kext/Contents/Resources/Library/wrappers/build.tool b/Lilu.kext/Contents/Resources/Library/wrappers/build.tool
new file mode 100755
index 0000000..14c6dae
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Library/wrappers/build.tool
@@ -0,0 +1,57 @@
+#!/bin/bash
+#
+# build.tool
+# Lilu
+#
+# Copyright © 2018 vit9696. All rights reserved.
+#
+
+cd $(dirname "$0") || exit 1
+
+rm -f *.o *.bin wrappers.inc entry32 entry64
+
+clang -m32 -c entry32.S || exit 1
+clang -m64 -c entry64.S || exit 1
+
+clang -m32 entry32.o -o entry32 || exit 1
+clang -m64 entry64.o -o entry64 || exit 1
+
+if [ "$(nm entry32.o | grep '00000000 T _main')" == "" ] || [ "$(nm entry64.o | grep '0000000000000000 T _main')" == "" ]; then
+ echo "Invalid main address"
+ exit 1
+fi
+
+otool -t entry32 | grep -E '^0000' | sed 's#^[0-9a-f]*##' | xxd -r -p > entry32.bin
+otool -t entry64 | grep -E '^0000' | sed 's#^[0-9a-f]*##' | xxd -r -p > entry64.bin
+
+sz32=$(stat -f '%z' entry32.bin)
+sz64=$(stat -f '%z' entry64.bin)
+
+btr32=$(nm entry32.o | grep -E 't booter$' | cut -f1 -d' ')
+btr64=$(nm entry64.o | grep -E 't booter$' | cut -f1 -d' ')
+
+ep32=$(nm entry32.o | grep -E 't entrypoint$' | cut -f1 -d' ')
+ep64=$(nm entry64.o | grep -E 't entrypoint$' | cut -f1 -d' ')
+
+echo '//' > wrappers.inc
+echo '// wrappers.inc' >> wrappers.inc
+echo '// Lilu' >> wrappers.inc
+echo '//' >> wrappers.inc
+echo '// Copyright © 2018 vit9696. All rights reserved.' >> wrappers.inc
+echo '//' >> wrappers.inc
+echo '' >> wrappers.inc
+echo '// This is an autogenerated file, do not edit!' >> wrappers.inc
+echo 'static uint8_t entryWrapper32[] = {' >> wrappers.inc
+cat entry32.bin | xxd -i >> wrappers.inc
+echo '};' >> wrappers.inc
+echo 'static uint8_t entryWrapper64[] = {' >> wrappers.inc
+cat entry64.bin | xxd -i >> wrappers.inc
+echo '};' >> wrappers.inc
+echo "static_assert(sizeof(entryWrapper32) == ${sz32}, \"Invalid entryWrapper32 size\");" >> wrappers.inc
+echo "static_assert(sizeof(entryWrapper64) == ${sz64}, \"Invalid entryWrapper64 size\");" >> wrappers.inc
+echo "static constexpr size_t EntryWrapper32Booter {0x${btr32}};" >> wrappers.inc
+echo "static constexpr size_t EntryWrapper64Booter {0x${btr64}};" >> wrappers.inc
+echo "static constexpr size_t EntryWrapper32Entry {0x${ep32}};" >> wrappers.inc
+echo "static constexpr size_t EntryWrapper64Entry {0x${ep64}};" >> wrappers.inc
+
+rm -f *.o *.bin entry32 entry64
diff --git a/Lilu.kext/Contents/Resources/Library/wrappers/entry32.S b/Lilu.kext/Contents/Resources/Library/wrappers/entry32.S
new file mode 100644
index 0000000..249172e
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Library/wrappers/entry32.S
@@ -0,0 +1,41 @@
+#
+# entry32.S
+# Lilu
+#
+# Copyright © 2018 vit9696. All rights reserved.
+#
+
+.text
+.global _main
+_main:
+ push %ebp
+ mov %esp, %ebp
+ # ensure 16-byte alignment
+ and $0xfffffff0, %esp
+ # int main(int argc, const char* argv[], const char* envp[], const char* apple[]);
+ push 20(%ebp)
+ push 16(%ebp)
+ push 12(%ebp)
+ push 8(%ebp)
+ call get_booter
+# entrypoint-compatible wrapper
+booter:
+ .word 0xFFFF
+ .word 0xFFFF
+get_booter:
+ pop %edx
+ mov (%edx), %edx
+ call *%edx
+ xor %eax, %eax
+ mov %ebp, %esp
+ pop %ebp
+ call get_entrypoint
+# original entrypoint (main)
+entrypoint:
+ .word 0xFFFF
+ .word 0xFFFF
+get_entrypoint:
+ pop %edx
+ mov (%edx), %edx
+ jmp *%edx
+_end:
diff --git a/Lilu.kext/Contents/Resources/Library/wrappers/entry64.S b/Lilu.kext/Contents/Resources/Library/wrappers/entry64.S
new file mode 100644
index 0000000..01ccc45
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Library/wrappers/entry64.S
@@ -0,0 +1,41 @@
+#
+# entry64.S
+# Lilu
+#
+# Copyright © 2018 vit9696. All rights reserved.
+#
+
+.text
+.global _main
+_main:
+ push %rbp
+ mov %rsp, %rbp
+ # ensure 16-byte alignment
+ and $0xfffffffffffffff0, %rsp
+ # int main(int argc, const char* argv[], const char* envp[], const char* apple[]);
+ push %rdi
+ push %rsi
+ push %rdx
+ push %rcx
+ call *booter(%rip)
+ xor %eax, %eax
+ pop %rcx
+ pop %rdx
+ pop %rsi
+ pop %rdi
+ mov %rbp, %rsp
+ pop %rbp
+ jmp *entrypoint(%rip)
+# original entrypoint (main)
+entrypoint:
+ .word 0xFFFF
+ .word 0xFFFF
+ .word 0xFFFF
+ .word 0xFFFF
+# entrypoint-compatible wrapper
+booter:
+ .word 0xFFFF
+ .word 0xFFFF
+ .word 0xFFFF
+ .word 0xFFFF
+_end:
diff --git a/Lilu.kext/Contents/Resources/Library/wrappers/wrappers.inc b/Lilu.kext/Contents/Resources/Library/wrappers/wrappers.inc
new file mode 100644
index 0000000..62d919c
--- /dev/null
+++ b/Lilu.kext/Contents/Resources/Library/wrappers/wrappers.inc
@@ -0,0 +1,28 @@
+//
+// wrappers.inc
+// Lilu
+//
+// Copyright © 2018 vit9696. All rights reserved.
+//
+
+// This is an autogenerated file, do not edit!
+static uint8_t entryWrapper32[] = {
+ 0x55, 0x89, 0xe5, 0x83, 0xe4, 0xf0, 0xff, 0x75, 0x14, 0xff, 0x75, 0x10,
+ 0xff, 0x75, 0x0c, 0xff, 0x75, 0x08, 0xe8, 0x04, 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0xff, 0x5a, 0x8b, 0x12, 0xff, 0xd2, 0x31, 0xc0, 0x89, 0xec,
+ 0x5d, 0xe8, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x5a, 0x8b,
+ 0x12, 0xff, 0xe2
+};
+static uint8_t entryWrapper64[] = {
+ 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xe4, 0xf0, 0x57, 0x56, 0x52, 0x51,
+ 0xff, 0x15, 0x18, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x59, 0x5a, 0x5e, 0x5f,
+ 0x48, 0x89, 0xec, 0x5d, 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff
+};
+static_assert(sizeof(entryWrapper32) == 51, "Invalid entryWrapper32 size");
+static_assert(sizeof(entryWrapper64) == 50, "Invalid entryWrapper64 size");
+static constexpr size_t EntryWrapper32Booter {0x00000017};
+static constexpr size_t EntryWrapper64Booter {0x000000000000002a};
+static constexpr size_t EntryWrapper32Entry {0x0000002a};
+static constexpr size_t EntryWrapper64Entry {0x0000000000000022};
diff --git a/README.md b/README.md
index 4f3e566..e44ffa2 100644
--- a/README.md
+++ b/README.md
@@ -14,9 +14,19 @@ Boot args:
- AR9565: -ath9565
+#### Installation
+- This kext version requires LILU plugin version 1.2.6+
+- Download Lilu.kext, ATH9KInjector.kext and ATH9KFixup.kext
+- Inject Lilu.kext and ATH9KFixup.kext using CLOVER bootloader.
+- Install ATH9KInjector.kext to /System/Library/Extensions (CLOVER injection won't work).
+- User -ath9485 boot arg for AR9485 and -ath9565 for AR9565 (If you don't use any boot args it will do the patching for AR946X by default)
+- Optional (Rebuild Caches)
+
+
#### Credits
- [Apple](https://www.apple.com) for macOS
-- [vit9696](https://github.com/vit9696) for [Lilu.kext](https://github.com/vit9696/Lilu) & for patch
+- [Acidanthera](https://github.com/acidanthera) for [Lilu.kext](https://github.com/acidanthera/Lilu) & for patch
- [Pike R. Alpha](https://github.com/Piker-Alpha) for patch
- [lvs1974](https://applelife.ru/members/lvs1974.53809/) for original source code and idea
- [chunnann](http://www.insanelymac.com/forum/user/1977171-chunnann/) for writing the software and maintaining it
+- [black.dragon74](https://github.com/black-dragon74) for adding support for Lilu 1.2.0+ and macOS Mojave