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

Archive Download this file

Revision: 2885