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.14") && kernelOSVer < MacOSVer2Int("10.15"))
763{
764verbose("\tFound Mojave Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);
765}
766else if (kernelOSVer >= MacOSVer2Int("10.13") && kernelOSVer < MacOSVer2Int("10.14"))
767{
768verbose("\tFound High Sierra Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);
769}
770else if (kernelOSVer >= MacOSVer2Int("10.12") && kernelOSVer < MacOSVer2Int("10.13"))
771{
772verbose("\tFound Sierra Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);
773}
774else
775{
776verbose("\tFound El Capitan Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);
777}
778
779break;
780}
781}
782
783if (!patchLocation)
784{
785verbose("\tCan't find Lapic Version panic, kernel patch aborted.\n");
786return false;
787}
788
789// Already patched? May be running a non-vanilla kernel already?
790
791if (bytes[patchLocation + 0] == 0x90
792&& bytes[patchLocation + 1] == 0x90
793&& bytes[patchLocation + 2] == 0x90
794&& bytes[patchLocation + 3] == 0x90
795&& bytes[patchLocation + 4] == 0x90)
796{
797verbose("\tLapic Version panic already patched, kernel file manually patched?\n");
798return false;
799}
800else
801{
802bytes[patchLocation + 0] = 0x90;
803bytes[patchLocation + 1] = 0x90;
804bytes[patchLocation + 2] = 0x90;
805bytes[patchLocation + 3] = 0x90;
806bytes[patchLocation + 4] = 0x90;
807}
808return true;
809}
810
811// ===================================
812// Lapic Error Panic 64
813bool patch_lapic_init_64(void *kernelData) // KernelLapicPatch_64
814{
815// Credits to donovan6000 and Sherlocks for providing the lapic kernel patch source used to build this function
816
817UInt8 *bytes = (UInt8 *)kernelData;
818UInt32 patchLocation = 0;
819UInt32 i;
820
821verbose("\t- Looking for Lapic panic call Start\n");
822
823for (i = 0; i < 0x1000000; i++)
824{
825if (KernelLapicError
826&& (bytes[i + 0] == 0x65
827&& bytes[i + 1] == 0x8B
828&& bytes[i + 2] == 0x04
829&& bytes[i + 3] == 0x25
830&& bytes[i + 4] == 0x3C
831&& bytes[i + 5] == 0x00
832&& bytes[i + 6] == 0x00
833&& bytes[i + 7] == 0x00
834&& bytes[i + 45] == 0x65
835&& bytes[i + 46] == 0x8B
836&& bytes[i + 47] == 0x04
837&& bytes[i + 48] == 0x25
838&& bytes[i + 49] == 0x3C
839&& bytes[i + 50] == 0x00
840&& bytes[i + 51] == 0x00
841&& bytes[i + 52] == 0x00))
842{
843patchLocation = i + 40;
844verbose("\tFound Snow Leopard Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
845break;
846}
847else if (KernelLapicError
848&& (bytes[i + 0] == 0x65
849&& bytes[i + 1] == 0x8B
850&& bytes[i + 2] == 0x04
851&& bytes[i + 3] == 0x25
852&& bytes[i + 4] == 0x14
853&& bytes[i + 5] == 0x00
854&& bytes[i + 6] == 0x00
855&& bytes[i + 7] == 0x00
856&& bytes[i + 35] == 0x65
857&& bytes[i + 36] == 0x8B
858&& bytes[i + 37] == 0x04
859&& bytes[i + 38] == 0x25
860&& bytes[i + 39] == 0x14
861&& bytes[i + 40] == 0x00
862&& bytes[i + 41] == 0x00
863&& bytes[i + 42] == 0x00))
864{
865patchLocation = i + 30;
866verbose("\tFound %sLion Lapic panic at 0x%08X\n", checkOSVersion("10.7") ? "" : "Mountain ", (unsigned int)patchLocation);
867break;
868}
869else if (KernelLapicError
870&& (bytes[i + 0] == 0x65
871&& bytes[i + 1] == 0x8B
872&& bytes[i + 2] == 0x04
873&& bytes[i + 3] == 0x25
874&& bytes[i + 4] == 0x1C
875&& bytes[i + 5] == 0x00
876&& bytes[i + 6] == 0x00
877&& bytes[i + 7] == 0x00
878&& bytes[i + 36] == 0x65
879&& bytes[i + 37] == 0x8B
880&& bytes[i + 38] == 0x04
881&& bytes[i + 39] == 0x25
882&& bytes[i + 40] == 0x1C
883&& bytes[i + 41] == 0x00
884&& bytes[i + 42] == 0x00
885&& bytes[i + 43] == 0x00))
886{
887patchLocation = i + 31;
888verbose("\tFound Mavericks Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
889break;
890}
891 // RehabMan: 10.10.DP1 lapic
892else if (KernelLapicError
893&& (bytes[i + 0] == 0x65
894&& bytes[i + 1] == 0x8B
895&& bytes[i + 2] == 0x04
896&& bytes[i + 3] == 0x25
897&& bytes[i + 4] == 0x1C
898&& bytes[i + 5] == 0x00
899&& bytes[i + 6] == 0x00
900&& bytes[i + 7] == 0x00
901&& bytes[i + 33] == 0x65
902&& bytes[i + 34] == 0x8B
903&& bytes[i + 35] == 0x04
904&& bytes[i + 36] == 0x25
905&& bytes[i + 37] == 0x1C
906&& bytes[i + 38] == 0x00
907&& bytes[i + 39] == 0x00
908&& bytes[i + 40] == 0x00))
909{
910patchLocation = i + 28;
911verbose("\tFound Yosemite Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
912break;
913}
914// Sherlocks: 10.11.DP1
915else if (KernelLapicError
916&& (bytes[i + 0] == 0x65
917&& bytes[i + 1] == 0x8B
918&& bytes[i + 2] == 0x0C
919&& bytes[i + 3] == 0x25
920&& bytes[i + 4] == 0x1C
921&& bytes[i + 5] == 0x00
922&& bytes[i + 6] == 0x00
923&& bytes[i + 7] == 0x00
924&& bytes[i + 1411] == 0x65
925&& bytes[i + 1412] == 0x8B
926&& bytes[i + 1413] == 0x0C
927&& bytes[i + 1414] == 0x25
928&& bytes[i + 1415] == 0x1C
929&& bytes[i + 1416] == 0x00
930&& bytes[i + 1417] == 0x00
931&& bytes[i + 1418] == 0x00))
932{
933patchLocation = i + 1400;
934verbose("\tFound El Capitan Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
935break;
936}
937// Sherlocks: 10.12.DP1
938else if (KernelLapicError
939&& (bytes[i+0] == 0x65
940&& bytes[i+1] == 0x8B
941&& bytes[i+2] == 0x0C
942&& bytes[i+3] == 0x25
943&& bytes[i+4] == 0x1C
944&& bytes[i+5] == 0x00
945&& bytes[i+6] == 0x00
946&& bytes[i+7] == 0x00
947&& bytes[i+1409] == 0x65
948&& bytes[i+1410] == 0x8B
949&& bytes[i+1411] == 0x0C
950&& bytes[i+1412] == 0x25
951&& bytes[i+1413] == 0x1C
952&& bytes[i+1414] == 0x00
953&& bytes[i+1415] == 0x00
954&& bytes[i+1416] == 0x00))
955{
956patchLocation = i+1398;
957verbose("\tFound Sierra Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
958break;
959}
960// PMheart: 10.13.DP1
961else if (KernelLapicError
962&& (bytes[i+0] == 0x65
963&& bytes[i+1] == 0x8B
964&& bytes[i+2] == 0x0C
965&& bytes[i+3] == 0x25
966&& bytes[i+4] == 0x1C
967&& bytes[i+5] == 0x00
968&& bytes[i+6] == 0x00
969&& bytes[i+7] == 0x00
970&& bytes[i+1407] == 0x65
971&& bytes[i+1408] == 0x8B
972&& bytes[i+1409] == 0x0C
973&& bytes[i+1410] == 0x25
974&& bytes[i+1411] == 0x1C
975&& bytes[i+1412] == 0x00
976&& bytes[i+1413] == 0x00
977&& bytes[i+1414] == 0x00))
978{
979patchLocation = i+1396;
980verbose("\tFound High Sierra Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
981break;
982}
983// PMheart: 10.14.DP1
984else if (KernelLapicError
985&& (bytes[i+0] == 0x65
986&& bytes[i+1] == 0x8B
987&& bytes[i+2] == 0x0C
988&& bytes[i+3] == 0x25
989&& bytes[i+4] == 0x1C
990&& bytes[i+5] == 0x00
991&& bytes[i+6] == 0x00
992&& bytes[i+7] == 0x00
993&& bytes[i+1396] == 0x65
994&& bytes[i+1397] == 0x8B
995&& bytes[i+1398] == 0x0C
996&& bytes[i+1399] == 0x25
997&& bytes[i+1400] == 0x1C
998&& bytes[i+1401] == 0x00
999&& bytes[i+1402] == 0x00
1000&& bytes[i+1403] == 0x00))
1001{
1002patchLocation = i+1385;
1003verbose("\tFound Mojave Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
1004break;
1005}
1006}
1007
1008if (!patchLocation)
1009{
1010verbose("\tCan't find Lapic panic, kernel patch aborted.\n");
1011return false;
1012}
1013
1014// Already patched? May be running a non-vanilla kernel already?
1015
1016if (bytes[patchLocation + 0] == 0x90
1017&& bytes[patchLocation + 1] == 0x90
1018&& bytes[patchLocation + 2] == 0x90
1019&& bytes[patchLocation + 3] == 0x90
1020&& bytes[patchLocation + 4] == 0x90)
1021{
1022verbose("\tLapic panic already patched, kernel file manually patched?\n");
1023return false;
1024}
1025else
1026{
1027bytes[patchLocation + 0] = 0x90;
1028bytes[patchLocation + 1] = 0x90;
1029bytes[patchLocation + 2] = 0x90;
1030bytes[patchLocation + 3] = 0x90;
1031bytes[patchLocation + 4] = 0x90;
1032}
1033return true;
1034}
1035
1036// ===================================
1037// Bronya: Lapic Panic Version 32 bit
1038bool patch_lapic_version_init_32(void *kernelData)
1039{
1040UInt8 *bytes = (UInt8 *)kernelData;
1041UInt32 patchLocation = 0;
1042UInt32 i;
1043
1044verbose("\t- Looking for Lapic Version panic call Start\n");
1045
1046for (i = 0; i < 0x1000000; i++)
1047{
1048// Bronya: Snow Leopard 10.6 Lapic Version
1049if (bytes[i + 0] == 0x0f
1050&& bytes[i + 1] == 0x44
1051&& bytes[i + 2] == 0xc2
1052&& bytes[i + 49] == 0x89
1053&& bytes[i + 50] == 0x44
1054&& bytes[i + 51] == 0x24
1055&& bytes[i + 52] == 0x04)
1056{
1057patchLocation = i+60;
1058verbose("\tFound Snow Leopard Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);
1059break;
1060}
1061else
1062{
1063// Bronya: Lion 10.7 Lapic Version
1064if (bytes[i + 0] == 0x0f
1065&& bytes[i + 1] == 0x44
1066&& bytes[i + 2] == 0xc8
1067&& bytes[i + 52] == 0x89
1068&& bytes[i + 53] == 0x44
1069&& bytes[i + 54] == 0x24
1070&& bytes[i + 55] == 0x04)
1071{
1072patchLocation = i+63;
1073verbose("\tFound Lion, Lion Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);
1074break;
1075}
1076}
1077}
1078
1079if (!patchLocation)
1080{
1081verbose("\tCan't find Lapic Version panic, kernel patch aborted.\n");
1082return false;
1083}
1084
1085// Already patched? May be running a non-vanilla kernel already?
1086
1087if (bytes[patchLocation + 0] == 0x90
1088&& bytes[patchLocation + 1] == 0x90
1089&& bytes[patchLocation + 2] == 0x90
1090&& bytes[patchLocation + 3] == 0x90
1091&& bytes[patchLocation + 4] == 0x90)
1092{
1093verbose("\tLapic Version panic already patched, kernel file manually patched?\n");
1094return false;
1095}
1096else
1097{
1098bytes[patchLocation + 0] = 0x90;
1099bytes[patchLocation + 1] = 0x90;
1100bytes[patchLocation + 2] = 0x90;
1101bytes[patchLocation + 3] = 0x90;
1102bytes[patchLocation + 4] = 0x90;
1103}
1104return true;
1105}
1106
1107// ===================================
1108// Lapic Error Panic 32
1109bool patch_lapic_init_32(void *kernelData) // KernelLapicPatch_32
1110{
1111// Credits to donovan6000 and sherlocks for providing the lapic kernel patch source used to build this function
1112
1113UInt8 *bytes = (UInt8 *)kernelData;
1114UInt32 patchLocation=0;
1115UInt32 i;
1116
1117verbose("\t- Looking for Lapic panic call Start\n");
1118
1119for (i = 0; i < 0x1000000; i++)
1120{
1121if (bytes[i+0] == 0x65
1122&& bytes[i+1] == 0xA1
1123&& bytes[i+2] == 0x0C
1124&& bytes[i+3] == 0x00
1125&& bytes[i+4] == 0x00
1126&& bytes[i+5] == 0x00
1127&& bytes[i+30] == 0x65
1128&& bytes[i+31] == 0xA1
1129&& bytes[i+32] == 0x0C
1130&& bytes[i+33] == 0x00
1131&& bytes[i+34] == 0x00
1132&& bytes[i+35] == 0x00)
1133{
1134patchLocation = i + 25;
1135verbose("\tFound Lapic panic at 0x%08X\n", (unsigned int)patchLocation);
1136break;
1137}
1138}
1139
1140if (!patchLocation)
1141{
1142verbose("\tCan't find Lapic panic, kernel patch aborted.\n");
1143return false;
1144}
1145
1146// Already patched? May be running a non-vanilla kernel already?
1147
1148if (bytes[patchLocation + 0] == 0x90
1149&& bytes[patchLocation + 1] == 0x90
1150&& bytes[patchLocation + 2] == 0x90
1151&& bytes[patchLocation + 3] == 0x90
1152&& bytes[patchLocation + 4] == 0x90)
1153{
1154verbose("\tLapic panic already patched, kernel file manually patched?\n");
1155return false;
1156}
1157else
1158{
1159bytes[patchLocation + 0] = 0x90;
1160bytes[patchLocation + 1] = 0x90;
1161bytes[patchLocation + 2] = 0x90;
1162bytes[patchLocation + 3] = 0x90;
1163bytes[patchLocation + 4] = 0x90;
1164}
1165return true;
1166}
1167
1168// ===================================
1169// Haswell-E Patch
1170bool patch_haswell_E_init(void *kernelData) // KernelHaswellEPatch
1171{
1172// Credit to stinga11 for the patches used below
1173// Based on Pike R. Alpha's Haswell patch for Mavericks
1174
1175UInt8*Bytes;
1176UInt32Index;
1177boolPatchApplied;
1178
1179verbose("\t- Searching for Haswell-E patch pattern\n");
1180
1181Bytes = (UInt8 *)kernelData;
1182PatchApplied = false;
1183
1184for (Index = 0; Index < 0x1000000; ++Index)
1185{
1186// sudo perl -pi -e 's|\x74\x11\x83\xF8\x3C|\x74\x11\x83\xF8\x3F|g' /System/Library/Kernels/kernel
1187if (Bytes[Index] == 0x74
1188&& Bytes[Index + 1] == 0x11
1189&& Bytes[Index + 2] == 0x83
1190&& Bytes[Index + 3] == 0xF8
1191&& Bytes[Index + 4] == 0x3C)
1192{
1193Bytes[Index + 4] = 0x3F;
1194
1195verbose("\tFound Haswell-E pattern #1; patched.\n");
1196
1197if (PatchApplied)
1198{
1199break;
1200}
1201
1202PatchApplied = true;
1203}
1204
1205// sudo perl -pi -e 's|\xEB\x0A\x83\xF8\x3A|\xEB\x0A\x83\xF8\x3F|g' /System/Library/Kernels/kernel
1206if (Bytes[Index] == 0xEB
1207&& Bytes[Index + 1] == 0x0A
1208&& Bytes[Index + 2] == 0x83
1209&& Bytes[Index + 3] == 0xF8
1210&& Bytes[Index + 4] == 0x3A)
1211{
1212Bytes[Index + 4] = 0x3F;
1213
1214verbose("\tFound Haswell-E pattern #2; patched.\n");
1215
1216if (PatchApplied)
1217{
1218break;
1219}
1220
1221PatchApplied = true;
1222}
1223}
1224
1225if (!PatchApplied)
1226{
1227verbose("\tCan't find Haswell-E patch pattern, patch not applied.\n");
1228}
1229
1230return PatchApplied;
1231}
1232
1233// ===================================
1234// Haswell-ULT Patch
1235bool patch_haswell_ULT_init(void *kernelData) // Fake CPUFAMILY To IVYBRIDGE Patch
1236{
1237// Credit to Tora Chi Yo for the patches used below
1238// http://www.insanelymac.com/forum/topic/307721-haswell-ult-kernel-patch-for-yosemite-mavericks
1239
1240UInt8*Bytes;
1241UInt32Index;
1242boolPatchApplied;
1243
1244verbose("\t- Searching for Haswell-ULT patch pattern\n");
1245
1246Bytes = (UInt8 *)kernelData;
1247PatchApplied = false;
1248
1249for (Index = 0; Index < 0x1000000; ++Index)
1250{
1251// sudo perl -pi -e 's|\xbb\xdc\x82\xb2\xdc|\xbb\x35\xe8\x65\x1f|g' /System/Library/Kernels/kernel
1252if (Bytes[Index] == 0xBB
1253&& Bytes[Index + 1] == 0xDC
1254&& Bytes[Index + 2] == 0x82
1255&& Bytes[Index + 3] == 0xB2
1256&& Bytes[Index + 4] == 0xdc)
1257{
1258Bytes[Index + 1] = 0x35;
1259Bytes[Index + 2] = 0xE8;
1260Bytes[Index + 3] = 0x65;
1261Bytes[Index + 4] = 0x1F;
1262
1263verbose("\tFound Haswell-ULT pattern #1; patched.\n");
1264
1265if (PatchApplied)
1266{
1267break;
1268}
1269
1270PatchApplied = true;
1271}
1272}
1273
1274if (!PatchApplied)
1275{
1276verbose("\tCan't find Haswell-ULT patch pattern, patch not applied.\n");
1277}
1278
1279return PatchApplied;
1280}
1281
1282// ===================================
1283// Custom Kext injection from Extra/Extensions folder
1284void patch_BooterExtensions_32(void *kernelData)
1285{
1286// KernelBooterExtensionsPatch to load extra kexts besides kernelcache
1287UInt8 *Bytes;
1288UInt32 Index;
1289bool PatchApplied;
1290int count = 0;
1291
1292verbose("\t- Searching for booter extensions pattern:\n");
1293
1294Bytes = (UInt8 *)kernelData;
1295PatchApplied = false;
1296
1297if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))
1298{
1299//UInt8 KBELionSearch_i386[] = { 0xE8, 0xAA, 0xFB, 0xFF, 0xFF, 0xEB, 0x08, 0x89, 0x34, 0x24 };
1300//UInt8 KBELionReplace_i386[] = { 0xE8, 0xAA, 0xFB, 0xFF, 0xFF, 0x90, 0x90, 0x89, 0x34, 0x24 };
1301for (Index = 0; Index < 0x1000000; ++Index)
1302{
1303if (Bytes[Index] == 0xE8
1304&& Bytes[Index + 1] == 0xAA
1305&& Bytes[Index + 2] == 0xFB
1306&& Bytes[Index + 3] == 0xFF
1307&& Bytes[Index + 4] == 0xFF
1308&& Bytes[Index + 5] == 0xEB
1309&& Bytes[Index + 6] == 0x08
1310&& Bytes[Index + 7] == 0x89
1311&& Bytes[Index + 8] == 0x34
1312&& Bytes[Index + 9] == 0x24)
1313{
1314Bytes[Index + 5] = 0x90;
1315Bytes[Index + 6] = 0x90;
1316count ++;
1317
1318verbose("\tFound Lion pattern: patched!\n");
1319
1320if (PatchApplied)
1321{
1322break;
1323}
1324
1325PatchApplied = true;
1326}
1327}
1328}
1329
1330/* UNDER REVIEW, crazybirdy test this patch on Snow leopard:
1331 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!
1332 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
1333
1334 need to re-try later.
1335 */
1336if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))
1337{
1338//UInt8 KBESnowSearch_i386[] = { 0xE8, 0xED, 0xF9, 0xFF, 0xFF, 0xEB, 0x08, 0x89, 0x1C, 0x24 };
1339//UInt8 KBESnowReplace_i386[] = { 0xE8, 0xED, 0xF9, 0xFF, 0xFF, 0x90, 0x90, 0x89, 0x1C, 0x24 };
1340for (Index = 0; Index < 0x1000000; ++Index)
1341{
1342if (Bytes[Index] == 0xE8
1343&& Bytes[Index + 1] == 0xED
1344&& Bytes[Index + 2] == 0xF9
1345&& Bytes[Index + 3] == 0xFF
1346&& Bytes[Index + 4] == 0xFF
1347&& Bytes[Index + 5] == 0xEB
1348&& Bytes[Index + 6] == 0x08
1349&& Bytes[Index + 7] == 0x89
1350&& Bytes[Index + 8] == 0x1C
1351&& Bytes[Index + 9] == 0x24)
1352{
1353Bytes[Index + 5] = 0x90;
1354Bytes[Index + 6] = 0x90;
1355count ++;
1356
1357verbose("\tFound Snow Leopard pattern: patched!\n");
1358
1359if (PatchApplied)
1360{
1361break;
1362}
1363
1364PatchApplied = true;
1365}
1366}
1367}
1368
1369if (!PatchApplied)
1370{
1371verbose("\tCan't find Booter Extensions patch location.\n");
1372}
1373else
1374{
1375verbose("\t%d substitution(s) made.\n", count);
1376}
1377}
1378
1379void patch_BooterExtensions_64(void *kernelData)
1380{
1381// KernelBooterExtensionsPatch to load extra kexts besides kernelcache
1382UInt8 *Bytes;
1383UInt32 Index;
1384bool PatchApplied; // does nothing
1385int count = 0;
1386
1387verbose("\t- Searching for booter extensions pattern:\n");
1388
1389Bytes = (UInt8 *)kernelData;
1390PatchApplied = false;
1391
1392// High Sierra, Mojave onward, need to use 10.12 instead of 10.13. kernel bug?
1393// if (kernelOSVer >= MacOSVer2Int("10.13") && kernelOSVer < MacOSVer2Int("10.14"))
1394if (kernelOSVer >= MacOSVer2Int("10.12"))
1395{
1396for (Index = 0; Index < 0x1000000; ++Index)
1397{
1398// High Sierra
1399if (Bytes[Index] == 0xC3
1400&& Bytes[Index + 1] == 0x48
1401&& Bytes[Index + 2] == 0x85
1402&& Bytes[Index + 3] == 0xDB
1403&& Bytes[Index + 4] == 0x74
1404&& Bytes[Index + 5] == 0x69
1405&& Bytes[Index + 6] == 0x48
1406&& Bytes[Index + 7] == 0x8B
1407&& Bytes[Index + 8] == 0x03
1408&& Bytes[Index + 9] == 0x48
1409&& Bytes[Index + 10] == 0x89
1410&& Bytes[Index + 11] == 0xDF
1411&& Bytes[Index + 12] == 0xFF
1412&& Bytes[Index + 13] == 0x50
1413&& Bytes[Index + 14] == 0x28
1414&& Bytes[Index + 15] == 0x48)
1415{
1416Bytes[Index + 4] = 0xEB;
1417Bytes[Index + 5] = 0x12;
1418count++;
1419
1420verbose("\tFound High Sierra, Mojave SIP pattern: patched!\n");
1421
1422if (PatchApplied)
1423{
1424break;
1425}
1426
1427PatchApplied = true;
1428}
1429}
1430}
1431
1432// Sierra
1433if (kernelOSVer >= MacOSVer2Int("10.12") && kernelOSVer < MacOSVer2Int("10.13"))
1434{
1435for (Index = 0; Index < 0x1000000; ++Index)
1436{
1437// Sierra
1438if (Bytes[Index] == 0xC3
1439&& Bytes[Index + 1] == 0x48
1440&& Bytes[Index + 2] == 0x85
1441&& Bytes[Index + 3] == 0xDB
1442&& Bytes[Index + 4] == 0x74
1443&& Bytes[Index + 5] == 0x71
1444&& Bytes[Index + 6] == 0x48
1445&& Bytes[Index + 7] == 0x8B
1446&& Bytes[Index + 8] == 0x03
1447&& Bytes[Index + 9] == 0x48
1448&& Bytes[Index + 10] == 0x89
1449&& Bytes[Index + 11] == 0xDF
1450&& Bytes[Index + 12] == 0xFF
1451&& Bytes[Index + 13] == 0x50
1452&& Bytes[Index + 14] == 0x28
1453&& Bytes[Index + 15] == 0x48)
1454{
1455Bytes[Index + 4] = 0xEB;
1456Bytes[Index + 5] = 0x12;
1457count++;
1458
1459verbose("\tFound Sierra SIP pattern: patched!\n");
1460
1461if (PatchApplied)
1462{
1463break;
1464}
1465
1466PatchApplied = true;
1467}
1468}
1469}
1470
1471// Yosemite/El Capitan
1472if (kernelOSVer >= MacOSVer2Int("10.10") && kernelOSVer < MacOSVer2Int("10.12"))
1473{
1474for (Index = 0; Index < 0x1000000; ++Index)
1475{
1476// El Capitan
1477if (Bytes[Index] == 0xC3
1478&& Bytes[Index + 1] == 0x48
1479&& Bytes[Index + 2] == 0x85
1480&& Bytes[Index + 3] == 0xDB
1481&& Bytes[Index + 4] == 0x74
1482&& Bytes[Index + 5] == 0x70
1483&& Bytes[Index + 6] == 0x48
1484&& Bytes[Index + 7] == 0x8B
1485&& Bytes[Index + 8] == 0x03
1486&& Bytes[Index + 9] == 0x48
1487&& Bytes[Index + 10] == 0x89
1488&& Bytes[Index + 11] == 0xDF
1489&& Bytes[Index + 12] == 0xFF
1490&& Bytes[Index + 13] == 0x50
1491&& Bytes[Index + 14] == 0x28
1492&& Bytes[Index + 15] == 0x48)
1493{
1494Bytes[Index + 4] = 0xEB;
1495Bytes[Index + 5] = 0x12;
1496count++;
1497
1498if (kernelOSVer >= MacOSVer2Int("10.11"))
1499{
1500verbose("\tFound El Capitan SIP pattern: patched!\n");
1501}
1502else
1503{
1504verbose("\tFound Yosemite SIP pattern: patched!\n");
1505}
1506
1507if (PatchApplied)
1508{
1509break;
1510}
1511
1512PatchApplied = true;
1513}
1514}
1515}
1516
1517// Mojave, need to use 10.12 instead of 10.14. kernel bug?
1518// if (kernelOSVer >= MacOSVer2Int("10.10") && kernelOSVer < MacOSVer2Int("10.14"))
1519if (kernelOSVer >= MacOSVer2Int("10.12"))
1520{
1521
1522for (Index = 0; Index < 0x1000000; ++Index)
1523{
1524if (Bytes[Index] == 0xE8
1525&& Bytes[Index + 1] == 0xAF
1526&& Bytes[Index + 2] == 0x00
1527&& Bytes[Index + 3] == 0x00
1528&& Bytes[Index + 4] == 0x00
1529&& Bytes[Index + 5] == 0xEB
1530&& Bytes[Index + 6] == 0x05
1531&& Bytes[Index + 7] == 0xE8)
1532{
1533Bytes[Index + 5] = 0x90;
1534Bytes[Index + 6] = 0x90;
1535count++;
1536
1537verbose("\tFound Mojave EXT pattern: patched!\n");
1538
1539if (PatchApplied)
1540{
1541break;
1542}
1543
1544PatchApplied = true;
1545}
1546}
1547}
1548
1549// Yosemite onward.
1550// Yosemite/EL Capitan/Sierra/High Sierra
1551// if (kernelOSVer >= MacOSVer2Int("10.10") && kernelOSVer < MacOSVer2Int("10.14"))
1552if (kernelOSVer >= MacOSVer2Int("10.10"))
1553{
1554
1555for (Index = 0; Index < 0x1000000; ++Index)
1556{
1557if (Bytes[Index] == 0xE8
1558&& Bytes[Index + 1] == 0x25
1559&& Bytes[Index + 2] == 0x00
1560&& Bytes[Index + 3] == 0x00
1561&& Bytes[Index + 4] == 0x00
1562&& Bytes[Index + 5] == 0xEB
1563&& Bytes[Index + 6] == 0x05
1564&& Bytes[Index + 7] == 0xE8)
1565{
1566Bytes[Index + 5] = 0x90;
1567Bytes[Index + 6] = 0x90;
1568count++;
1569
1570if (kernelOSVer >= MacOSVer2Int("10.13") && kernelOSVer < MacOSVer2Int("10.14"))
1571{
1572verbose("\tFound High Sierra EXT pattern: patched!\n");
1573}
1574else if (kernelOSVer >= MacOSVer2Int("10.12") && kernelOSVer < MacOSVer2Int("10.13"))
1575{
1576verbose("\tFound Sierra EXT pattern: patched!\n");
1577}
1578else if (kernelOSVer >= MacOSVer2Int("10.11") && kernelOSVer < MacOSVer2Int("10.12"))
1579{
1580verbose("\tFound EL Capitan EXT pattern: patched!\n");
1581}
1582else
1583{
1584verbose("\tFound Yosemite EXT pattern: patched!\n");
1585}
1586
1587if (PatchApplied)
1588{
1589break;
1590}
1591
1592PatchApplied = true;
1593}
1594}
1595}
1596
1597// Mountain Lion/Mavericks
1598if (kernelOSVer >= MacOSVer2Int("10.8") && kernelOSVer < MacOSVer2Int("10.10"))
1599{
1600
1601for (Index = 0; Index < 0x1000000; ++Index)
1602{
1603if (Bytes[Index] == 0xC6
1604&& Bytes[Index + 1] == 0xE8
1605&& Bytes[Index + 2] == 0x30
1606&& Bytes[Index + 3] == 0x00
1607&& Bytes[Index + 4] == 0x00
1608&& Bytes[Index + 5] == 0x00
1609&& Bytes[Index + 6] == 0xEB
1610&& Bytes[Index + 7] == 0x08
1611&& Bytes[Index + 8] == 0x48
1612&& Bytes[Index + 9] == 0x89
1613&& Bytes[Index + 10] == 0xDF)
1614{
1615Bytes[Index + 6] = 0x90;
1616Bytes[Index + 7] = 0x90;
1617count++;
1618
1619verbose("\tFound M%s EXT pattern: patched!\n", checkOSVersion("10.8") ? "ountain Lion" : "avericks");
1620
1621if (PatchApplied)
1622{
1623break;
1624}
1625
1626PatchApplied = true;
1627}
1628}
1629}
1630
1631// Lion 64
1632if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))
1633{
1634for (Index = 0; Index < 0x1000000; ++Index)
1635{
1636if (Bytes[Index] == 0xE8
1637&& Bytes[Index + 1] == 0x0C
1638&& Bytes[Index + 2] == 0xFD
1639&& Bytes[Index + 3] == 0xFF
1640&& Bytes[Index + 4] == 0xFF
1641&& Bytes[Index + 5] == 0xEB
1642&& Bytes[Index + 6] == 0x08
1643&& Bytes[Index + 7] == 0x48
1644&& Bytes[Index + 8] == 0x89
1645&& Bytes[Index + 9] == 0xDF)
1646{
1647Bytes[Index + 5] = 0x90;
1648Bytes[Index + 6] = 0x90;
1649count++;
1650
1651verbose("\tFound Lion EXT pattern: patched!\n");
1652
1653if (PatchApplied)
1654{
1655break;
1656}
1657
1658PatchApplied = true;
1659}
1660}
1661}
1662
1663// Snow Leopard 64
1664if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))
1665{
1666for (Index = 0; Index < 0x1000000; ++Index)
1667{
1668if (Bytes[Index] == 0xE8
1669&& Bytes[Index + 1] == 0x5A
1670&& Bytes[Index + 2] == 0xFB
1671&& Bytes[Index + 3] == 0xFF
1672&& Bytes[Index + 4] == 0xFF
1673&& Bytes[Index + 5] == 0xEB
1674&& Bytes[Index + 6] == 0x08
1675&& Bytes[Index + 7] == 0x48
1676&& Bytes[Index + 8] == 0x89
1677&& Bytes[Index + 9] == 0xDF)
1678{
1679Bytes[Index + 5] = 0x90;
1680Bytes[Index + 6] = 0x90;
1681verbose("\tFound Snow Leopard EXT pattern: patched!\n");
1682count++;
1683
1684if (PatchApplied)
1685{
1686break;
1687}
1688
1689PatchApplied = true;
1690}
1691}
1692}
1693
1694if (!PatchApplied)
1695{
1696verbose("\tCan't find Booter Extensions patch location.\n");
1697}
1698else
1699{
1700verbose("\t%d substitution(s) made.\n", count);
1701}
1702}
1703
1704// ===================================
1705// Patch ssse3
1706void patch_SSE3_6(void *kernelData)
1707{
1708UInt8 *bytes = (UInt8 *)kernelData;
1709UInt32 patchLocation1 = 0;
1710UInt32 patchLocation2 = 0;
1711UInt32 patchlast = 0;
1712UInt32 i;
1713//UInt32 Length = sizeof(kernelData);
1714
1715verbose("\t- Start find SSE3 address\n");
1716i = 0;
1717//for (i = 0; i < Length; i++)
1718while(true)
1719{
1720if (bytes[i] == 0x66
1721&& bytes[i + 1] == 0x0F
1722&& bytes[i + 2] == 0x6F
1723&& bytes[i + 3] == 0x44
1724&& bytes[i + 4] == 0x0E
1725&& bytes[i + 5] == 0xF1
1726&& bytes[i - 1664 - 32] == 0x55)
1727{
1728patchLocation1 = i-1664-32;
1729verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);
1730}
1731
1732// hasSSE2+..... title
1733if (bytes[i] == 0xE3
1734&& bytes[i + 1] == 0x07
1735&& bytes[i + 2] == 0x00
1736&& bytes[i + 3] == 0x00
1737&& bytes[i + 4] == 0x80
1738&& bytes[i + 5] == 0x07
1739&& bytes[i + 6] == 0xFF
1740&& bytes[i + 7] == 0xFF
1741&& bytes[i + 8] == 0x24
1742&& bytes[i + 9] == 0x01)
1743{
1744patchLocation2 = i;
1745verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);
1746break;
1747}
1748i++;
1749}
1750
1751if (!patchLocation1 || !patchLocation2)
1752{
1753verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);
1754return;
1755}
1756
1757verbose("\tFound SSE3 last data addres Start\n");
1758i = patchLocation1 + 1500;
1759//for (i=(patchLocation1+1500); i<(patchLocation1+3000); i++)
1760while(true)
1761{
1762if (bytes[i] == 0x90
1763&& bytes[i + 1] == 0x90
1764&& bytes[i + 2] == 0x55 )
1765{
1766patchlast = (i+1) - patchLocation1;
1767verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);
1768break;
1769}
1770i++;
1771}
1772
1773if (!patchlast)
1774{
1775verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);
1776return;
1777}
1778// patch sse3_64 data
1779
1780for (i = 0; i < patchlast; i++)
1781{
1782if (i < sizeof(sse3_patcher))
1783{
1784bytes[patchLocation1 + i] = sse3_patcher[i];
1785}
1786else
1787{
1788bytes[patchLocation1 + i] = 0x90;
1789}
1790}
1791
1792// patch kHasSSE3 title
1793bytes[patchLocation2 + 0] = 0xFC;
1794bytes[patchLocation2 + 1] = 0x05;
1795bytes[patchLocation2 + 8] = 0x2C;
1796bytes[patchLocation2 + 9] = 0x00;
1797
1798}
1799
1800// ===================================
1801//
1802void patch_SSE3_5(void *kernelData)
1803{
1804UInt8 *bytes = (UInt8 *)kernelData;
1805UInt32 patchLocation1 = 0;
1806UInt32 patchLocation2 = 0;
1807UInt32 patchlast=0;
1808UInt32 Length = sizeof(kernelData);
1809UInt32 i;
1810
1811verbose("\t- Start find SSE3 address\n");
1812
1813for (i = 256; i < (Length-256); i++)
1814{
1815if (bytes[i] == 0x66
1816&& bytes[i + 1] == 0x0F
1817&& bytes[i + 2] == 0x6F
1818&& bytes[i + 3] == 0x44
1819&& bytes[i + 4] == 0x0E
1820&& bytes[i + 5] == 0xF1
1821&& bytes[i - 1680 - 32] == 0x55)
1822{
1823patchLocation1 = i-1680-32;
1824verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);
1825}
1826
1827// khasSSE2+..... title
1828if (bytes[i] == 0xF3
1829&& bytes[i + 1] == 0x07
1830&& bytes[i + 2] == 0x00
1831&& bytes[i + 3] == 0x00
1832&& bytes[i + 4] == 0x80
1833&& bytes[i + 5] == 0x07
1834&& bytes[i + 6] == 0xFF
1835&& bytes[i + 7] == 0xFF
1836&& bytes[i + 8] == 0x24
1837&& bytes[i + 9] == 0x01)
1838{
1839patchLocation2 = i;
1840verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);
1841break;
1842}
1843}
1844
1845if (!patchLocation1 || !patchLocation2)
1846{
1847verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);
1848return;
1849}
1850
1851verbose("\tFound SSE3 last data addres Start\n");
1852
1853for (i = (patchLocation1+1500);i < Length;i++)
1854{
1855if (bytes[i] == 0x90
1856&& bytes[i + 1] == 0x90
1857&& bytes[i + 2] == 0x55)
1858{
1859patchlast = (i+1) - patchLocation1;
1860verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);
1861break;
1862}
1863}
1864
1865if (!patchlast)
1866{
1867verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);
1868return;
1869}
1870
1871// patech sse3_64 data
1872
1873for (i = 0; i < patchlast; i++)
1874{
1875if (i < sizeof(sse3_5_patcher))
1876{
1877bytes[patchLocation1 + i] = sse3_5_patcher[i];
1878}
1879else
1880{
1881bytes[patchLocation1 + i] = 0x90;
1882}
1883}
1884
1885// patch kHasSSE3 title
1886bytes[patchLocation2 + 0] = 0x0C;
1887bytes[patchLocation2 + 1] = 0x06;
1888bytes[patchLocation2 + 8] = 0x2C;
1889bytes[patchLocation2 + 9] = 0x00;
1890
1891}
1892
1893// ===================================
1894//
1895void patch_SSE3_7(void *kernelData)
1896{
1897// not support yet
1898return;
1899}
1900
1901// ===================================
1902// root:xnu text replacement Patch
1903bool patch_string_XNU_init(void *kernelData) //
1904{
1905
1906UInt8*Bytes;
1907UInt32Index;
1908boolPatchApplied;
1909
1910DBG("\t- Searching for \"root:xnu-\" string pattern\n");
1911
1912Bytes = (UInt8 *)kernelData;
1913PatchApplied = false;
1914
1915for (Index = 0; Index < 0x1000000; ++Index)
1916{
1917// search for root:xnu- and replace it with ***Enoch-
1918if (Bytes[Index] == ' '
1919&& Bytes[Index + 1] == 'r'
1920&& Bytes[Index + 2] == 'o'
1921&& Bytes[Index + 3] == 'o'
1922&& Bytes[Index + 4] == 't'
1923&& Bytes[Index + 5] == ':'
1924&& Bytes[Index + 6] == 'x'
1925&& Bytes[Index + 7] == 'n'
1926&& Bytes[Index + 8] == 'u'
1927&& Bytes[Index + 9] == '-' )
1928{
1929Bytes[Index + 1] = '*';
1930Bytes[Index + 2] = '*';
1931Bytes[Index + 3] = '*';
1932Bytes[Index + 4] = 'E';
1933Bytes[Index + 5] = 'n';
1934Bytes[Index + 6] = 'o';
1935Bytes[Index + 7] = 'c';
1936Bytes[Index + 8] = 'h';
1937
1938DBG("\tFound \"root:xnu-\" pattern; patched.\n");
1939
1940if (PatchApplied)
1941{
1942break;
1943}
1944
1945PatchApplied = true;
1946}
1947}
1948
1949if (!PatchApplied)
1950{
1951DBG("\tCan't find \"root:xnu-\" string pattern: patch not applied.\n");
1952}
1953
1954return PatchApplied;
1955}
1956
1957// ===================================
1958// (Clover)
1959// Patching AppleRTC to prevent CMOS reset
1960unsigned int AppleRTC_Patch(void *data, UInt32 DriverSize, UInt32 StartLocation)
1961{
1962 unsigned int count = 0;
1963 // as far as I know this works from Lion to Sierra
1964 UInt8 LionSearch_X64[] = { 0x75, 0x30, 0x44, 0x89, 0xf8 };
1965 UInt8 LionReplace_X64[] = { 0xeb, 0x30, 0x44, 0x89, 0xf8 };
1966
1967 UInt8 LionSearch_i386[] = { 0x75, 0x3d, 0x8b, 0x75, 0x08 };
1968 UInt8 LionReplace_i386[] = { 0xeb, 0x3d, 0x8b, 0x75, 0x08 };
1969
1970 UInt8 MLSearch[] = { 0x75, 0x30, 0x89, 0xd8 };
1971 UInt8 MLReplace[] = { 0xeb, 0x30, 0x89, 0xd8 };
1972 //SunKi
1973 //752e0fb6 -> eb2e0fb6
1974 UInt8 MavSearch[] = { 0x75, 0x2e, 0x0f, 0xb6 };
1975 UInt8 MavReplace[] = { 0xeb, 0x2e, 0x0f, 0xb6};
1976
1977 if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))
1978 {
1979 count = FindAndReplace(data,
1980 DriverSize,
1981 StartLocation,
1982 LionSearch_i386,
1983 sizeof(LionSearch_i386),
1984 LionReplace_i386,
1985 0);
1986
1987 count = count + FindAndReplace(data,
1988 DriverSize,
1989 StartLocation,
1990 LionSearch_X64,
1991 sizeof(LionSearch_X64),
1992 LionReplace_X64,
1993 0);
1994 }
1995 else
1996 if (kernelOSVer >= MacOSVer2Int("10.8") && kernelOSVer < MacOSVer2Int("10.9"))
1997 {
1998 count = FindAndReplace(data,
1999 DriverSize,
2000 StartLocation,
2001 MLSearch,
2002 sizeof(MLSearch),
2003 MLReplace,
2004 0);
2005 }
2006 else
2007 if (kernelOSVer >= MacOSVer2Int("10.9"))
2008 {
2009 count = FindAndReplace(data,
2010 DriverSize,
2011 StartLocation,
2012 MavSearch,
2013 sizeof(MavSearch),
2014 MavReplace,
2015 0);
2016 }
2017
2018 return count;
2019}
2020
2021// ===================================
2022// (Clover)
2023// Patching AppleIntelCPUPowerManagement
2024unsigned int AsusAICPUPMPatch(void *data, UInt32 DriverSize, UInt32 StartLocation)
2025{
2026 unsigned int Index1;
2027 unsigned int Index2;
2028 unsigned int Count = 0;
2029
2030 UInt8 MovlE2ToEcx[] = { 0xB9, 0xE2, 0x00, 0x00, 0x00 };
2031 UInt8 MovE2ToCx[] = { 0x66, 0xB9, 0xE2, 0x00 };
2032 UInt8 Wrmsr[] = { 0x0F, 0x30 };
2033
2034 UInt8*Driver = (UInt8 *)data;
2035
2036 //TODO: we should scan only __text __TEXT
2037 for (Index1 = StartLocation; Index1 < (StartLocation+DriverSize); Index1++)
2038 {
2039 // search for MovlE2ToEcx
2040 if (memcmp(Driver + Index1, MovlE2ToEcx, sizeof(MovlE2ToEcx)) == 0)
2041 {
2042 // search for wrmsr in next few bytes
2043 for (Index2 = Index1 + sizeof(MovlE2ToEcx); Index2 < Index1 + sizeof(MovlE2ToEcx) + 32; Index2++)
2044 {
2045 if (Driver[Index2] == Wrmsr[0] && Driver[Index2 + 1] == Wrmsr[1])
2046 {
2047 // found it - patch it with nops
2048 Count++;
2049 Driver[Index2] = 0x90;
2050 Driver[Index2 + 1] = 0x90;
2051 verbose("\t%d wrmsr patched at 0x%X\n", Count, Index2);
2052 break;
2053 } else if ((Driver[Index2] == 0xC9 && Driver[Index2 + 1] == 0xC3) ||
2054 (Driver[Index2] == 0x5D && Driver[Index2 + 1] == 0xC3) ||
2055 (Driver[Index2] == 0xB9 && Driver[Index2 + 3] == 0 && Driver[Index2 + 4] == 0) ||
2056 (Driver[Index2] == 0x66 && Driver[Index2 + 1] == 0xB9 && Driver[Index2 + 3] == 0))
2057 {
2058 // a leave/ret will cancel the search
2059 // so will an intervening "mov[l] $xx, [e]cx"
2060 break;
2061 }
2062 }
2063 } else if (memcmp(Driver + Index1, MovE2ToCx, sizeof(MovE2ToCx)) == 0)
2064 {
2065 // search for wrmsr in next few bytes
2066 for (Index2 = Index1 + sizeof(MovE2ToCx); Index2 < Index1 + sizeof(MovE2ToCx) + 32; Index2++)
2067 {
2068 if (Driver[Index2] == Wrmsr[0] && Driver[Index2 + 1] == Wrmsr[1])
2069 {
2070 // found it - patch it with nops
2071 Count++;
2072 Driver[Index2] = 0x90;
2073 Driver[Index2 + 1] = 0x90;
2074 verbose("\t%d wrmsr patched at 0x%X\n", Count, Index2);
2075 break;
2076 } else if ((Driver[Index2] == 0xC9 && Driver[Index2 + 1] == 0xC3) ||
2077 (Driver[Index2] == 0x5D && Driver[Index2 + 1] == 0xC3) ||
2078 (Driver[Index2] == 0xB9 && Driver[Index2 + 3] == 0 && Driver[Index2 + 4] == 0) ||
2079 (Driver[Index2] == 0x66 && Driver[Index2 + 1] == 0xB9 && Driver[Index2 + 3] == 0))
2080 {
2081 // a leave/ret will cancel the search
2082 // so will an intervening "mov[l] $xx, [e]cx"
2083 break;
2084 }
2085 }
2086 }
2087 }
2088
2089 return Count;
2090}
2091
2092// ===================================
2093// Patching IOAHCIBlockStorage to enable the trim support
2094unsigned int trimEnablerSata(void *data, UInt32 DriverSize, UInt32 StartLocation)
2095{
2096 // as far as I know this works from Lion to Sierra
2097 UInt8 Find[] = { 0x00, 0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x53, 0x53, 0x44, 0x00 };
2098
2099 UInt8 Replace[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2100 unsigned int count = FindAndReplace(data,
2101 DriverSize,
2102 StartLocation,
2103 Find,
2104 sizeof(Find),
2105 Replace,
2106 0);
2107
2108 return count;
2109}
2110
2111// ===================================
2112// Patching AppleAHCIPort to fix orange icon (Sata only)
2113unsigned int patch_AppleAHCIPort_OrangeFix(void *data, UInt32 DriverSize, UInt32 StartLocation)
2114{
2115 // as far as I know this works from lion onward
2116 UInt8 Find[] = { 0x45, 0x78, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C };
2117 UInt8 Replace[] = { 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C };
2118 unsigned int count = FindAndReplace(data,
2119 DriverSize,
2120 StartLocation,
2121 Find,
2122 sizeof(Find),
2123 Replace,
2124 0);
2125
2126 return count;
2127}
2128
2129// ===================================
2130// (Micky1979)
2131// Patching NVDAStartupWeb
2132unsigned int patch_NVDAStartupWeb(void *data, UInt32 DriverSize, UInt32 StartLocation)
2133{
2134 unsigned int count = 0;
2135 // this patch is needed only in Sierra onward
2136 if (MacOSVerCurrent >= MacOSVer2Int("10.12"))
2137 {
2138 Node *nvdadrvNode = DT__FindNode("/nvdadrv", true);
2139 if (nvdadrvNode != 0)
2140 {
2141 DT__AddProperty(nvdadrvNode, "nvda_drv", strlen(NVDAVALUE), (void*)NVDAVALUE);
2142 UInt8 Find[] = { 0x49, 0x4F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65,
2143 0x3A, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x00, 0x4E, 0x56,
2144 0x44, 0x41, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x57, 0x65, 0x62,
2145 0x3A };
2146
2147 UInt8 Replace[] = { 0x49, 0x4F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65,
2148 0x3A, 0x2F, 0x6E, 0x76, 0x64, 0x61, 0x64, 0x72, 0x76, 0x00, 0x4E, 0x56,
2149 0x44, 0x41, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x57, 0x65, 0x62,
2150 0x3A };
2151 count = FindAndReplace(data,
2152 DriverSize,
2153 StartLocation,
2154 Find,
2155 sizeof(Find),
2156 Replace,
2157 0);
2158 }
2159 else
2160 {
2161 verbose("Error: Unable to add nvdadrv node\n");
2162 }
2163
2164 }
2165 return count;
2166}
2167
2168// ===================================
2169// Micky1979, 2017
2170// patch_prelinked_kexts
2171void patch_prelinked_kexts(void *kernelData,
2172 u_int32_t uncompressed_size,
2173 unsigned prelinkTextVmaddr,
2174 unsigned prelinkTextFileOff)
2175{
2176 TagPtr KextsPatches;
2177 bool canPatchKexts = false;
2178 unsigned long prelinkDictSize;
2179 unsigned int Index;
2180 unsigned int Count = 0;
2181
2182 UInt8 *Bytes = (UInt8 *)kernelData;
2183
2184 UInt8 *prelinkDic = NULL;
2185 UInt32 prelinkDictStartLocation = 0;
2186 UInt32 prelinkDictEndLocation = 0;
2187
2188
2189 if (bootInfo->kextConfig.dictionary)
2190 {
2191KextsPatches = XMLGetProperty(bootInfo->kextConfig.dictionary, (const char*)"KextsPatches");
2192 }
2193
2194 verbose("[ KEXTS PATCHER START ]\n");
2195 //int lessBytes = (int)((uncompressed_size/3)*2); // speedup, the _PrelinkInfoDictionary should not be 1/3 of entire cache!
2196 for (Index = 0/*lessBytes*/; Index < uncompressed_size; ++Index)
2197 {
2198 //scan for _PrelinkInfoDictionary
2199 if (Bytes[Index] == 0x3C
2200 && Bytes[Index + 1] == 0x64
2201 && Bytes[Index + 2] == 0x69
2202 && Bytes[Index + 3] == 0x63
2203 && Bytes[Index + 4] == 0x74
2204 && Bytes[Index + 5] == 0x3E
2205 && Bytes[Index + 6] == 0x3C
2206 && Bytes[Index + 7] == 0x6B
2207 && Bytes[Index + 8] == 0x65
2208 && Bytes[Index + 9] == 0x79
2209 && Bytes[Index + 10] == 0x3E
2210 && Bytes[Index + 11] == 0x5F
2211 && Bytes[Index + 12] == 0x50
2212 && Bytes[Index + 13] == 0x72
2213 && Bytes[Index + 14] == 0x65
2214 && Bytes[Index + 15] == 0x6C
2215 && Bytes[Index + 16] == 0x69
2216 && Bytes[Index + 17] == 0x6E
2217 && Bytes[Index + 18] == 0x6B
2218 && Bytes[Index + 19] == 0x49
2219 && Bytes[Index + 20] == 0x6E
2220 && Bytes[Index + 21] == 0x66
2221 && Bytes[Index + 22] == 0x6F
2222 && Bytes[Index + 23] == 0x44
2223 && Bytes[Index + 24] == 0x69
2224 && Bytes[Index + 25] == 0x63
2225 && Bytes[Index + 26] == 0x74
2226 && Bytes[Index + 27] == 0x69
2227 && Bytes[Index + 28] == 0x6F
2228 && Bytes[Index + 29] == 0x6E
2229 && Bytes[Index + 30] == 0x61
2230 && Bytes[Index + 31] == 0x72
2231 && Bytes[Index + 32] == 0x79
2232 && Bytes[Index + 33] == 0x3C
2233 && Bytes[Index + 34] == 0x2F
2234 && Bytes[Index + 35] == 0x6B
2235 && Bytes[Index + 36] == 0x65
2236 && Bytes[Index + 37] == 0x79
2237 && Bytes[Index + 38] == 0x3E)
2238 {
2239 Count++;
2240 prelinkDictStartLocation = Index;
2241 DBG("\tFound _PrelinkInfoDictionary at 0x%08X index = %d\n", (unsigned int)prelinkDictStartLocation, Index);
2242 canPatchKexts = true;
2243 break;
2244 }
2245 }
2246
2247 if (prelinkDictStartLocation)
2248 {
2249 for (Index = prelinkDictStartLocation; Index < uncompressed_size; ++Index)
2250 {
2251 // end of prelink ( <> plus some zeros)
2252 if (Bytes[Index] == 0x3C
2253 && Bytes[Index + 1] == 0x2F
2254 && Bytes[Index + 2] == 0x64
2255 && Bytes[Index + 3] == 0x69
2256 && Bytes[Index + 4] == 0x63
2257 && Bytes[Index + 5] == 0x74
2258 && Bytes[Index + 6] == 0x3E
2259 && Bytes[Index + 7] == 0x00
2260 && Bytes[Index + 8] == 0x00
2261 && Bytes[Index + 9] == 0x00
2262 && Bytes[Index + 10] == 0x00
2263 && Bytes[Index + 11] == 0x00
2264 && Bytes[Index + 12] == 0x00
2265 && Bytes[Index + 13] == 0x00)
2266 {
2267 Count++;
2268
2269 if ((Count = 2))
2270 {
2271 canPatchKexts = true;
2272 prelinkDictEndLocation = Index + 7 ;
2273 DBG("\tFound _PrelinkInfoDictionary end location at 0x%08X index = %d\n", (unsigned int)prelinkDictEndLocation, Index);
2274 }
2275 break;
2276 }
2277 }
2278 }
2279
2280 if (canPatchKexts)
2281 {
2282 prelinkDictSize = uncompressed_size - prelinkDictStartLocation;
2283 prelinkDic = malloc(prelinkDictSize);
2284 memcpy(prelinkDic, Bytes+prelinkDictStartLocation, prelinkDictSize);
2285 TagPtr prelinkInfoPtr = NULL;
2286 XMLParseFile( (char *)prelinkDic, &prelinkInfoPtr );
2287
2288 if (prelinkInfoPtr)
2289 {
2290 TagPtr prelinkInfoDictionary = XMLGetProperty(prelinkInfoPtr, "_PrelinkInfoDictionary");
2291 if (!prelinkInfoDictionary)
2292 {
2293 verbose("Unable to allocate the _PrelinkInfoDictionary, kexts patcher skipped.");
2294 return;
2295 }
2296 int count = XMLTagCount(prelinkInfoDictionary);
2297 while(count)
2298 {
2299 TagPtr sub = XMLGetElement( prelinkInfoDictionary, count-1);
2300 if (sub && XMLIsDict(sub))
2301 {
2302 char* execPath = XMLCastString(XMLGetProperty(sub, (const char*)"CFBundleExecutable"));
2303
2304 if (execPath != NULL)
2305 {
2306 UInt32 kextSize = XMLCastInteger(XMLGetProperty(sub, (const char*)"_PrelinkExecutableSize"));
2307 UInt32 kextAddr = XMLCastInteger(XMLGetProperty(sub, (const char*)"_PrelinkExecutableSourceAddr"));
2308
2309
2310 if (kextAddr && kextSize)
2311 {
2312 // adjust binary address location
2313 kextAddr -= prelinkTextVmaddr;
2314 kextAddr += prelinkTextFileOff;
2315
2316 DBG("\t[%d] found exec:%s (size = %u, kextAddr = 0x%X [vmaddr = 0x%X fileoff = 0x%X])\n", count, execPath,
2317 (unsigned int)kextSize, (unsigned int)kextAddr, (unsigned int)prelinkTextVmaddr, (unsigned int)prelinkTextFileOff);
2318
2319 if (!strcmp(execPath, "FakeSMC"))
2320 {
2321 FakeSMCLoaded = true;
2322 }
2323
2324// chameleon patches
2325patchBooterDefinedKext(execPath, kernelData, kextSize, kextAddr);
2326
2327 // user's defined
2328 if (KextsPatches && XMLIsDict(KextsPatches))
2329 {
2330 pach_binaryUsingDictionary(kernelData,
2331 kextSize,
2332 kextAddr,
2333 execPath,
2334 KextsPatches);
2335 }
2336
2337#if DEBUG_KERNEL
2338 getchar();
2339#endif
2340 }
2341 }
2342 }
2343
2344 count --;
2345 }
2346 }
2347 }
2348 else
2349 {
2350 verbose("Unable to find the _PrelinkInfoDictionary, kexts patcher skipped.");
2351 }
2352
2353 if (prelinkDic) free(prelinkDic);
2354 verbose("Kexts patcher: end!\n\n");
2355}
2356
2357void patchBooterDefinedKext(const char *kext, void *driverAddr, UInt32 DriverSize, UInt32 StartLocation)
2358{
2359if ((!strcmp(kext, "AppleRTC")) && AppleRTCPatch)
2360{
2361verbose("\tPatching %s:", kext);
2362
2363unsigned int numPatches = AppleRTC_Patch(driverAddr, DriverSize, StartLocation);
2364verbose(" %d substitutions made!\n", numPatches);
2365}
2366
2367if ((!strcmp(kext, "AppleIntelCPUPowerManagement")) && AICPMPatch)
2368{
2369verbose("\tPatching %s (locked msr):\n", kext);
2370
2371unsigned int numPatches = AsusAICPUPMPatch(driverAddr, DriverSize, StartLocation);
2372verbose("\t %d substitutions made!\n", numPatches);
2373}
2374
2375if ((!strcmp(kext, "NVDAStartupWeb")) && NVIDIAWebDrv)
2376{
2377verbose("\tPatching %s (force load w/o nvram):\n", kext);
2378
2379unsigned int numPatches = patch_NVDAStartupWeb(driverAddr, DriverSize, StartLocation);
2380verbose("\t %d substitutions made!\n", numPatches);
2381}
2382
2383if ((!strcmp(kext, "IOAHCIBlockStorage")) && TrimEnablerSata)
2384{
2385verbose("\tPatching %s (trim enabler SATA):", kext);
2386
2387unsigned int numPatches = trimEnablerSata(driverAddr, DriverSize, StartLocation);
2388verbose(" %d substitutions made!\n", numPatches);
2389}
2390
2391if ((!strcmp(kext, "AppleAHCIPort")) && OrangeIconFixSata)
2392{
2393verbose("\tPatching %s (orange icon fix):", kext);
2394
2395unsigned int numPatches = patch_AppleAHCIPort_OrangeFix(driverAddr, DriverSize, StartLocation);
2396verbose(" %d substitutions made!\n", numPatches);
2397}
2398}
2399
2400// ===================================
2401// Boolean function to check the full OSX match version
2402bool checkFullOSVer(const char *version)
2403{
2404// We are in a version with 7 char ?
2405if ( (sizeof(version) == 7) && ('.' == version[5]) && ('\0' != version[6]) ) // 10.xx.x
2406{
2407return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2408&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2409&& (gBootVolume->OSFullVer[2] == version[2]) // .
2410&& (gBootVolume->OSFullVer[3] == version[3]) // x
2411&& (gBootVolume->OSFullVer[4] == version[4]) // x
2412&& (gBootVolume->OSFullVer[5] == version[5]) // .
2413&& (gBootVolume->OSFullVer[6] == version[6]) // x
2414);
2415}
2416
2417// We are in a version with 7 char ?
2418if ( (sizeof(version) == 7) && ('.' == version[4]) && ('\0' != version[6]) ) // 10.4.11
2419{
2420return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2421&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2422&& (gBootVolume->OSFullVer[2] == version[2]) // .
2423&& (gBootVolume->OSFullVer[3] == version[3]) // 4
2424&& (gBootVolume->OSFullVer[4] == version[4]) // .
2425&& (gBootVolume->OSFullVer[5] == version[5]) // x
2426&& (gBootVolume->OSFullVer[6] == version[6]) // x
2427);
2428}
2429
2430// We are in a version with 6 char ?
2431if ( (sizeof(version) == 6) && ('.' == version[4]) && ('\0' != version[5]) ) // 10.x.x
2432{
2433return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2434&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2435&& (gBootVolume->OSFullVer[2] == version[2]) // .
2436&& (gBootVolume->OSFullVer[3] == version[3]) // x
2437&& (gBootVolume->OSFullVer[4] == version[4]) // .
2438&& (gBootVolume->OSFullVer[5] == version[5]) // x
2439);
2440}
2441
2442// We are in a version with 5 char ?
2443if ( (sizeof(version) == 5) && ('.' != version[4]) && ('\0' != version[4]) ) // 10.xx
2444{
2445return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2446&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2447&& (gBootVolume->OSFullVer[2] == version[2]) // .
2448&& (gBootVolume->OSFullVer[3] == version[3]) // x
2449&& (gBootVolume->OSFullVer[4] == version[4]) // x
2450);
2451}
2452
2453// We are in a version with 4 char ?
2454if ( (sizeof(version) == 4) && ('\0' != version[3]) ) // 10.x
2455{
2456return ( (gBootVolume->OSFullVer[0] == version[0]) // 1
2457&& (gBootVolume->OSFullVer[1] == version[1]) // 0
2458&& (gBootVolume->OSFullVer[2] == version[2]) // .
2459&& (gBootVolume->OSFullVer[3] == version[3]) // x
2460);
2461}
2462
2463// no match found
2464return false;
2465}
2466

Archive Download this file

Revision: 2918