@@ -27,14 +27,22 @@ static const uint8_t kAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched[] = {
2727 0xb8 , 0x02 , 0x00 , 0x00 , 0x00 , 0x90 , 0x90 , 0x90 , 0xeb ,
2828};
2929
30+ static constexpr size_t kAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize = sizeof (kAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal );
31+
32+ static_assert (kAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize == sizeof (kAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched ), " patch size invalid" );
33+
3034static const uint8_t kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal [] = {
3135 0xb9 , 0x02 , 0x00 , 0x00 , 0x00 , 0x01 , 0xc8 , 0x41 , 0x83 , 0xf8 , 0x21 , 0x0f , 0x42 , 0xc1 , 0xeb ,
3236};
3337
3438static const uint8_t kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched [] = {
35- 0xb9 , 0x02 , 0x00 , 0x00 , 0x00 , 0x01 , 0xc8 , 0x41 , 0x83 , 0xf8 , 0x21 , 0x90 , 0x90 , 0x90 , 0xeb ,
39+ 0xb9 , 0x02 , 0x00 , 0x00 , 0x00 , 0x01 , 0xc8 , 0x41 , 0x83 , 0xf8 , 0x21 , 0x0f , 0x43 , 0xc1 , 0xeb ,
3640};
3741
42+ static constexpr size_t kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize = sizeof (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal );
43+
44+ static_assert (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize == sizeof (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched ), " patch size invalid" );
45+
3846static const char kAmdBronzeMtlDriverPath [] = " /System/Library/Extensions/AMDMTLBronzeDriver.bundle/Contents/MacOS/AMDMTLBronzeDriver" ;
3947
4048static const char kDyldCachePath [] = " /private/var/db/dyld/dyld_shared_cache_x86_64h" ;
@@ -53,14 +61,10 @@ static KernelPatcher::KextInfo kAMDHWLibsInfo[] = {
5361 [kAmdRadeonX4000HwLibs ] = { " com.apple.kext.AMDRadeonX4000HWLibs" , kAmdRadeonX4000HwLibsPath , arrsize (kAmdRadeonX4000HwLibsPath ), {true }, {}, KernelPatcher::KextInfo::Unloaded },
5462};
5563
56- static mach_vm_address_t orig_cs_validate_range {};
64+ static mach_vm_address_t orig_cs_validate {};
5765static mach_vm_address_t orig_IsEarlySAMUInitEnabled {};
5866static mach_vm_address_t orig_getHardwareInfo {};
5967
60- static uint8_t const *patchFind {};
61- static uint8_t const *patchReplace {};
62- static size_t patchSize;
63-
6468#pragma mark - Kernel patching code
6569
6670/* *
@@ -85,6 +89,7 @@ static void doKernelPatch(void (^patchFunc)(void)) {
8589
8690#pragma mark - Patched functions
8791
92+ // pre Big Sur
8893static boolean_t patched_cs_validate_range (vnode_t vp,
8994 memory_object_t pager,
9095 memory_object_offset_t offset,
@@ -93,17 +98,47 @@ static boolean_t patched_cs_validate_range(vnode_t vp,
9398 unsigned *result) {
9499 char path[kPathMaxLen ];
95100 int pathlen = kPathMaxLen ;
96- boolean_t res = FunctionCast (patched_cs_validate_range, orig_cs_validate_range )(vp, pager, offset, data, size, result);
101+ boolean_t res = FunctionCast (patched_cs_validate_range, orig_cs_validate )(vp, pager, offset, data, size, result);
97102 if (res && vn_getpath (vp, path, &pathlen) == 0 ) {
98103 static_assert (sizeof (kAmdBronzeMtlDriverPath ) <= sizeof (path), " path too long" );
99104 static_assert (sizeof (kDyldCachePath ) <= sizeof (path), " path too long" );
100105 if (UNLIKELY (strncmp (path, kAmdBronzeMtlDriverPath , sizeof (kAmdBronzeMtlDriverPath )) == 0 ) ||
101106 UNLIKELY (strncmp (path, kDyldCachePath , sizeof (kDyldCachePath )) == 0 )) {
102107 void *res;
103- if (UNLIKELY ((res = memmem (data, size, patchFind, patchSize )) != NULL )) {
108+ if (UNLIKELY ((res = memmem (data, size, kAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal , kAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize )) != NULL )) {
104109 SYSLOG (MODULE_SHORT, " found function to patch!" );
110+ SYSLOG (MODULE_SHORT, " path: %s" , path);
105111 doKernelPatch (^{
106- lilu_os_memcpy (res, patchReplace, patchSize);
112+ lilu_os_memcpy (res, kAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched , kAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize );
113+ });
114+ }
115+ }
116+ }
117+ return res;
118+ }
119+
120+ // For Big Sur
121+ static boolean_t patched_cs_validate_page (vnode_t vp,
122+ memory_object_t pager,
123+ memory_object_offset_t page_offset,
124+ const void *data,
125+ int *arg4,
126+ int *arg5,
127+ int *arg6) {
128+ char path[kPathMaxLen ];
129+ int pathlen = kPathMaxLen ;
130+ boolean_t res = FunctionCast (patched_cs_validate_page, orig_cs_validate)(vp, pager, page_offset, data, arg4, arg5, arg6);
131+ if (res && vn_getpath (vp, path, &pathlen) == 0 ) {
132+ static_assert (sizeof (kAmdBronzeMtlDriverPath ) <= sizeof (path), " path too long" );
133+ static_assert (sizeof (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal ) == sizeof (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched ), " patch size invalid" );
134+ if (UNLIKELY (strncmp (path, kAmdBronzeMtlDriverPath , sizeof (kAmdBronzeMtlDriverPath )) == 0 )) {
135+ const void *start = (const char *)data - page_offset;
136+ void *res;
137+ SYSLOG (MODULE_SHORT, " found path: %s" , path);
138+ if (UNLIKELY ((res = memmem (start, page_offset, kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal , kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize )) != NULL )) {
139+ SYSLOG (MODULE_SHORT, " found function to patch!" );
140+ doKernelPatch (^{
141+ lilu_os_memcpy (res, kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched , kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnSize );
107142 });
108143 }
109144 }
@@ -132,33 +167,41 @@ static void pluginStart() {
132167 LiluAPI::Error error;
133168
134169 DBGLOG (MODULE_SHORT, " start" );
135- if (getKernelVersion () >= KernelVersion::BigSur) {
136- patchFind = kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal ;
137- patchReplace = kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched ;
138- patchSize = sizeof (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal );
139- static_assert (sizeof (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal ) == sizeof (kBigSurAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched ), " patch size invalid" );
140- } else {
141- patchFind = kAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal ;
142- patchReplace = kAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched ;
143- patchSize = sizeof (kAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal );
144- static_assert (sizeof (kAmdBronzeMtlAddrLibGetBaseArrayModeReturnOriginal ) == sizeof (kAmdBronzeMtlAddrLibGetBaseArrayModeReturnPatched ), " patch size invalid" );
145- }
146- error = lilu.onPatcherLoad ([](void *user, KernelPatcher &patcher){
147- DBGLOG (MODULE_SHORT, " patching cs_validate_range" );
148- mach_vm_address_t kern = patcher.solveSymbol (KernelPatcher::KernelID, " _cs_validate_range" );
149-
150- if (patcher.getError () == KernelPatcher::Error::NoError) {
151- orig_cs_validate_range = patcher.routeFunctionLong (kern, reinterpret_cast <mach_vm_address_t >(patched_cs_validate_range), true , true );
170+ if (getKernelVersion () < KernelVersion::BigSur) {
171+ error = lilu.onPatcherLoad ([](void *user, KernelPatcher &patcher){
172+ DBGLOG (MODULE_SHORT, " patching cs_validate_range" );
173+ mach_vm_address_t kern = patcher.solveSymbol (KernelPatcher::KernelID, " _cs_validate_range" );
174+
175+ if (patcher.getError () == KernelPatcher::Error::NoError) {
176+ orig_cs_validate = patcher.routeFunctionLong (kern, reinterpret_cast <mach_vm_address_t >(patched_cs_validate_range), true , true );
177+
178+ if (patcher.getError () != KernelPatcher::Error::NoError) {
179+ SYSLOG (MODULE_SHORT, " failed to hook _cs_validate_range" );
180+ } else {
181+ DBGLOG (MODULE_SHORT, " hooked cs_validate_range" );
182+ }
183+ } else {
184+ SYSLOG (MODULE_SHORT, " failed to find _cs_validate_range" );
185+ }
186+ });
187+ } else { // >= macOS 11
188+ error = lilu.onPatcherLoad ([](void *user, KernelPatcher &patcher){
189+ DBGLOG (MODULE_SHORT, " patching cs_validate_page" );
190+ mach_vm_address_t kern = patcher.solveSymbol (KernelPatcher::KernelID, " _cs_validate_page" );
152191
153- if (patcher.getError () != KernelPatcher::Error::NoError) {
154- SYSLOG (MODULE_SHORT, " failed to hook _cs_validate_range" );
192+ if (patcher.getError () == KernelPatcher::Error::NoError) {
193+ orig_cs_validate = patcher.routeFunctionLong (kern, reinterpret_cast <mach_vm_address_t >(patched_cs_validate_page), true , true );
194+
195+ if (patcher.getError () != KernelPatcher::Error::NoError) {
196+ SYSLOG (MODULE_SHORT, " failed to hook _cs_validate_page" );
197+ } else {
198+ DBGLOG (MODULE_SHORT, " hooked cs_validate_page" );
199+ }
155200 } else {
156- DBGLOG (MODULE_SHORT, " hooked cs_validate_range " );
201+ SYSLOG (MODULE_SHORT, " failed to find _cs_validate_page " );
157202 }
158- } else {
159- SYSLOG (MODULE_SHORT, " failed to find _cs_validate_range" );
160- }
161- });
203+ });
204+ }
162205 if (error != LiluAPI::Error::NoError) {
163206 SYSLOG (MODULE_SHORT, " failed to register onPatcherLoad method: %d" , error);
164207 }
0 commit comments