Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch/i386/boot2/kernel_patcher_internal.c

  • Property svn:executable set to *
1/*
2 * Original idea of patching kernel by Evan Lojewsky, 2009
3 *
4 * Copyright (c) 2011-2012 Frank Peng. All rights reserved.
5 *
6 * Correction and improvements by Clover team
7 *
8 * Ported and adapted to Chameleon by Micky1979 and ErmaC
9 *
10 * kexts patcher by Micky1979, 2017
11 */
12
13// TODO:
14// replace for loops with FindAndReplace
15
16#include "config.h"
17#include "boot.h"
18#include "libsaio.h"
19#include "bootstruct.h"
20#include "kernel_patcher_internal.h"
21#include "sse3_patcher.h"
22#include "sse3_5_patcher.h"
23#include "platform.h"
24
25#include "xml.h"
26#include "sl.h"
27
28#if DEBUG_KERNEL
29#define DBG(x...)verbose(x)
30#else
31#define DBG(x...)
32#endif
33
34#define NVDAVALUE "1" // unused (old method to activate NVidia Web Drivers)
35
36// ===================================
37/*
38 * Entrypoint from load.c
39 */
40void patch_kernel_internal(void *kernelData, u_int32_t uncompressed_size)
41{
42// ================================
43if (!useDarwinVersion)
44{
45kernelOSVer = MacOSVerCurrent;
46}
47
48// ================================
49verbose("[ KERNEL PATCHER START ]\n");
50
51/* to debug kernelOSVer and see if match the OS version: */
52DBG("\n\tMacOSVerCurrent = %08x version.\n\n", MacOSVerCurrent);
53DBG("\n\tkernelOSVer = %08x version.\n\n", kernelOSVer);
54
55verbose("\n\tWill patch for %d.%d.%d kernel version compatible.\n\n", gDarwinMajor, gDarwinMinor, gDarwinRev);
56
57verbose("\tKernelBooter_kexts state: %s!\n", KernelBooter_kexts ? " enabled" : "disabled");
58verbose("\tKernelPm state: %s!\n", KernelPm ? " enabled" : "disabled");
59verbose("\tKernelLapicError state: %s!\n", KernelLapicError ? " enabled" : "disabled");
60verbose("\tKernelHaswell state: %s!\n", KernelHaswell ? " enabled" : "disabled");
61verbose("\tKernelcpuFamily state: %s!\n", KernelcpuFamily ? " enabled" : "disabled");
62verbose("\tKernelSSE3 state: %s!\n", KernelSSE3 ? " enabled" : "disabled");
63
64 u_int32_t sizeToScan = uncompressed_size; // for further expansion
65
66// Select machine arch
67if (archCpuType == CPU_TYPE_I386)
68{
69patch_kernel_32((void *)kernelData, sizeToScan);
70}
71else
72{
73patch_kernel_64((void *)kernelData, sizeToScan);
74}
75
76/* VMware issue
77if (patch_string_XNU_init(kernelData))
78{
79DBG("\tKernel string replaced.\n");
80}
81*/
82
83 // do user's defined patches
84 if (bootInfo->kernelConfig.dictionary) {
85 pach_binaryUsingDictionary(kernelData,
86 (UInt32)uncompressed_size,
87 0,
88 "KernelPatches",
89 bootInfo->kernelConfig.dictionary);
90 }
91
92verbose("Kernel patcher: end!\n\n");
93}
94
95// ===================================
96// patches for a 64-bit kernel.
97void patch_kernel_64(void *kernelData, u_int32_t uncompressed_size) // KernelPatcher_64
98{
99DBG("[ 64-bit ]\n");
100
101UInt8 *bytes = (UInt8 *)kernelData;
102UInt32 patchLocation = 0, patchLocation1 = 0;
103UInt32 i;
104UInt32 switchaddr = 0;
105UInt32 mask_family = 0, mask_model = 0;
106UInt32 cpuid_family_addr = 0, cpuid_model_addr = 0;
107
108// Prelinked Extensions Patcher
109if (KernelBooter_kexts)
110{
111 patch_BooterExtensions_64(kernelData);
112}
113
114// Lapic Error
115if (KernelLapicError && patch_lapic_init_64(kernelData))
116{
117verbose("\tLapic Error call removed.\n");
118}
119
120// Power Managment
121if (KernelPm && patch_pm_init(kernelData))
122{
123verbose("\tPower Managment patch applied.\n");
124}
125
126// Haswell Kernel Patcher
127if ( KernelHaswell && (kernelOSVer >= MacOSVer2Int("10.8")) ) // Haswell "E" and "ULT" support
128{
129switch (Platform.CPU.Family)
130{
131case 0x06:
132{
133switch (Platform.CPU.Model)
134{
135case CPUID_MODEL_HASWELL_SVR: // Haswell-E Kernel Patcher
136if (patch_haswell_E_init(kernelData))
137{
138verbose("\tHaswell-E Kernel patch applied.\n");
139}
140break;
141
142case CPUID_MODEL_HASWELL_ULT: // Haswell-ULT Kernel Patcher
143if (patch_haswell_ULT_init(kernelData))
144{
145verbose("\tHaswell-ULT Kernel patch applied.\n");
146}
147break;
148
149default:
150verbose("\tNo Haswell-ULT/-E Kernel patch applied for this CPU.\n");
151break;
152}
153}
154}
155}
156
157if (KernelcpuFamily)
158{
159verbose("\t- Looking for _cpuid_set_info _panic ...\n");
160
161// Determine location of _cpuid_set_info _panic call for reference
162// basically looking for info_p->cpuid_model = bitfield32(reg[eax], 7, 4);
163for (i = 0; i < 0x1000000; i++)
164{
165if (bytes[i + 0] == 0xC7
166&& bytes[i + 1] == 0x05
167&& bytes[i + 5] == 0x00
168&& bytes[i + 6] == 0x07
169&& bytes[i + 7] == 0x00
170&& bytes[i + 8] == 0x00
171&& bytes[i + 9] == 0x00
172&& bytes[i - 5] == 0xE8)
173{
174// matching 0xE8 for _panic call start
175patchLocation = i-5;
176break;
177}
178}
179
180if (!patchLocation)
181{
182verbose("\t_cpuid_set_info Unsupported CPU _panic not found \n");
183return;
184}
185
186// make sure only kernels for OSX 10.6.0 to 10.7.3 are being patched by this approach
187if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer <= MacOSVer2Int("10.7.3"))
188{
189
190verbose("\t- will patch kernel for OSX 10.6.0 to 10.7.3\n");
191
192// remove tsc_init: unknown CPU family panic for kernels prior to 10.6.2 which still had Atom support
193if (kernelOSVer < MacOSVer2Int("10.6.2"))
194{
195for (i=0; i<0x1000000; i++)
196 {
197// find _tsc_init panic address by byte sequence 488d3df4632a00
198if (bytes[i] == 0x48
199&& bytes[i + 1] == 0x8D
200&& bytes[i + 2] == 0x3D
201&& bytes[i + 3] == 0xF4
202&& bytes[i + 4] == 0x63
203&& bytes[i + 5] == 0x2A
204&& bytes[i + 6] == 0x00)
205{
206patchLocation1 = i+9;
207verbose("\tFound _tsc_init _panic address at 0x%08x\n", (unsigned int)patchLocation1);
208break;
209}
210}
211
212// NOP _panic call
213if (patchLocation1)
214{
215bytes[patchLocation1 + 0] = 0x90;
216bytes[patchLocation1 + 1] = 0x90;
217bytes[patchLocation1 + 2] = 0x90;
218bytes[patchLocation1 + 3] = 0x90;
219bytes[patchLocation1 + 4] = 0x90;
220}
221}
222else
223{
224// assume patching logic for OSX 10.6.2 to 10.7.3
225
226/*
227 * Here is our case from CPUID switch statement, it sets CPUFAMILY_UNKNOWN
228 * C7051C2C5F0000000000 mov dword [ds:0xffffff80008a22c0], 0x0 (example from 10.7)
229 */
230switchaddr = patchLocation - 19;
231verbose("\tswitch statement patch location is 0x%08lx\n", (switchaddr+6));
232
233if (bytes[switchaddr + 0] == 0xC7
234&& bytes[switchaddr + 1] == 0x05
235&& bytes[switchaddr + 5] == 0x00
236&& bytes[switchaddr + 6] == 0x00
237&& bytes[switchaddr + 7] == 0x00
238&& bytes[switchaddr + 8] == 0x00)
239{
240// Determine cpuid_family address from above mov operation
241cpuid_family_addr =
242bytes[switchaddr + 2] << 0 |
243bytes[switchaddr + 3] << 8 |
244bytes[switchaddr + 4] << 16 |
245bytes[switchaddr + 5] << 24;
246cpuid_family_addr = cpuid_family_addr + (switchaddr + 10);
247
248if (cpuid_family_addr)
249{
250// Determine cpuid_model address
251// for 10.6.2 kernels it's offset by 299 bytes from cpuid_family address
252if (kernelOSVer == MacOSVer2Int("10.6.2"))
253{
254cpuid_model_addr = cpuid_family_addr - 0X12B;
255}
256// for 10.6.3 to 10.6.7 it's offset by 303 bytes
257else if (kernelOSVer <= MacOSVer2Int("10.6.7"))
258{
259cpuid_model_addr = cpuid_family_addr - 0X12F;
260}
261// for 10.6.8 to 10.7.3 kernels - by 339 bytes
262else
263{
264cpuid_model_addr = cpuid_family_addr - 0X153;
265}
266
267verbose("\tcpuid_family address: 0x%08X\n", (unsigned int)cpuid_family_addr);
268verbose("\tcpuid_model address: 0x%08X\n", (unsigned int)cpuid_model_addr);
269
270switchaddr += 6; // offset 6 bytes in mov operation to write a dword instead of zero
271
272// calculate mask for patching, cpuid_family mask not needed as we offset on a valid mask
273mask_model = cpuid_model_addr - (switchaddr+14);
274//verbose("\tmodel mask 0x%08x\n", (unsigned int)mask_model);
275
276//verbose("\toverriding cpuid_family and cpuid_model as CPUID_INTEL_PENRYN\n");
277bytes[switchaddr+0] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;
278bytes[switchaddr+1] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;
279bytes[switchaddr+2] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;
280bytes[switchaddr+3] = (CPUFAMILY_INTEL_PENRYN & 0xFF000000) >> 24;
281
282// mov dword [ds:0xffffff80008a216d], 0x2000117
283bytes[switchaddr+4] = 0xC7;
284bytes[switchaddr+5] = 0x05;
285bytes[switchaddr+6] = (UInt8)((mask_model & 0x000000FF) >> 0);
286bytes[switchaddr+7] = (UInt8)((mask_model & 0x0000FF00) >> 8);
287bytes[switchaddr+8] = (UInt8)((mask_model & 0x00FF0000) >> 16);
288bytes[switchaddr+9] = (UInt8)((mask_model & 0xFF000000) >> 24);
289bytes[switchaddr+10] = 0x17; // cpuid_model (Penryn)
290bytes[switchaddr+11] = 0x01; // cpuid_extmodel
291bytes[switchaddr+12] = 0x00; // cpuid_extfamily
292bytes[switchaddr+13] = 0x02; // cpuid_stepping
293
294// fill remainder with 4 NOPs
295for (i = 14; i < 18; i++)
296{
297bytes[switchaddr+i] = 0x90;
298}
299}
300}
301else
302{
303verbose("\tUnable to determine cpuid_family address, patching aborted\n");
304return;
305}
306}
307
308// patch sse3
309if (KernelSSE3 && (SNOW_LEOPARD))
310{
311patch_SSE3_6((void *)bytes);
312}
313
314if (KernelSSE3 && (LION))
315{
316patch_SSE3_7((void *)bytes);
317}
318}
319
320// all 10.7.4+ kernels share common CPUID switch statement logic,
321// it needs to be exploited in diff manner due to the lack of space
322else if (kernelOSVer >= MacOSVer2Int("10.7.4"))
323{
324verbose("\t- will patch kernel for OSX %s (from 10.7.4 and newer)\n", gBootVolume->OSFullVer);
325
326/*
327 * Here is our switchaddress location ... it should be case 20 from CPUID switch statement
328 * 833D78945F0000 cmp dword [ds:0xffffff80008a21d0], 0x0;
329 * 7417 je 0xffffff80002a8d71
330 */
331switchaddr = patchLocation-45;
332verbose("\tswitch statement patch location is 0x%08X\n", (unsigned int)switchaddr);
333
334if(bytes[switchaddr + 0] == 0x83
335&& bytes[switchaddr + 1] == 0x3D
336&& bytes[switchaddr + 5] == 0x00
337&& bytes[switchaddr + 6] == 0x00
338&& bytes[switchaddr + 7] == 0x74)
339{
340
341// Determine cpuid_family address
342// 891D4F945F00 mov dword [ds:0xffffff80008a21a0], ebx
343cpuid_family_addr =
344bytes[switchaddr - 4] << 0 |
345bytes[switchaddr - 3] << 8 |
346bytes[switchaddr - 2] << 16 |
347bytes[switchaddr - 1] << 24;
348cpuid_family_addr = cpuid_family_addr + switchaddr;
349
350if (cpuid_family_addr)
351{
352// Determine cpuid_model address
353// for 10.6.8+ kernels it's 339 bytes apart from cpuid_family address
354cpuid_model_addr = cpuid_family_addr - 0X153;
355
356verbose("\tcpuid_family address: 0x%08X\n", (unsigned int)cpuid_family_addr);
357verbose("\tcpuid_model address: 0x%08X\n", (unsigned int)cpuid_model_addr);
358
359// Calculate masks for patching
360mask_family = cpuid_family_addr - (switchaddr +15);
361mask_model = cpuid_model_addr - (switchaddr +25);
362verbose("\tfamily mask: 0x%08X \n\tmodel mask: 0x%08X\n", (unsigned int)mask_family, (unsigned int)mask_model);
363
364// retain original
365// test ebx, ebx
366bytes[switchaddr+0] = bytes[patchLocation-13];
367bytes[switchaddr+1] = bytes[patchLocation-12];
368// retain original, but move jump offset by 20 bytes forward
369// jne for above test
370bytes[switchaddr+2] = bytes[patchLocation-11];
371bytes[switchaddr+3] = bytes[patchLocation-10]+0x20;
372// mov ebx, 0x78ea4fbc
373bytes[switchaddr+4] = 0xBB;
374bytes[switchaddr+5] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;
375bytes[switchaddr+6] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;
376bytes[switchaddr+7] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;
377bytes[switchaddr+8] = (CPUFAMILY_INTEL_PENRYN & 0xFF000000) >> 24;
378
379// mov dword, ebx
380bytes[switchaddr+9] = 0x89;
381bytes[switchaddr+10] = 0x1D;
382// cpuid_cpufamily address 0xffffff80008a21a0
383bytes[switchaddr+11] = (UInt8)((mask_family & 0x000000FF) >> 0);
384bytes[switchaddr+12] = (UInt8)((mask_family & 0x0000FF00) >> 8);
385bytes[switchaddr+13] = (UInt8)((mask_family & 0x00FF0000) >> 16);
386bytes[switchaddr+14] = (UInt8)((mask_family & 0xFF000000) >> 24);
387
388// mov dword
389bytes[switchaddr+15] = 0xC7;
390bytes[switchaddr+16] = 0x05;
391// cpuid_model address 0xffffff80008b204d
392bytes[switchaddr+17] = (UInt8)((mask_model & 0x000000FF) >> 0);
393bytes[switchaddr+18] = (UInt8)((mask_model & 0x0000FF00) >> 8);
394bytes[switchaddr+19] = (UInt8)((mask_model & 0x00FF0000) >> 16);
395bytes[switchaddr+20] = (UInt8)((mask_model & 0xFF000000) >> 24);
396
397bytes[switchaddr+21] = 0x17; // cpuid_model
398bytes[switchaddr+22] = 0x01; // cpuid_extmodel
399bytes[switchaddr+23] = 0x00; // cpuid_extfamily
400bytes[switchaddr+24] = 0x02; // cpuid_stepping
401
402// fill remainder with 25 NOPs
403for (i=25; i<25+25; i++)
404{
405bytes[switchaddr+i] = 0x90;
406}
407}
408}
409else
410{
411verbose("\tUnable to determine cpuid_family address, patching aborted\n");
412return;
413}
414}
415
416verbose("\n");
417}
418}
419
420// ===================================
421// patches for a 32-bit kernel.
422void patch_kernel_32(void *kernelData, u_int32_t uncompressed_size) // KernelPatcher_32
423{
424DBG("[ 32-bit ]\n");
425
426UInt8 *bytes = ( UInt8 *)kernelData;
427UInt32 patchLocation = 0, patchLocation1 = 0;
428UInt32 i;
429UInt32 jumpaddr;
430
431// Prelinked Extensions Patcher
432if (KernelBooter_kexts)
433{
434patch_BooterExtensions_32(kernelData);
435}
436
437// Lapic Error
438if (KernelLapicError && patch_lapic_init_32(kernelData))
439{
440verbose("\tLapic Error call removed.\n");
441}
442
443if (KernelcpuFamily)
444{
445verbose("\t- Looking for _cpuid_set_info _panic ...\n");
446// _cpuid_set_info _panic address
447for (i = 0; i < 0x1000000; i++)
448{
449if (bytes[i] == 0xC7
450&& bytes[i + 1] == 0x05
451&& bytes[i + 6] == 0x07
452&& bytes[i + 7] == 0x00
453&& bytes[i + 8] == 0x00
454&& bytes[i + 9] == 0x00
455&& bytes[i + 10] == 0xC7
456&& bytes[i + 11] == 0x05
457&& bytes[i - 5] == 0xE8)
458{
459patchLocation = i-5;
460verbose("\tFound _cpuid_set_info _panic address at 0x%08X\n", (unsigned int)patchLocation);
461break;
462}
463}
464
465if (!patchLocation)
466{
467verbose("\tCan't find _cpuid_set_info _panic address, patch kernel abort.\n");
468return;
469}
470
471// this for 10.6.0 and 10.6.1 kernel and remove tsc.c unknow cpufamily panic
472// c70424540e5900
473// find _tsc_init panic address
474for (i = 0; i < 0x1000000; i++)
475{
476// _cpuid_set_info _panic address
477if (bytes[i] == 0xC7
478&& bytes[i + 1] == 0x04
479&& bytes[i + 2] == 0x24
480&& bytes[i + 3] == 0x54
481&& bytes[i + 4] == 0x0E
482&& bytes[i + 5] == 0x59
483&& bytes[i + 6] == 0x00)
484{
485patchLocation1 = i+7;
486verbose("\tFound _tsc_init _panic address at 0x%08X\n", (unsigned int)patchLocation1);
487break;
488}
489}
490
491// found _tsc_init panic addres and patch it
492if (patchLocation1)
493{
494bytes[patchLocation1 + 0] = 0x90;
495bytes[patchLocation1 + 1] = 0x90;
496bytes[patchLocation1 + 2] = 0x90;
497bytes[patchLocation1 + 3] = 0x90;
498bytes[patchLocation1 + 4] = 0x90;
499}
500// end tsc.c panic
501
502//first move panic code total 5 bytes, if patch cpuid fail still can boot with kernel
503bytes[patchLocation + 0] = 0x90;
504bytes[patchLocation + 1] = 0x90;
505bytes[patchLocation + 2] = 0x90;
506bytes[patchLocation + 3] = 0x90;
507bytes[patchLocation + 4] = 0x90;
508
509jumpaddr = patchLocation;
510
511for (i = 0 ;i < 500; i++)
512{
513if (bytes[jumpaddr-i-3] == 0x85
514&& bytes[jumpaddr-i-2] == 0xC0
515&& bytes[jumpaddr-i-1] == 0x75 )
516{
517jumpaddr -= i;
518bytes[jumpaddr-1] = 0x77;
519if(bytes[patchLocation - 17] == 0xC7)
520{
521bytes[jumpaddr] -=10;
522}
523break;
524}
525}
526
527if (jumpaddr == patchLocation)
528{
529verbose("\tCan't Found jumpaddr address.\n");
530return; //can't find jump location
531}
532// patch info_p->cpufamily to CPUFAMILY_INTEL_MEROM
533
534if (bytes[patchLocation - 17] == 0xC7)
535{
536bytes[patchLocation - 11] = (CPUFAMILY_INTEL_MEROM & 0x000000FF) >> 0;
537bytes[patchLocation - 10] = (CPUFAMILY_INTEL_MEROM & 0x0000FF00) >> 8;
538bytes[patchLocation - 9] = (CPUFAMILY_INTEL_MEROM & 0x00FF0000) >> 16;
539bytes[patchLocation - 8] = (CPUFAMILY_INTEL_MEROM & 0xFF000000) >> 24;
540}
541
542//patch info->cpuid_cpufamily
543bytes[patchLocation - 7] = 0xC7;
544bytes[patchLocation - 6] = 0x05;
545bytes[patchLocation - 5] = bytes[jumpaddr + 3];
546bytes[patchLocation - 4] = bytes[jumpaddr + 4];
547bytes[patchLocation - 3] = bytes[jumpaddr + 5];
548bytes[patchLocation - 2] = bytes[jumpaddr + 6];
549
550bytes[patchLocation - 1] = CPUIDFAMILY_DEFAULT; //cpuid_family need alway set 0x06
551bytes[patchLocation + 0] = CPUID_MODEL_MEROM; //cpuid_model set CPUID_MODEL_MEROM
552bytes[patchLocation + 1] = 0x01; //cpuid_extmodel alway set 0x01
553bytes[patchLocation + 2] = 0x00; //cpuid_extfamily alway set 0x00
554bytes[patchLocation + 3] = 0x90;
555bytes[patchLocation + 4] = 0x90;
556
557if (KernelSSE3 && ( LION ))
558{
559patch_SSE3_6((void *)bytes);
560}
561
562if (KernelSSE3 && ( LEOPARD ))
563{
564patch_SSE3_5((void *)bytes);
565}
566}
567}
568
569// ===================================
570// Power Managment
571bool patch_pm_init(void *kernelData) // KernelPatchPm
572{
573UInt8 *Ptr = (UInt8 *)kernelData;
574UInt8 *End = Ptr + 0x1000000;
575if (Ptr == NULL)
576{
577return false;
578}
579
580// Credits to RehabMan for the kernel patch information
581// XCPM (Xnu CPU Power Management)
582verbose("\t- Patching kernel power management...\n");
583while (Ptr < End)
584{
585if (KERNEL_PATCH_SIGNATURE == (*((UInt64 *)Ptr)))
586{
587// Bytes 19,20 of KernelPm patch for kernel 13.x change between kernel versions, so we skip them in search&replace
588if ((memcmp(Ptr + sizeof(UInt64), KernelPatchPmSrc + sizeof(UInt64), 18 * sizeof(UInt8) - sizeof(UInt64)) == 0) &&
589(memcmp(Ptr + 20 * sizeof(UInt8), KernelPatchPmSrc + 20 * sizeof(UInt8), sizeof(KernelPatchPmSrc) - 20 * sizeof(UInt8)) == 0))
590{
591// Don't copy more than the source here!
592memcpy(Ptr, KernelPatchPmRepl, 18 * sizeof(UInt8)); // Copy block of memory
593memcpy(Ptr + 20 * sizeof(UInt8), KernelPatchPmRepl + 20 * sizeof(UInt8), sizeof(KernelPatchPmSrc) - 20 * sizeof(UInt8)); // Copy block of memory
594verbose("\tKernel power management patch region 1 found and patched\n");
595return true;
596}
597else if (memcmp(Ptr + sizeof(UInt64), KernelPatchPmSrc2 + sizeof(UInt64), sizeof(KernelPatchPmSrc2) - sizeof(UInt64)) == 0)
598{
599// Don't copy more than the source here!
600memcpy(Ptr, KernelPatchPmRepl2, sizeof(KernelPatchPmSrc2)); // Copy block of memory
601verbose("\tKernel power management patch region 2 found and patched\n");
602return true;
603}
604}
605// RehabMan: for 10.10 (data portion)
606else if (0x00000002000000E2ULL == (*((UInt64 *)Ptr)))
607{
608(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;
609verbose("\tKernel power management patch 10.1x(data1) found and patched\n");
610}
611else if (0x0000004C000000E2ULL == (*((UInt64 *)Ptr)))
612{
613(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;
614verbose("\tKernel power management patch 10.1x(data2) found and patched\n");
615}
616else if (0x00000190000000E2ULL == (*((UInt64 *)Ptr)))
617{
618(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;
619verbose("\tKernel power management patch 10.10(data3) found and patched\n");
620return true;
621}
622// rehabman: change for 10.11.1 beta 15B38b
623else if (0x00001390000000E2ULL == (*((UInt64 *)Ptr)))
624{
625(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;
626verbose("\tKernel power management patch 10.11(data3) found and patched\n");
627return true;
628}
629//rehabman: change for 10.11.6 security update 2017-003 15G1611
630else if (0x00001b90000000E2ULL == (*((UInt64 *)Ptr)))
631{
632(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;
633verbose("\tKernel power management patch 10.11.6(2017-003 15G1611)(data3) found and patched\n");
634return true;
635}
636// sherlocks: change for 10.12 DP1
637else if (0x00003390000000E2ULL == (*((UInt64 *)Ptr)))
638{
639(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;
640verbose("\tKernel power management patch 10.12 DP1 found and patched\n");
641return true;
642}
643// PMheart: change for 10.13 DP1 17A264c
644else if (0x00004000000000E2ULL == (*((UInt64 *)Ptr)))
645{
646(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;
647verbose("\tKernel power management patch 10.13 DP1 found and patched\n");
648return true;
649}
650Ptr += 16;
651}
652verbose("\tKernel power management patch region not found!\n");
653return false;
654}
655
656// ===================================
657// Lapic Error Panic 64
658bool patch_lapic_init_64(void *kernelData) // KernelLapicPatch_64
659{
660// Credits to donovan6000 and Sherlocks for providing the lapic kernel patch source used to build this function
661
662UInt8 *bytes = (UInt8 *)kernelData;
663UInt32 patchLocation = 0;
664UInt32 patchLocation2 = 0;
665UInt32 i;
666UInt32 y;
667
668verbose("\t- Looking for Lapic panic call Start\n");
669
670for (i = 0; i < 0x1000000; i++)
671{
672if (KernelLapicError
673&& (bytes[i + 0] == 0x65
674&& bytes[i + 1] == 0x8B
675&& bytes[i + 2] == 0x04
676&& bytes[i + 3] == 0x25
677&& bytes[i + 4] == 0x3C
678&& bytes[i + 5] == 0x00
679&& bytes[i + 6] == 0x00
680&& bytes[i + 7] == 0x00
681&& bytes[i + 45] == 0x65
682&& bytes[i + 46] == 0x8B
683&& bytes[i + 47] == 0x04
684&& bytes[i + 48] == 0x25
685&& bytes[i + 49] == 0x3C
686&& bytes[i + 50] == 0x00
687&& bytes[i + 51] == 0x00
688&& bytes[i + 52] == 0x00))
689{
690patchLocation = i + 40;
691verbose("\tFound Lapic panic (10.6) at 0x%08X\n", (unsigned int)patchLocation);
692break;
693}
694else if (KernelLapicError
695&& (bytes[i + 0] == 0x65
696&& bytes[i + 1] == 0x8B
697&& bytes[i + 2] == 0x04
698&& bytes[i + 3] == 0x25
699&& bytes[i + 4] == 0x14
700&& bytes[i + 5] == 0x00
701&& bytes[i + 6] == 0x00
702&& bytes[i + 7] == 0x00
703&& bytes[i + 35] == 0x65
704&& bytes[i + 36] == 0x8B
705&& bytes[i + 37] == 0x04
706&& bytes[i + 38] == 0x25
707&& bytes[i + 39] == 0x14
708&& bytes[i + 40] == 0x00
709&& bytes[i + 41] == 0x00
710&& bytes[i + 42] == 0x00))
711{
712patchLocation = i + 30;
713verbose("\tFound Lapic panic (10.7 - 10.8) at 0x%08X\n", (unsigned int)patchLocation);
714break;
715}
716else if (KernelLapicError
717&& (bytes[i + 0] == 0x65
718&& bytes[i + 1] == 0x8B
719&& bytes[i + 2] == 0x04
720&& bytes[i + 3] == 0x25
721&& bytes[i + 4] == 0x1C
722&& bytes[i + 5] == 0x00
723&& bytes[i + 6] == 0x00
724&& bytes[i + 7] == 0x00
725&& bytes[i + 36] == 0x65
726&& bytes[i + 37] == 0x8B
727&& bytes[i + 38] == 0x04
728&& bytes[i + 39] == 0x25
729&& bytes[i + 40] == 0x1C
730&& bytes[i + 41] == 0x00
731&& bytes[i + 42] == 0x00
732&& bytes[i + 43] == 0x00))
733{
734patchLocation = i + 31;
735verbose("\tFound Lapic panic (10.9) at 0x%08X\n", (unsigned int)patchLocation);
736break;
737}
738 // 00 29 C7 78 XX 31 DB 8D 47 FA 83
739else if (bytes[i+0] == 0x00
740&& bytes[i+1] == 0x29
741&& bytes[i+2] == 0xC7
742&& bytes[i+3] == 0x78
743 //(bytes[i+4] == 0x3F || bytes[i+4] == 0x4F) && // 3F:10.10-10.12/4F:10.13+
744&& bytes[i+5] == 0x31
745&& bytes[i+6] == 0xDB
746&& bytes[i+7] == 0x8D
747&& bytes[i+8] == 0x47
748&& bytes[i+9] == 0xFA
749&& bytes[i+10] == 0x83) {
750 for (y = i; y < 0x1000000; y++) {
751 // Lapic panic patch, by vit9696
752 // mov eax, gs:1Ch
753 // cmp eax, cs:_master_cpu
754 // 65 8B 04 25 1C 00 00 00 3B 05 XX XX XX 00
755 if (bytes[y+0] == 0x65
756 && bytes[y+1] == 0x8B
757 && bytes[y+2] == 0x04
758 && bytes[y+3] == 0x25
759 && bytes[y+4] == 0x1C
760 && bytes[y+5] == 0x00
761 && bytes[y+6] == 0x00
762 && bytes[y+7] == 0x00
763 && bytes[y+8] == 0x3B
764 && bytes[y+9] == 0x05
765 && bytes[y+13] == 0x00) {
766 patchLocation = y;
767 verbose("\tFound Lapic panic (10.10 - recent macOS) at 0x%08X\n", (unsigned int)patchLocation);
768 break;
769 }
770 }
771 break;
772 }
773}
774
775if (!patchLocation)
776{
777verbose("\tCan't find Lapic panic, kernel patch aborted.\n");
778return false;
779}
780
781// Already patched? May be running a non-vanilla kernel already?
782
783if (bytes[patchLocation + 0] == 0x90
784&& bytes[patchLocation + 1] == 0x90
785&& bytes[patchLocation + 2] == 0x90
786&& bytes[patchLocation + 3] == 0x90
787&& bytes[patchLocation + 4] == 0x90)
788{
789verbose("\tLapic panic already patched, kernel file (10.6 - 10.9) manually patched?\n");
790return false;
791} else if (bytes[patchLocation + 0] == 0x31
792 && bytes[patchLocation + 1] == 0xC0
793 && bytes[patchLocation + 2] == 0x90
794 && bytes[patchLocation + 3] == 0x90)
795{
796verbose("\tLapic panic already patched, kernel file (10.10 - recent macOS) manually patched?\n");
797return false;
798} else {
799 if (bytes[patchLocation + 8] == 0x3B
800 && bytes[patchLocation + 9] == 0x05
801 && bytes[patchLocation + 13] == 0x00) {
802 // 65 8B 04 25 1C 00 00 00 3B XX XX XX XX 00
803 // 31 C0 90 90 90 90 90 90 90 90 90 90 90 90
804 verbose("\tPatched Lapic panic (10.10 - recent macOS)\n");
805 bytes[patchLocation + 0] = 0x31;
806 bytes[patchLocation + 1] = 0xC0;
807 for (i = 2; i < 14; i++) {
808 bytes[patchLocation + i] = 0x90;
809 }
810
811 for (i = 0; i < 0x1000000; i++) {
812 // 00 29 C7 78 XX 31 DB 8D 47 FA 83
813 if (bytes[i+0] == 0x00
814 && bytes[i+1] == 0x29
815 && bytes[i+2] == 0xC7
816 && bytes[i+3] == 0x78
817 //(bytes[i+4] == 0x3F || bytes[i+4] == 0x4F) && // 3F:10.10-10.12/4F:10.13+
818 && bytes[i+5] == 0x31
819 && bytes[i+6] == 0xDB
820 && bytes[i+7] == 0x8D
821 && bytes[i+8] == 0x47
822 && bytes[i+9] == 0xFA
823 && bytes[i+10] == 0x83) {
824 for (y = i; y < 0x1000000; y++) {
825 // Lapic panic master patch, by vit9696
826 // cmp cs:_debug_boot_arg, 0
827 // E8 XX XX FF FF 83 XX XX XX XX 00 00
828 if (bytes[y+0] == 0xE8
829 && bytes[y+3] == 0xFF
830 && bytes[y+4] == 0xFF
831 && bytes[y+5] == 0x83
832 && bytes[y+10] == 0x00
833 && bytes[y+11] == 0x00) {
834 patchLocation2 = y;
835 verbose("\tFound Lapic panic master (10.10 - recent macOS) at 0x%08X\n", (unsigned int)patchLocation2);
836 break;
837 }
838 }
839 break;
840 }
841 }
842
843 if (!patchLocation2) {
844 verbose("\tCan't find Lapic panic master (10.10 - recent macOS), kernel patch aborted.\n");
845 return false;
846 }
847
848 // Already patched? May be running a non-vanilla kernel already?
849 if (bytes[patchLocation2 + 5] == 0x31
850 && bytes[patchLocation2 + 6] == 0xC0) {
851 verbose("\tLapic panic master already patched, kernel file (10.6 - 10.9) manually patched?\n");
852 return false;
853 } else {
854 verbose("\tPatched Lapic panic master (10.10 - recent macOS)\n");
855 // E8 XX XX FF FF 83 XX XX XX XX 00 00
856 // E8 XX XX FF FF 31 C0 90 90 90 90 90
857 bytes[patchLocation2 + 5] = 0x31;
858 bytes[patchLocation2 + 6] = 0xC0;
859 for (i = 7; i < 12; i++) {
860 bytes[patchLocation2 + i] = 0x90;
861 }
862 }
863 } else {
864 verbose("\tPatched Lapic panic (10.6 - 10.9)\n");
865 for (i = 0; i < 5; i++) {
866 bytes[patchLocation + i] = 0x90;
867 }
868 }
869 }
870return true;
871}
872
873// ===================================
874// Lapic Error Panic 32
875bool patch_lapic_init_32(void *kernelData) // KernelLapicPatch_32
876{
877// Credits to donovan6000 and sherlocks for providing the lapic kernel patch source used to build this function
878
879UInt8 *bytes = (UInt8 *)kernelData;
880UInt32 patchLocation=0;
881UInt32 i;
882
883verbose("\t- Looking for Lapic panic call Start\n");
884
885for (i = 0; i < 0x1000000; i++)
886{
887if (bytes[i+0] == 0x65
888&& bytes[i+1] == 0xA1
889&& bytes[i+2] == 0x0C
890&& bytes[i+3] == 0x00
891&& bytes[i+4] == 0x00
892&& bytes[i+5] == 0x00
893&& bytes[i+30] == 0x65
894&& bytes[i+31] == 0xA1
895&& bytes[i+32] == 0x0C
896&& bytes[i+33] == 0x00
897&& bytes[i+34] == 0x00
898&& bytes[i+35] == 0x00)
899{
900patchLocation = i + 25;
901verbose("\tFound Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
902break;
903}
904}
905
906if (!patchLocation)
907{
908verbose("\tCan't find Lapic panic, kernel patch aborted.\n");
909return false;
910}
911
912// Already patched? May be running a non-vanilla kernel already?
913
914if (bytes[patchLocation + 0] == 0x90
915&& bytes[patchLocation + 1] == 0x90
916&& bytes[patchLocation + 2] == 0x90
917&& bytes[patchLocation + 3] == 0x90
918&& bytes[patchLocation + 4] == 0x90)
919{
920verbose("\tLapic panic already patched, kernel file manually patched?\n");
921return false;
922}
923else
924{
925bytes[patchLocation + 0] = 0x90;
926bytes[patchLocation + 1] = 0x90;
927bytes[patchLocation + 2] = 0x90;
928bytes[patchLocation + 3] = 0x90;
929bytes[patchLocation + 4] = 0x90;
930}
931return true;
932}
933
934// ===================================
935// Haswell-E Patch
936bool patch_haswell_E_init(void *kernelData) // KernelHaswellEPatch
937{
938// Credit to stinga11 for the patches used below
939// Based on Pike R. Alpha's Haswell patch for Mavericks
940
941UInt8*Bytes;
942UInt32Index;
943boolPatchApplied;
944
945verbose("\t- Searching for Haswell-E patch pattern\n");
946
947Bytes = (UInt8 *)kernelData;
948PatchApplied = false;
949
950for (Index = 0; Index < 0x1000000; ++Index)
951{
952// sudo perl -pi -e 's|\x74\x11\x83\xF8\x3C|\x74\x11\x83\xF8\x3F|g' /System/Library/Kernels/kernel
953if (Bytes[Index] == 0x74
954&& Bytes[Index + 1] == 0x11
955&& Bytes[Index + 2] == 0x83
956&& Bytes[Index + 3] == 0xF8
957&& Bytes[Index + 4] == 0x3C)
958{
959Bytes[Index + 4] = 0x3F;
960
961verbose("\tFound Haswell-E pattern #1; patched.\n");
962
963if (PatchApplied)
964{
965break;
966}
967
968PatchApplied = true;
969}
970
971// sudo perl -pi -e 's|\xEB\x0A\x83\xF8\x3A|\xEB\x0A\x83\xF8\x3F|g' /System/Library/Kernels/kernel
972if (Bytes[Index] == 0xEB
973&& Bytes[Index + 1] == 0x0A
974&& Bytes[Index + 2] == 0x83
975&& Bytes[Index + 3] == 0xF8
976&& Bytes[Index + 4] == 0x3A)
977{
978Bytes[Index + 4] = 0x3F;
979
980verbose("\tFound Haswell-E pattern #2; patched.\n");
981
982if (PatchApplied)
983{
984break;
985}
986
987PatchApplied = true;
988}
989}
990
991if (!PatchApplied)
992{
993verbose("\tCan't find Haswell-E patch pattern, patch not applied.\n");
994}
995
996return PatchApplied;
997}
998
999// ===================================
1000// Haswell-ULT Patch
1001bool patch_haswell_ULT_init(void *kernelData) // Fake CPUFAMILY To IVYBRIDGE Patch
1002{
1003// Credit to Tora Chi Yo for the patches used below
1004// http://www.insanelymac.com/forum/topic/307721-haswell-ult-kernel-patch-for-yosemite-mavericks
1005
1006UInt8*Bytes;
1007UInt32Index;
1008boolPatchApplied;
1009
1010verbose("\t- Searching for Haswell-ULT patch pattern\n");
1011
1012Bytes = (UInt8 *)kernelData;
1013PatchApplied = false;
1014
1015for (Index = 0; Index < 0x1000000; ++Index)
1016{
1017// sudo perl -pi -e 's|\xbb\xdc\x82\xb2\xdc|\xbb\x35\xe8\x65\x1f|g' /System/Library/Kernels/kernel
1018if (Bytes[Index] == 0xBB
1019&& Bytes[Index + 1] == 0xDC
1020&& Bytes[Index + 2] == 0x82
1021&& Bytes[Index + 3] == 0xB2
1022&& Bytes[Index + 4] == 0xdc)
1023{
1024Bytes[Index + 1] = 0x35;
1025Bytes[Index + 2] = 0xE8;
1026Bytes[Index + 3] = 0x65;
1027Bytes[Index + 4] = 0x1F;
1028
1029verbose("\tFound Haswell-ULT pattern #1; patched.\n");
1030
1031if (PatchApplied)
1032{
1033break;
1034}
1035
1036PatchApplied = true;
1037}
1038}
1039
1040if (!PatchApplied)
1041{
1042verbose("\tCan't find Haswell-ULT patch pattern, patch not applied.\n");
1043}
1044
1045return PatchApplied;
1046}
1047
1048// ===================================
1049// Custom Kext injection from Extra/Extensions folder
1050void patch_BooterExtensions_32(void *kernelData)
1051{
1052// KernelBooterExtensionsPatch to load extra kexts besides kernelcache
1053UInt8 *Bytes;
1054UInt32 Index;
1055bool PatchApplied;
1056int count = 0;
1057
1058verbose("\t- Searching for booter extensions pattern:\n");
1059
1060Bytes = (UInt8 *)kernelData;
1061PatchApplied = false;
1062
1063if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))
1064{
1065//UInt8 KBELionSearch_i386[] = { 0xE8, 0xAA, 0xFB, 0xFF, 0xFF, 0xEB, 0x08, 0x89, 0x34, 0x24 };
1066//UInt8 KBELionReplace_i386[] = { 0xE8, 0xAA, 0xFB, 0xFF, 0xFF, 0x90, 0x90, 0x89, 0x34, 0x24 };
1067for (Index = 0; Index < 0x1000000; ++Index)
1068{
1069if (Bytes[Index] == 0xE8
1070&& Bytes[Index + 1] == 0xAA
1071&& Bytes[Index + 2] == 0xFB
1072&& Bytes[Index + 3] == 0xFF
1073&& Bytes[Index + 4] == 0xFF
1074&& Bytes[Index + 5] == 0xEB
1075&& Bytes[Index + 6] == 0x08
1076&& Bytes[Index + 7] == 0x89
1077&& Bytes[Index + 8] == 0x34
1078&& Bytes[Index + 9] == 0x24)
1079{
1080Bytes[Index + 5] = 0x90;
1081Bytes[Index + 6] = 0x90;
1082count ++;
1083
1084verbose("\tFound Lion pattern: patched!\n");
1085
1086if (PatchApplied)
1087{
1088break;
1089}
1090
1091PatchApplied = true;
1092}
1093}
1094}
1095
1096/* UNDER REVIEW, crazybirdy test this patch on Snow leopard:
1097 1) He has reported has not working, but he runs the /S/L/E/Extensions.mkext: this patch allow booter extensions, so no reason to use that!
1098 2) He try to load /Extra/Extensions, but the bootloader have a bug (after the RecoveryHD code inserted) and does not load the kernelcache and scan SLE
1099
1100 need to re-try later.
1101 */
1102if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))
1103{
1104//UInt8 KBESnowSearch_i386[] = { 0xE8, 0xED, 0xF9, 0xFF, 0xFF, 0xEB, 0x08, 0x89, 0x1C, 0x24 };
1105//UInt8 KBESnowReplace_i386[] = { 0xE8, 0xED, 0xF9, 0xFF, 0xFF, 0x90, 0x90, 0x89, 0x1C, 0x24 };
1106for (Index = 0; Index < 0x1000000; ++Index)
1107{
1108if (Bytes[Index] == 0xE8
1109&& Bytes[Index + 1] == 0xED
1110&& Bytes[Index + 2] == 0xF9
1111&& Bytes[Index + 3] == 0xFF
1112&& Bytes[Index + 4] == 0xFF
1113&& Bytes[Index + 5] == 0xEB
1114&& Bytes[Index + 6] == 0x08
1115&& Bytes[Index + 7] == 0x89
1116&& Bytes[Index + 8] == 0x1C
1117&& Bytes[Index + 9] == 0x24)
1118{
1119Bytes[Index + 5] = 0x90;
1120Bytes[Index + 6] = 0x90;
1121count ++;
1122
1123verbose("\tFound Snow Leopard pattern: patched!\n");
1124
1125if (PatchApplied)
1126{
1127break;
1128}
1129
1130PatchApplied = true;
1131}
1132}
1133}
1134
1135if (!PatchApplied)
1136{
1137verbose("\tCan't find Booter Extensions patch location.\n");
1138}
1139else
1140{
1141verbose("\t%d substitution(s) made.\n", count);
1142}
1143}
1144
1145void patch_BooterExtensions_64(void *kernelData)
1146{
1147// Port from Clover 4979
1148UInt32 i;
1149UInt32 y;
1150UInt32 patchLocation = 0;
1151UInt32 patchLocation2 = 0;
1152// Port from Clover 4979
1153
1154// KernelBooterExtensionsPatch to load extra kexts besides kernelcache
1155UInt8 *Bytes;
1156UInt32 Index;
1157bool PatchApplied; // does nothing
1158int count = 0;
1159
1160verbose("\t- Searching for booter extensions pattern:\n");
1161
1162Bytes = (UInt8 *)kernelData;
1163PatchApplied = false;
1164
1165// Port from Clover 4979 start.
1166// EXT - 10.8 - recent macOS
1167if (kernelOSVer >= MacOSVer2Int("10.8"))
1168{
1169 // EXT - load extra kexts besides kernelcache.
1170 for (i = 0; i < 0x1000000; i++) {
1171 // 01 00 31 FF BE 14 00 05
1172 if (Bytes[i+0] == 0x01 && Bytes[i+1] == 0x00 && Bytes[i+2] == 0x31 &&
1173 Bytes[i+3] == 0xFF && Bytes[i+4] == 0xBE && Bytes[i+5] == 0x14 &&
1174 Bytes[i+6] == 0x00 && Bytes[i+7] == 0x05) {
1175 for (y = i; y < 0x1000000; y++) {
1176 // E8 XX 00 00 00 EB XX XX
1177 if (Bytes[y+0] == 0xE8 && Bytes[y+2] == 0x00 && Bytes[y+3] == 0x00 &&
1178 Bytes[y+4] == 0x00 && Bytes[y+5] == 0xEB) {
1179 //(Bytes[y+7] == 0x48 || Bytes[y+7] == 0xE8)) { // 48:10.8-10.9/E8:10.10+
1180 patchLocation = y;
1181 break;
1182 }
1183 }
1184 break;
1185 }
1186 }
1187 if (patchLocation) {
1188 verbose("\tFound EXT pattern (10.8 - recent macOS): patched!\n");
1189 for (i = 5; i < 7; i++) {
1190 // E8 XX 00 00 00 EB XX
1191 // E8 XX 00 00 00 90 90
1192 Bytes[patchLocation + i] = 0x90;
1193 }
1194 count++;
1195 PatchApplied = true;
1196 }
1197}
1198
1199// SIP - 10.11 - recent macOS
1200if (kernelOSVer >= MacOSVer2Int("10.11"))
1201{
1202 // SIP - bypass kext check by System Integrity Protection.
1203 for (i = 0; i < 0x1000000; ++i) {
1204 // 45 31 FF 41 XX 01 00 00 DC 48
1205 if (Bytes[i + 0] == 0x45 && Bytes[i + 1] == 0x31 && Bytes[i + 3] == 0x41 &&
1206 //(Bytes[i + 4] == 0xBF || Bytes[i + 4] == 0xBE) && // BF:10.11/BE:10.12+
1207 Bytes[i + 5] == 0x01 && Bytes[i + 6] == 0x00 && Bytes[i + 7] == 0x00 &&
1208 Bytes[i + 8] == 0xDC && Bytes[i + 9] == 0x48) {
1209 for (y = i; y < 0x1000000; ++y) {
1210 // 48 85 XX 74 XX 48 XX XX 48
1211 if (Bytes[y+0] == 0x48 && Bytes[y+1] == 0x85 && Bytes[y+3] == 0x74 &&
1212 Bytes[y+5] == 0x48 && Bytes[y+8] == 0x48) {
1213 patchLocation2 = y;
1214 break;
1215 // 00 85 C0 0F 84 XX 00 00 00 49
1216 } else if (Bytes[y+0] == 0x00 && Bytes[y+1] == 0x85 && Bytes[y+2] == 0xC0 &&
1217 Bytes[y+3] == 0x0F && Bytes[y+4] == 0x84 && Bytes[y+9] == 0x49) {
1218 patchLocation2 = y;
1219 break;
1220 }
1221 }
1222 }
1223 }
1224 if (patchLocation2) {
1225 if (Bytes[patchLocation2 + 0] == 0x48 && Bytes[patchLocation2 + 1] == 0x85) {
1226 Bytes[patchLocation2 + 3] = 0xEB;
1227 verbose("\tFound SIP pattern (10.11 - 10.14): patched!\n");
1228 if (Bytes[patchLocation2 + 4] == 0x6C) {
1229 // 48 85 XX 74 6C 48 XX XX 48
1230 // 48 85 XX EB 15 48 XX XX 48
1231 Bytes[patchLocation2 + 4] = 0x15; // 10.14.4-10.14.6
1232 } else {
1233 // 48 85 XX 74 XX 48 XX XX 48
1234 // 48 85 XX EB 12 48 XX XX 48
1235 Bytes[patchLocation2 + 4] = 0x12; // 10.11-10.14.3
1236 }
1237 count++;
1238 PatchApplied = true;
1239 // PMheart
1240 } else if (Bytes[patchLocation2 + 0] == 0x00 && Bytes[patchLocation2 + 1] == 0x85) {
1241 verbose("\tFound SIP pattern (10.15 - recent macOS): patched!\n");
1242 for (i = 3; i < 9; i++) {
1243 // 00 85 C0 0F 84 XX 00 00 00 49
1244 // 00 85 C0 90 90 90 90 90 90 49
1245 Bytes[patchLocation2 + i] = 0x90;
1246 }
1247 count++;
1248 PatchApplied = true;
1249 }
1250 }
1251 }
1252 // Port from Clover 4979 end.
1253
1254// Lion 64
1255if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))
1256{
1257for (Index = 0; Index < 0x1000000; ++Index)
1258{
1259if (Bytes[Index] == 0xE8
1260&& Bytes[Index + 1] == 0x0C
1261&& Bytes[Index + 2] == 0xFD
1262&& Bytes[Index + 3] == 0xFF
1263&& Bytes[Index + 4] == 0xFF
1264&& Bytes[Index + 5] == 0xEB
1265&& Bytes[Index + 6] == 0x08
1266&& Bytes[Index + 7] == 0x48
1267&& Bytes[Index + 8] == 0x89
1268&& Bytes[Index + 9] == 0xDF)
1269{
1270Bytes[Index + 5] = 0x90;
1271Bytes[Index + 6] = 0x90;
1272count++;
1273
1274verbose("\tFound Lion EXT pattern: patched!\n");
1275
1276if (PatchApplied)
1277{
1278break;
1279}
1280
1281PatchApplied = true;
1282}
1283}
1284}
1285
1286// Snow Leopard 64
1287if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))
1288{
1289for (Index = 0; Index < 0x1000000; ++Index)
1290{
1291if (Bytes[Index] == 0xE8
1292&& Bytes[Index + 1] == 0x5A
1293&& Bytes[Index + 2] == 0xFB
1294&& Bytes[Index + 3] == 0xFF
1295&& Bytes[Index + 4] == 0xFF
1296&& Bytes[Index + 5] == 0xEB
1297&& Bytes[Index + 6] == 0x08
1298&& Bytes[Index + 7] == 0x48
1299&& Bytes[Index + 8] == 0x89
1300&& Bytes[Index + 9] == 0xDF)
1301{
1302Bytes[Index + 5] = 0x90;
1303Bytes[Index + 6] = 0x90;
1304verbose("\tFound Snow Leopard EXT pattern: patched!\n");
1305count++;
1306
1307if (PatchApplied)
1308{
1309break;
1310}
1311
1312PatchApplied = true;
1313}
1314}
1315}
1316
1317if (!PatchApplied)
1318{
1319verbose("\tCan't find Booter Extensions patch location.\n");
1320}
1321else
1322{
1323verbose("\t%d substitution(s) made.\n", count);
1324}
1325}
1326
1327// ===================================
1328// Patch ssse3
1329void patch_SSE3_6(void *kernelData)
1330{
1331UInt8 *bytes = (UInt8 *)kernelData;
1332UInt32 patchLocation1 = 0;
1333UInt32 patchLocation2 = 0;
1334UInt32 patchlast = 0;
1335UInt32 i;
1336//UInt32 Length = sizeof(kernelData);
1337
1338verbose("\t- Start find SSE3 address\n");
1339i = 0;
1340//for (i = 0; i < Length; i++)
1341while(true)
1342{
1343if (bytes[i] == 0x66
1344&& bytes[i + 1] == 0x0F
1345&& bytes[i + 2] == 0x6F
1346&& bytes[i + 3] == 0x44
1347&& bytes[i + 4] == 0x0E
1348&& bytes[i + 5] == 0xF1
1349&& bytes[i - 1664 - 32] == 0x55)
1350{
1351patchLocation1 = i-1664-32;
1352verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);
1353}
1354
1355// hasSSE2+..... title
1356if (bytes[i] == 0xE3
1357&& bytes[i + 1] == 0x07
1358&& bytes[i + 2] == 0x00
1359&& bytes[i + 3] == 0x00
1360&& bytes[i + 4] == 0x80
1361&& bytes[i + 5] == 0x07
1362&& bytes[i + 6] == 0xFF
1363&& bytes[i + 7] == 0xFF
1364&& bytes[i + 8] == 0x24
1365&& bytes[i + 9] == 0x01)
1366{
1367patchLocation2 = i;
1368verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);
1369break;
1370}
1371i++;
1372}
1373
1374if (!patchLocation1 || !patchLocation2)
1375{
1376verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);
1377return;
1378}
1379
1380verbose("\tFound SSE3 last data addres Start\n");
1381i = patchLocation1 + 1500;
1382//for (i=(patchLocation1+1500); i<(patchLocation1+3000); i++)
1383while(true)
1384{
1385if (bytes[i] == 0x90
1386&& bytes[i + 1] == 0x90
1387&& bytes[i + 2] == 0x55 )
1388{
1389patchlast = (i+1) - patchLocation1;
1390verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);
1391break;
1392}
1393i++;
1394}
1395
1396if (!patchlast)
1397{
1398verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);
1399return;
1400}
1401// patch sse3_64 data
1402
1403for (i = 0; i < patchlast; i++)
1404{
1405if (i < sizeof(sse3_patcher))
1406{
1407bytes[patchLocation1 + i] = sse3_patcher[i];
1408}
1409else
1410{
1411bytes[patchLocation1 + i] = 0x90;
1412}
1413}
1414
1415// patch kHasSSE3 title
1416bytes[patchLocation2 + 0] = 0xFC;
1417bytes[patchLocation2 + 1] = 0x05;
1418bytes[patchLocation2 + 8] = 0x2C;
1419bytes[patchLocation2 + 9] = 0x00;
1420
1421}
1422
1423// ===================================
1424//
1425void patch_SSE3_5(void *kernelData)
1426{
1427UInt8 *bytes = (UInt8 *)kernelData;
1428UInt32 patchLocation1 = 0;
1429UInt32 patchLocation2 = 0;
1430UInt32 patchlast=0;
1431UInt32 Length = sizeof(kernelData);
1432UInt32 i;
1433
1434verbose("\t- Start find SSE3 address\n");
1435
1436for (i = 256; i < (Length-256); i++)
1437{
1438if (bytes[i] == 0x66
1439&& bytes[i + 1] == 0x0F
1440&& bytes[i + 2] == 0x6F
1441&& bytes[i + 3] == 0x44
1442&& bytes[i + 4] == 0x0E
1443&& bytes[i + 5] == 0xF1
1444&& bytes[i - 1680 - 32] == 0x55)
1445{
1446patchLocation1 = i-1680-32;
1447verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);
1448}
1449
1450// khasSSE2+..... title
1451if (bytes[i] == 0xF3
1452&& bytes[i + 1] == 0x07
1453&& bytes[i + 2] == 0x00
1454&& bytes[i + 3] == 0x00
1455&& bytes[i + 4] == 0x80
1456&& bytes[i + 5] == 0x07
1457&& bytes[i + 6] == 0xFF
1458&& bytes[i + 7] == 0xFF
1459&& bytes[i + 8] == 0x24
1460&& bytes[i + 9] == 0x01)
1461{
1462patchLocation2 = i;
1463verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);
1464break;
1465}
1466}
1467
1468if (!patchLocation1 || !patchLocation2)
1469{
1470verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);
1471return;
1472}
1473
1474verbose("\tFound SSE3 last data addres Start\n");
1475
1476for (i = (patchLocation1+1500);i < Length;i++)
1477{
1478if (bytes[i] == 0x90
1479&& bytes[i + 1] == 0x90
1480&& bytes[i + 2] == 0x55)
1481{
1482patchlast = (i+1) - patchLocation1;
1483verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);
1484break;
1485}
1486}
1487
1488if (!patchlast)
1489{
1490verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);
1491return;
1492}
1493
1494// patech sse3_64 data
1495
1496for (i = 0; i < patchlast; i++)
1497{
1498if (i < sizeof(sse3_5_patcher))
1499{
1500bytes[patchLocation1 + i] = sse3_5_patcher[i];
1501}
1502else
1503{
1504bytes[patchLocation1 + i] = 0x90;
1505}
1506}
1507
1508// patch kHasSSE3 title
1509bytes[patchLocation2 + 0] = 0x0C;
1510bytes[patchLocation2 + 1] = 0x06;
1511bytes[patchLocation2 + 8] = 0x2C;
1512bytes[patchLocation2 + 9] = 0x00;
1513
1514}
1515
1516// ===================================
1517//
1518void patch_SSE3_7(void *kernelData)
1519{
1520// not support yet
1521return;
1522}
1523
1524// ===================================
1525// root:xnu text replacement Patch
1526bool patch_string_XNU_init(void *kernelData) //
1527{
1528
1529UInt8*Bytes;
1530UInt32Index;
1531boolPatchApplied;
1532
1533DBG("\t- Searching for \"root:xnu-\" string pattern\n");
1534
1535Bytes = (UInt8 *)kernelData;
1536PatchApplied = false;
1537
1538for (Index = 0; Index < 0x1000000; ++Index)
1539{
1540// search for root:xnu- and replace it with ***Enoch-
1541if (Bytes[Index] == ' '
1542&& Bytes[Index + 1] == 'r'
1543&& Bytes[Index + 2] == 'o'
1544&& Bytes[Index + 3] == 'o'
1545&& Bytes[Index + 4] == 't'
1546&& Bytes[Index + 5] == ':'
1547&& Bytes[Index + 6] == 'x'
1548&& Bytes[Index + 7] == 'n'
1549&& Bytes[Index + 8] == 'u'
1550&& Bytes[Index + 9] == '-' )
1551{
1552Bytes[Index + 1] = '*';
1553Bytes[Index + 2] = '*';
1554Bytes[Index + 3] = '*';
1555Bytes[Index + 4] = 'E';
1556Bytes[Index + 5] = 'n';
1557Bytes[Index + 6] = 'o';
1558Bytes[Index + 7] = 'c';
1559Bytes[Index + 8] = 'h';
1560
1561DBG("\tFound \"root:xnu-\" pattern; patched.\n");
1562
1563if (PatchApplied)
1564{
1565break;
1566}
1567
1568PatchApplied = true;
1569}
1570}
1571
1572if (!PatchApplied)
1573{
1574DBG("\tCan't find \"root:xnu-\" string pattern: patch not applied.\n");
1575}
1576
1577return PatchApplied;
1578}
1579
1580// ===================================
1581// (Clover)
1582// Patching AppleRTC to prevent CMOS reset
1583unsigned int AppleRTC_Patch(void *data, UInt32 DriverSize, UInt32 StartLocation)
1584{
1585 unsigned int count = 0;
1586 // as far as I know this works from Lion to Sierra
1587 UInt8 LionSearch_X64[] = { 0x75, 0x30, 0x44, 0x89, 0xf8 };
1588 UInt8 LionReplace_X64[] = { 0xeb, 0x30, 0x44, 0x89, 0xf8 };
1589
1590 UInt8 LionSearch_i386[] = { 0x75, 0x3d, 0x8b, 0x75, 0x08 };
1591 UInt8 LionReplace_i386[] = { 0xeb, 0x3d, 0x8b, 0x75, 0x08 };
1592
1593 UInt8 MLSearch[] = { 0x75, 0x30, 0x89, 0xd8 };
1594 UInt8 MLReplace[] = { 0xeb, 0x30, 0x89, 0xd8 };
1595 //SunKi
1596 //752e0fb6 -> eb2e0fb6
1597 UInt8 MavSearch[] = { 0x75, 0x2e, 0x0f, 0xb6 };
1598 UInt8 MavReplace[] = { 0xeb, 0x2e, 0x0f, 0xb6};
1599
1600 if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))
1601 {
1602 count = FindAndReplace(data,
1603 DriverSize,
1604 StartLocation,
1605 LionSearch_i386,
1606 sizeof(LionSearch_i386),
1607 LionReplace_i386,
1608 0);
1609
1610 count = count + FindAndReplace(data,
1611 DriverSize,
1612 StartLocation,
1613 LionSearch_X64,
1614 sizeof(LionSearch_X64),
1615 LionReplace_X64,
1616 0);
1617 }
1618 else
1619 if (kernelOSVer >= MacOSVer2Int("10.8") && kernelOSVer < MacOSVer2Int("10.9"))
1620 {
1621 count = FindAndReplace(data,
1622 DriverSize,
1623 StartLocation,
1624 MLSearch,
1625 sizeof(MLSearch),
1626 MLReplace,
1627 0);
1628 }
1629 else
1630 if (kernelOSVer >= MacOSVer2Int("10.9"))
1631 {
1632 count = FindAndReplace(data,
1633 DriverSize,
1634 StartLocation,
1635 MavSearch,
1636 sizeof(MavSearch),
1637 MavReplace,
1638 0);
1639 }
1640
1641 return count;
1642}
1643
1644// ===================================
1645// (Clover)
1646// Patching AppleIntelCPUPowerManagement
1647unsigned int AsusAICPUPMPatch(void *data, UInt32 DriverSize, UInt32 StartLocation)
1648{
1649 unsigned int Index1;
1650 unsigned int Index2;
1651 unsigned int Count = 0;
1652
1653 UInt8 MovlE2ToEcx[] = { 0xB9, 0xE2, 0x00, 0x00, 0x00 };
1654 UInt8 MovE2ToCx[] = { 0x66, 0xB9, 0xE2, 0x00 };
1655 UInt8 Wrmsr[] = { 0x0F, 0x30 };
1656
1657 UInt8*Driver = (UInt8 *)data;
1658
1659 //TODO: we should scan only __text __TEXT
1660 for (Index1 = StartLocation; Index1 < (StartLocation+DriverSize); Index1++)
1661 {
1662 // search for MovlE2ToEcx
1663 if (memcmp(Driver + Index1, MovlE2ToEcx, sizeof(MovlE2ToEcx)) == 0)
1664 {
1665 // search for wrmsr in next few bytes
1666 for (Index2 = Index1 + sizeof(MovlE2ToEcx); Index2 < Index1 + sizeof(MovlE2ToEcx) + 32; Index2++)
1667 {
1668 if (Driver[Index2] == Wrmsr[0] && Driver[Index2 + 1] == Wrmsr[1])
1669 {
1670 // found it - patch it with nops
1671 Count++;
1672 Driver[Index2] = 0x90;
1673 Driver[Index2 + 1] = 0x90;
1674 verbose("\t%d wrmsr patched at 0x%X\n", Count, Index2);
1675 break;
1676 } else if ((Driver[Index2] == 0xC9 && Driver[Index2 + 1] == 0xC3) ||
1677 (Driver[Index2] == 0x5D && Driver[Index2 + 1] == 0xC3) ||
1678 (Driver[Index2] == 0xB9 && Driver[Index2 + 3] == 0 && Driver[Index2 + 4] == 0) ||
1679 (Driver[Index2] == 0x66 && Driver[Index2 + 1] == 0xB9 && Driver[Index2 + 3] == 0))
1680 {
1681 // a leave/ret will cancel the search
1682 // so will an intervening "mov[l] $xx, [e]cx"
1683 break;
1684 }
1685 }
1686 } else if (memcmp(Driver + Index1, MovE2ToCx, sizeof(MovE2ToCx)) == 0)
1687 {
1688 // search for wrmsr in next few bytes
1689 for (Index2 = Index1 + sizeof(MovE2ToCx); Index2 < Index1 + sizeof(MovE2ToCx) + 32; Index2++)
1690 {
1691 if (Driver[Index2] == Wrmsr[0] && Driver[Index2 + 1] == Wrmsr[1])
1692 {
1693 // found it - patch it with nops
1694 Count++;
1695 Driver[Index2] = 0x90;
1696 Driver[Index2 + 1] = 0x90;
1697 verbose("\t%d wrmsr patched at 0x%X\n", Count, Index2);
1698 break;
1699 } else if ((Driver[Index2] == 0xC9 && Driver[Index2 + 1] == 0xC3) ||
1700 (Driver[Index2] == 0x5D && Driver[Index2 + 1] == 0xC3) ||
1701 (Driver[Index2] == 0xB9 && Driver[Index2 + 3] == 0 && Driver[Index2 + 4] == 0) ||
1702 (Driver[Index2] == 0x66 && Driver[Index2 + 1] == 0xB9 && Driver[Index2 + 3] == 0))
1703 {
1704 // a leave/ret will cancel the search
1705 // so will an intervening "mov[l] $xx, [e]cx"
1706 break;
1707 }
1708 }
1709 }
1710 }
1711
1712 return Count;
1713}
1714
1715// ===================================
1716// Patching IOAHCIBlockStorage to enable the trim support
1717unsigned int trimEnablerSata(void *data, UInt32 DriverSize, UInt32 StartLocation)
1718{
1719 // as far as I know this works from Lion to Sierra
1720 UInt8 Find[] = { 0x00, 0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x53, 0x53, 0x44, 0x00 };
1721
1722 UInt8 Replace[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1723 unsigned int count = FindAndReplace(data,
1724 DriverSize,
1725 StartLocation,
1726 Find,
1727 sizeof(Find),
1728 Replace,
1729 0);
1730
1731 return count;
1732}
1733
1734// ===================================
1735// Patching AppleAHCIPort to fix orange icon (Sata only)
1736unsigned int patch_AppleAHCIPort_OrangeFix(void *data, UInt32 DriverSize, UInt32 StartLocation)
1737{
1738 // as far as I know this works from lion onward
1739 UInt8 Find[] = { 0x45, 0x78, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C };
1740 UInt8 Replace[] = { 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C };
1741 unsigned int count = FindAndReplace(data,
1742 DriverSize,
1743 StartLocation,
1744 Find,
1745 sizeof(Find),
1746 Replace,
1747 0);
1748
1749 return count;
1750}
1751
1752// ===================================
1753// (Micky1979)
1754// Patching NVDAStartupWeb
1755unsigned int patch_NVDAStartupWeb(void *data, UInt32 DriverSize, UInt32 StartLocation)
1756{
1757 unsigned int count = 0;
1758 // this patch is needed only in Sierra onward
1759 if (MacOSVerCurrent >= MacOSVer2Int("10.12"))
1760 {
1761 Node *nvdadrvNode = DT__FindNode("/nvdadrv", true);
1762 if (nvdadrvNode != 0)
1763 {
1764 DT__AddProperty(nvdadrvNode, "nvda_drv", strlen(NVDAVALUE), (void*)NVDAVALUE);
1765 UInt8 Find[] = { 0x49, 0x4F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65,
1766 0x3A, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x00, 0x4E, 0x56,
1767 0x44, 0x41, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x57, 0x65, 0x62,
1768 0x3A };
1769
1770 UInt8 Replace[] = { 0x49, 0x4F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65,
1771 0x3A, 0x2F, 0x6E, 0x76, 0x64, 0x61, 0x64, 0x72, 0x76, 0x00, 0x4E, 0x56,
1772 0x44, 0x41, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x57, 0x65, 0x62,
1773 0x3A };
1774 count = FindAndReplace(data,
1775 DriverSize,
1776 StartLocation,
1777 Find,
1778 sizeof(Find),
1779 Replace,
1780 0);
1781 }
1782 else
1783 {
1784 verbose("Error: Unable to add nvdadrv node\n");
1785 }
1786
1787 }
1788 return count;
1789}
1790
1791// ===================================
1792// Micky1979, 2017
1793// patch_prelinked_kexts
1794void patch_prelinked_kexts(void *kernelData,
1795 u_int32_t uncompressed_size,
1796 unsigned prelinkTextVmaddr,
1797 unsigned prelinkTextFileOff)
1798{
1799 TagPtr KextsPatches;
1800 bool canPatchKexts = false;
1801 unsigned long prelinkDictSize;
1802 unsigned int Index;
1803 unsigned int Count = 0;
1804
1805 UInt8 *Bytes = (UInt8 *)kernelData;
1806
1807 UInt8 *prelinkDic = NULL;
1808 UInt32 prelinkDictStartLocation = 0;
1809 UInt32 prelinkDictEndLocation = 0;
1810
1811
1812 if (bootInfo->kextConfig.dictionary)
1813 {
1814KextsPatches = XMLGetProperty(bootInfo->kextConfig.dictionary, (const char*)"KextsPatches");
1815 }
1816
1817 verbose("[ KEXTS PATCHER START ]\n");
1818 //int lessBytes = (int)((uncompressed_size/3)*2); // speedup, the _PrelinkInfoDictionary should not be 1/3 of entire cache!
1819 for (Index = 0/*lessBytes*/; Index < uncompressed_size; ++Index)
1820 {
1821 // scan for _PrelinkInfoDictionary
1822 // <dict><key>_PrelinkInfoDictionary</key>
1823 // 3C 64 69 63 74 3E 3C 6B 65 79 3E 5F 50 72 65 6C 69 6E 6B 49 6E 66 6F 44 69 63 74 69 6F 6E 61 72 79 3C 2F 6B 65 79 3E
1824 if (Bytes[Index] == 0x3C
1825 && Bytes[Index + 1] == 0x64
1826 && Bytes[Index + 2] == 0x69
1827 && Bytes[Index + 3] == 0x63
1828 && Bytes[Index + 4] == 0x74
1829 && Bytes[Index + 5] == 0x3E
1830 && Bytes[Index + 6] == 0x3C
1831 && Bytes[Index + 7] == 0x6B
1832 && Bytes[Index + 8] == 0x65
1833 && Bytes[Index + 9] == 0x79
1834 && Bytes[Index + 10] == 0x3E
1835 && Bytes[Index + 11] == 0x5F
1836 && Bytes[Index + 12] == 0x50
1837 && Bytes[Index + 13] == 0x72
1838 && Bytes[Index + 14] == 0x65
1839 && Bytes[Index + 15] == 0x6C
1840 && Bytes[Index + 16] == 0x69
1841 && Bytes[Index + 17] == 0x6E
1842 && Bytes[Index + 18] == 0x6B
1843 && Bytes[Index + 19] == 0x49
1844 && Bytes[Index + 20] == 0x6E
1845 && Bytes[Index + 21] == 0x66
1846 && Bytes[Index + 22] == 0x6F
1847 && Bytes[Index + 23] == 0x44
1848 && Bytes[Index + 24] == 0x69
1849 && Bytes[Index + 25] == 0x63
1850 && Bytes[Index + 26] == 0x74
1851 && Bytes[Index + 27] == 0x69
1852 && Bytes[Index + 28] == 0x6F
1853 && Bytes[Index + 29] == 0x6E
1854 && Bytes[Index + 30] == 0x61
1855 && Bytes[Index + 31] == 0x72
1856 && Bytes[Index + 32] == 0x79
1857 && Bytes[Index + 33] == 0x3C
1858 && Bytes[Index + 34] == 0x2F
1859 && Bytes[Index + 35] == 0x6B
1860 && Bytes[Index + 36] == 0x65
1861 && Bytes[Index + 37] == 0x79
1862 && Bytes[Index + 38] == 0x3E)
1863 {
1864 Count++;
1865 prelinkDictStartLocation = Index;
1866 DBG("\tFound _PrelinkInfoDictionary at 0x%08X index = %d\n", (unsigned int)prelinkDictStartLocation, Index);
1867 canPatchKexts = true;
1868 break;
1869 }
1870 }
1871
1872 if (prelinkDictStartLocation)
1873 {
1874 for (Index = prelinkDictStartLocation; Index < uncompressed_size; ++Index)
1875 {
1876 // end of prelink ( <> plus some zeros)
1877 // </dict>
1878 // 3C 2F 64 69 63 74 3E 00 00 00 00 00 00 00
1879 if (Bytes[Index] == 0x3C
1880 && Bytes[Index + 1] == 0x2F
1881 && Bytes[Index + 2] == 0x64
1882 && Bytes[Index + 3] == 0x69
1883 && Bytes[Index + 4] == 0x63
1884 && Bytes[Index + 5] == 0x74
1885 && Bytes[Index + 6] == 0x3E
1886 && Bytes[Index + 7] == 0x00
1887 && Bytes[Index + 8] == 0x00
1888 && Bytes[Index + 9] == 0x00
1889 && Bytes[Index + 10] == 0x00
1890 && Bytes[Index + 11] == 0x00
1891 && Bytes[Index + 12] == 0x00
1892 && Bytes[Index + 13] == 0x00)
1893 {
1894 Count++;
1895
1896 if ((Count = 2))
1897 {
1898 canPatchKexts = true;
1899 prelinkDictEndLocation = Index + 7 ;
1900 DBG("\tFound _PrelinkInfoDictionary end location at 0x%08X index = %d\n", (unsigned int)prelinkDictEndLocation, Index);
1901 }
1902 break;
1903 }
1904 }
1905 }
1906
1907 if (canPatchKexts)
1908 {
1909 prelinkDictSize = uncompressed_size - prelinkDictStartLocation;
1910 prelinkDic = malloc(prelinkDictSize);
1911 memcpy(prelinkDic, Bytes+prelinkDictStartLocation, prelinkDictSize);
1912 TagPtr prelinkInfoPtr = NULL;
1913 XMLParseFile( (char *)prelinkDic, &prelinkInfoPtr );
1914
1915 if (prelinkInfoPtr)
1916 {
1917 TagPtr prelinkInfoDictionary = XMLGetProperty(prelinkInfoPtr, "_PrelinkInfoDictionary");
1918 if (!prelinkInfoDictionary)
1919 {
1920 verbose("Unable to allocate the _PrelinkInfoDictionary, kexts patcher skipped.");
1921 return;
1922 }
1923 int count = XMLTagCount(prelinkInfoDictionary);
1924 while(count)
1925 {
1926 TagPtr sub = XMLGetElement( prelinkInfoDictionary, count-1);
1927 if (sub && XMLIsDict(sub))
1928 {
1929 char* execPath = XMLCastString(XMLGetProperty(sub, (const char*)"CFBundleExecutable"));
1930
1931 if (execPath != NULL)
1932 {
1933 UInt32 kextSize = XMLCastInteger(XMLGetProperty(sub, (const char*)"_PrelinkExecutableSize"));
1934 UInt32 kextAddr = XMLCastInteger(XMLGetProperty(sub, (const char*)"_PrelinkExecutableSourceAddr"));
1935
1936
1937 if (kextAddr && kextSize)
1938 {
1939 // adjust binary address location
1940 kextAddr -= prelinkTextVmaddr;
1941 kextAddr += prelinkTextFileOff;
1942
1943 DBG("\t[%d] found exec:%s (size = %u, kextAddr = 0x%X [vmaddr = 0x%X fileoff = 0x%X])\n", count, execPath,
1944 (unsigned int)kextSize, (unsigned int)kextAddr, (unsigned int)prelinkTextVmaddr, (unsigned int)prelinkTextFileOff);
1945
1946 if (!strcmp(execPath, "FakeSMC"))
1947 {
1948 FakeSMCLoaded = true;
1949 }
1950
1951// chameleon patches
1952patchBooterDefinedKext(execPath, kernelData, kextSize, kextAddr);
1953
1954 // user's defined
1955 if (KextsPatches && XMLIsDict(KextsPatches))
1956 {
1957 pach_binaryUsingDictionary(kernelData,
1958 kextSize,
1959 kextAddr,
1960 execPath,
1961 KextsPatches);
1962 }
1963
1964#if DEBUG_KERNEL
1965 getchar();
1966#endif
1967 }
1968 }
1969 }
1970
1971 count --;
1972 }
1973 }
1974 }
1975 else
1976 {
1977 verbose("Unable to find the _PrelinkInfoDictionary, kexts patcher skipped.");
1978 }
1979
1980 if (prelinkDic) free(prelinkDic);
1981 verbose("Kexts patcher: end!\n\n");
1982}
1983
1984void patchBooterDefinedKext(const char *kext, void *driverAddr, UInt32 DriverSize, UInt32 StartLocation)
1985{
1986if ((!strcmp(kext, "AppleRTC")) && AppleRTCPatch)
1987{
1988verbose("\tPatching %s:", kext);
1989
1990unsigned int numPatches = AppleRTC_Patch(driverAddr, DriverSize, StartLocation);
1991verbose(" %d substitutions made!\n", numPatches);
1992}
1993
1994if ((!strcmp(kext, "AppleIntelCPUPowerManagement")) && AICPMPatch)
1995{
1996verbose("\tPatching %s (locked msr):\n", kext);
1997
1998unsigned int numPatches = AsusAICPUPMPatch(driverAddr, DriverSize, StartLocation);
1999verbose("\t %d substitutions made!\n", numPatches);
2000}
2001
2002if ((!strcmp(kext, "NVDAStartupWeb")) && NVIDIAWebDrv)
2003{
2004verbose("\tPatching %s (force load w/o nvram):\n", kext);
2005
2006unsigned int numPatches = patch_NVDAStartupWeb(driverAddr, DriverSize, StartLocation);
2007verbose("\t %d substitutions made!\n", numPatches);
2008}
2009
2010if ((!strcmp(kext, "IOAHCIBlockStorage")) && TrimEnablerSata)
2011{
2012verbose("\tPatching %s (trim enabler SATA):", kext);
2013
2014unsigned int numPatches = trimEnablerSata(driverAddr, DriverSize, StartLocation);
2015verbose(" %d substitutions made!\n", numPatches);
2016}
2017
2018if ((!strcmp(kext, "AppleAHCIPort")) && OrangeIconFixSata)
2019{
2020verbose("\tPatching %s (orange icon fix):", kext);
2021
2022unsigned int numPatches = patch_AppleAHCIPort_OrangeFix(driverAddr, DriverSize, StartLocation);
2023verbose(" %d substitutions made!\n", numPatches);
2024}
2025}
2026
2027// ===================================
2028// Boolean function to check the full OSX match version
2029bool checkFullOSVer(const char *version)
2030{
2031// We are in a version with 7 char ?
2032if ( (sizeof(version) == 7) && ('.' == version[5]) && ('\0' != version[6]) ) // 10.xx.x
2033{
2034return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2035&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2036&& (gBootVolume->OSFullVer[2] == version[2]) // .
2037&& (gBootVolume->OSFullVer[3] == version[3]) // x
2038&& (gBootVolume->OSFullVer[4] == version[4]) // x
2039&& (gBootVolume->OSFullVer[5] == version[5]) // .
2040&& (gBootVolume->OSFullVer[6] == version[6]) // x
2041);
2042}
2043
2044// We are in a version with 7 char ?
2045if ( (sizeof(version) == 7) && ('.' == version[4]) && ('\0' != version[6]) ) // 10.4.11
2046{
2047return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2048&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2049&& (gBootVolume->OSFullVer[2] == version[2]) // .
2050&& (gBootVolume->OSFullVer[3] == version[3]) // 4
2051&& (gBootVolume->OSFullVer[4] == version[4]) // .
2052&& (gBootVolume->OSFullVer[5] == version[5]) // x
2053&& (gBootVolume->OSFullVer[6] == version[6]) // x
2054);
2055}
2056
2057// We are in a version with 6 char ?
2058if ( (sizeof(version) == 6) && ('.' == version[4]) && ('\0' != version[5]) ) // 10.x.x
2059{
2060return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2061&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2062&& (gBootVolume->OSFullVer[2] == version[2]) // .
2063&& (gBootVolume->OSFullVer[3] == version[3]) // x
2064&& (gBootVolume->OSFullVer[4] == version[4]) // .
2065&& (gBootVolume->OSFullVer[5] == version[5]) // x
2066);
2067}
2068
2069// We are in a version with 5 char ?
2070if ( (sizeof(version) == 5) && ('.' != version[4]) && ('\0' != version[4]) ) // 10.xx
2071{
2072return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2073&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2074&& (gBootVolume->OSFullVer[2] == version[2]) // .
2075&& (gBootVolume->OSFullVer[3] == version[3]) // x
2076&& (gBootVolume->OSFullVer[4] == version[4]) // x
2077);
2078}
2079
2080// We are in a version with 4 char ?
2081if ( (sizeof(version) == 4) && ('\0' != version[3]) ) // 10.x
2082{
2083return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2084&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2085&& (gBootVolume->OSFullVer[2] == version[2]) // .
2086&& (gBootVolume->OSFullVer[3] == version[3]) // x
2087);
2088}
2089
2090// no match found
2091return false;
2092}
2093

Archive Download this file

Revision: HEAD