diff --git a/Changelog.md b/Changelog.md
index ed994ea..6faa39c 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,10 @@
RestrictEvents Changelog
========================
+#### v1.1.7
+- Added `hashmismatch` to `revpatch` in order to disable APFS Volume Hash Mismatch notification in macOS 12+
+- Allow `diskread` patch only in 10.9+ (Disabled uninitialized disk UI is not present in 10.8 or lower)
+- RestrictEfiCheck: remove 2 duplicates entries (pci8086,8c44 and pci8086,8c4b) and move specific entries in order to follow alphabetical sort
+
#### v1.1.6
- Added constants for macOS 26 support
diff --git a/README.md b/README.md
index 81c2084..c9d6aa6 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,8 @@ The list of patches currently includes:
- Disabled `MacBookAir` model memory replacement UI (comes in pair with `SystemMemoryStatus` = `Upgradable` quirk).
- Disabled `MacPro7,1` PCI Expansion view and RAM view.
- CPU brand string patch for non-Intel CPUs (can be forced for Intel with `revcpu=1`).
-- Disabled uninitialized disk UI
+- Disabled uninitialized disk UI on 10.9+
+- Disabled APFS Volume Hash Mismatch on macOS 12+
_Note_: Apple CPU identifier must be `0x0F01` for 8 core CPUs or higher and `0x0601` for 1, 2, 4, or 6 cores. This is the default in OpenCore for non-natively supported CPUs.
@@ -26,7 +27,8 @@ _Note_: Apple CPU identifier must be `0x0F01` for 8 core CPUs or higher and `0x0
- `memtab` - enable memory tab in System Information on MacBookAir and MacBookPro10,x platforms
- `pci` - prevent PCI configuration warnings in System Settings on MacPro7,1 platforms
- `cpuname` - custom CPU name in System Information
- - `diskread` - disables uninitialized disk warning in Finder
+ - `diskread` - disables uninitialized disk warning in Finder on 10.9+
+ - `hashmismatch` - disables APFS Volume Hash Mismatch on macOS 12+
- `asset` - allows Content Caching when `sysctl kern.hv_vmm_present` returns `1` on macOS 11.3 or newer
- `sbvmm` - forces VMM SB model, allowing OTA updates for unsupported models on macOS 11.3 or newer
- `f16c` - resolve CoreGraphics crashing on Ivy Bridge CPUs by disabling f16c instruction set reporting in macOS 13.3 or newer
diff --git a/RestrictEvents/Info.plist b/RestrictEvents/Info.plist
index b528380..0c91282 100644
--- a/RestrictEvents/Info.plist
+++ b/RestrictEvents/Info.plist
@@ -88,13 +88,6 @@
pci8086,3b12
pci8086,3b14
pci8086,3b16
- pci8086,8c44
- pci8086,8c4b
- pci8086,8cc1
- pci8086,8cc2
- pci8086,8cc3
- pci8086,8cc4
- pci8086,8cc6
pci8086,8c41
pci8086,8c42
pci8086,8c44
@@ -110,8 +103,16 @@
pci8086,8c54
pci8086,8c56
pci8086,8c5c
+ pci8086,8cc1
+ pci8086,8cc2
+ pci8086,8cc3
+ pci8086,8cc4
+ pci8086,8cc6
pci8086,8d44
pci8086,8d47
+ pci8086,9c41
+ pci8086,9c43
+ pci8086,9c45
pci8086,9cc1
pci8086,9cc2
pci8086,9cc3
@@ -119,9 +120,6 @@
pci8086,9cc6
pci8086,9cc7
pci8086,9cc9
- pci8086,9c41
- pci8086,9c43
- pci8086,9c45
pci8086,9d41
pci8086,9d43
pci8086,9d46
diff --git a/RestrictEvents/RestrictEvents.cpp b/RestrictEvents/RestrictEvents.cpp
index bd0857f..95117d5 100644
--- a/RestrictEvents/RestrictEvents.cpp
+++ b/RestrictEvents/RestrictEvents.cpp
@@ -42,11 +42,13 @@ static const char binPathSPMemoryReporter[] = "/System/Library/SystemPr
static const char binPathAboutExtension[] = "/System/Library/ExtensionKit/Extensions/AboutExtension.appex/Contents/MacOS/AboutExtension";
static const char binPathDiskArbitrationAgent[] = "/System/Library/Frameworks/DiskArbitration.framework/Versions/A/Support/DiskArbitrationAgent";
+static const char binPathAPFSUserAgent[] = "/System/Library/CoreServices/APFSUserAgent";
static bool enableMemoryUiPatching;
static bool enablePciUiPatching;
static bool enableCpuNamePatching;
static bool enableDiskArbitrationPatching;
+static bool enableAPFSUserPatching;
static bool enableAssetPatching;
static bool enableSbvmmPatching;
static bool enableF16cPatching;
@@ -79,6 +81,127 @@ static uint8_t replDiskArbitrationPatch[] = { 0x83, 0xF8, 0x0F };
const char *procBlacklist[10] = {};
+static uint8_t findAPFSUserPatch14[] = {
+ 0x00, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, ///< mov rdi, qword [whatever]
+ 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, ///< lea rdx, qword [aIogeneralinter]
+ 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, ///< lea rcx, qword [whatever]
+ 0x89, 0x00, ///< mov esi, ebx
+ 0x00, 0x89, 0x00, ///< mov r8, r15
+ 0x00, 0x89, 0x00, ///< mov r9, r15
+ 0xE8, 0x00, 0x00, 0x00, 0x00 ///< call imp___stubs__IOServiceAddInterestNotification
+};
+
+static uint8_t maskAPFSUserPatch14[] = {
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0x00
+};
+
+static uint8_t replAPFSUserPatch14[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x90, 0x90, 0x90, 0x90, 0x90 ///< nop (call imp___stubs__IOServiceAddInterestNotification)
+};
+
+static uint8_t replmaskAPFSUserPatch14[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+
+
+
+
+
+
+
+static uint8_t findAPFSUserPatch[] = {
+ 0x00, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, ///< mov rdi, qword [whatever]
+ 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, ///< lea rdx, qword [aIogeneralinter]
+ 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, ///< lea rcx, qword [whatever]
+ 0x00, 0x89, 0x00, ///< mov esi, r15d
+ 0x00, 0x89, 0x00, ///< mov r8, rbx
+ 0x00, 0x89, 0x00, ///< mov r9, rbx
+ 0xE8, 0x00, 0x00, 0x00, 0x00 ///< call imp___stubs__IOServiceAddInterestNotification
+};
+
+static uint8_t maskAPFSUserPatch[] = {
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0x00
+};
+
+static uint8_t replAPFSUserPatch[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x90, 0x90, 0x90, 0x90, 0x90 ///< nop (call imp___stubs__IOServiceAddInterestNotification)
+};
+
+static uint8_t replmaskAPFSUserPatch[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+static mach_vm_address_t orig_apfs_announce_hash_mismatch;
+static mach_vm_address_t orig_apfs_notify_hash_mismatch;
+
+static const char *kextapfsPath = { "/System/Library/Extensions/apfs.kext/Contents/MacOS/apfs" };
+
+static KernelPatcher::KextInfo kextapfs = { "com.apple.filesystems.apfs", &kextapfsPath, 1, {true}, {}, KernelPatcher::KextInfo::Unloaded };
+
+static int patched_apfs_announce_hash_mismatch(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8) {
+ return 0;
+};
+
+static int patched_apfs_notify_hash_mismatch(int arg0, int arg1, int arg2) {
+ return 0;
+};
+
+static void processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
+ // Check if 'apfs.kext' is loaded
+ if (index != kextapfs.loadIndex) {
+ return;
+ }
+
+ // Force '_apfs_announce_hash_mismatch' to return 0
+ // Force '_apfs_notify_hash_mismatch' to return 0
+ KernelPatcher::RouteRequest requests[] = {
+ {"_apfs_announce_hash_mismatch", patched_apfs_announce_hash_mismatch, orig_apfs_announce_hash_mismatch},
+ {"_apfs_notify_hash_mismatch", patched_apfs_notify_hash_mismatch, orig_apfs_notify_hash_mismatch}
+ };
+
+ if (!patcher.routeMultiple(index, requests, address, size)) {
+ SYSLOG("rev", "patcher.routeMultiple for at least one of specified symbols is failed with error %d", patcher.getError());
+ patcher.clearError();
+ }
+}
+
struct RestrictEventsPolicy {
/**
@@ -134,13 +257,33 @@ struct RestrictEventsPolicy {
DBGLOG("rev", "patched %s in SPMemoryReporter.spreporter", reinterpret_cast(modelFindPatch));
return;
}
- } else if (enableDiskArbitrationPatching && UNLIKELY(strcmp(path, binPathDiskArbitrationAgent) == 0)) {
+ } else if (enableDiskArbitrationPatching && getKernelVersion() >= KernelVersion::Mavericks && UNLIKELY(strcmp(path, binPathDiskArbitrationAgent) == 0)) {
if (UNLIKELY(KernelPatcher::findAndReplace(const_cast(data), size,
findDiskArbitrationPatch, sizeof(findDiskArbitrationPatch),
replDiskArbitrationPatch, sizeof(findDiskArbitrationPatch)))) {
DBGLOG("rev", "patched unreadable disk case in DiskArbitrationAgent");
return;
}
+ } else if (enableAPFSUserPatching && getKernelVersion() >= KernelVersion::Monterey && UNLIKELY(strcmp(path, binPathAPFSUserAgent) == 0)) {
+ if (getKernelVersion() >= KernelVersion::Sonoma) {
+ if (UNLIKELY(KernelPatcher::findAndReplaceWithMask(const_cast(data), size,
+ findAPFSUserPatch14, sizeof(findAPFSUserPatch14),
+ maskAPFSUserPatch14, sizeof(findAPFSUserPatch14),
+ replAPFSUserPatch14, sizeof(findAPFSUserPatch14),
+ replmaskAPFSUserPatch14, sizeof(findAPFSUserPatch14)))) {
+ DBGLOG("rev", "patched Volume Hash Mismatch notification in APFSUserAgent for macOS 14+");
+ return;
+ }
+ } else {
+ if (UNLIKELY(KernelPatcher::findAndReplaceWithMask(const_cast(data), size,
+ findAPFSUserPatch, sizeof(findAPFSUserPatch),
+ maskAPFSUserPatch, sizeof(findAPFSUserPatch),
+ replAPFSUserPatch, sizeof(findAPFSUserPatch),
+ replmaskAPFSUserPatch, sizeof(findAPFSUserPatch)))) {
+ DBGLOG("rev", "patched Volume Hash Mismatch notification in APFSUserAgent for macOS 12+");
+ return;
+ }
+ }
} else if (UserPatcher::matchSharedCachePath(path)) {
// Model check and CPU name may exist in the same page in AppleSystemInfo.
if (needsMemPatch && getKernelVersion() >= KernelVersion::Yosemite) {
@@ -364,6 +507,9 @@ struct RestrictEventsPolicy {
if (strstr(value, "diskread", strlen("diskread"))) {
enableDiskArbitrationPatching = true;
}
+ if (strstr(value, "hashmismatch", strlen("hashmismatch"))) {
+ enableAPFSUserPatching = true;
+ }
if (strstr(value, "asset", strlen("asset"))) {
enableAssetPatching = true;
}
@@ -545,6 +691,12 @@ PluginConfiguration ADDPR(config) {
if (modelFindPatch != nullptr || needsCpuNamePatch || enableDiskArbitrationPatching ||
(getKernelVersion() >= KernelVersion::Monterey ||
(getKernelVersion() == KernelVersion::BigSur && getKernelMinorVersion() >= 4))) {
+ if (enableAPFSUserPatching && getKernelVersion() >= KernelVersion::Monterey) {
+ lilu.onKextLoadForce(&kextapfs, 1,
+ [](void *user, KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
+ processKext(patcher, index, address, size);
+ }, nullptr);
+ }
lilu.onPatcherLoadForce([](void *user, KernelPatcher &patcher) {
if ((lilu.getRunMode() & LiluAPI::RunningNormal) != 0) {
if (needsCpuNamePatch) RestrictEventsPolicy::calculatePatchedBrandString();