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

Archive Download this file

Revision: 2894