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

Archive Download this file

Revision: 2871