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

Archive Download this file

Revision: 2883