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 | */␊ |
40 | void patch_kernel_internal(void *kernelData, u_int32_t uncompressed_size)␊ |
41 | {␊ |
42 | ␉// ================================␊ |
43 | ␉if (!useDarwinVersion)␊ |
44 | ␉{␊ |
45 | ␉␉kernelOSVer = MacOSVerCurrent;␊ |
46 | ␉}␊ |
47 | ␊ |
48 | ␉// ================================␊ |
49 | ␉verbose("[ KERNEL PATCHER START ]\n");␊ |
50 | ␊ |
51 | ␉/* to debug kernelOSVer and see if match the OS version: */␊ |
52 | ␉DBG("\n\tMacOSVerCurrent = %08x version.\n\n", MacOSVerCurrent);␊ |
53 | ␉DBG("\n\tkernelOSVer = %08x version.\n\n", kernelOSVer);␊ |
54 | ␊ |
55 | ␉verbose("\n\tWill patch for %d.%d.%d kernel version compatible.\n\n", gDarwinMajor, gDarwinMinor, gDarwinRev);␊ |
56 | ␊ |
57 | ␉verbose("\tKernelBooter_kexts state: %s!\n", KernelBooter_kexts ? " enabled" : "disabled");␊ |
58 | ␉verbose("\tKernelPm state: %s!\n", KernelPm ? " enabled" : "disabled");␊ |
59 | ␉verbose("\tKernelLapicError state: %s!\n", KernelLapicError ? " enabled" : "disabled");␊ |
60 | ␉verbose("\tKernelLapicVersion state: %s!\n", KernelLapicVersion ? " enabled" : "disabled");␊ |
61 | ␉verbose("\tKernelHaswell state: %s!\n", KernelHaswell ? " enabled" : "disabled");␊ |
62 | ␉verbose("\tKernelcpuFamily state: %s!\n", KernelcpuFamily ? " enabled" : "disabled");␊ |
63 | ␉verbose("\tKernelSSE3 state: %s!\n", KernelSSE3 ? " enabled" : "disabled");␊ |
64 | ␊ |
65 | u_int32_t sizeToScan = uncompressed_size; // for further expansion␊ |
66 | ␊ |
67 | ␉// Select machine arch␊ |
68 | ␉if (archCpuType == CPU_TYPE_I386)␊ |
69 | ␉{␊ |
70 | ␉␉patch_kernel_32((void *)kernelData, sizeToScan);␊ |
71 | ␉}␊ |
72 | ␉else␊ |
73 | ␉{␊ |
74 | ␉␉patch_kernel_64((void *)kernelData, sizeToScan);␊ |
75 | ␉}␊ |
76 | ␊ |
77 | ␉/* VMware issue␊ |
78 | ␉if (patch_string_XNU_init(kernelData))␊ |
79 | ␉{␊ |
80 | ␉␉DBG("\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 | ␊ |
93 | ␉verbose("Kernel patcher: end!\n\n");␊ |
94 | }␊ |
95 | ␊ |
96 | // ===================================␊ |
97 | // patches for a 64-bit kernel.␊ |
98 | void patch_kernel_64(void *kernelData, u_int32_t uncompressed_size) // KernelPatcher_64␊ |
99 | {␊ |
100 | ␉DBG("[ 64-bit ]\n");␊ |
101 | ␊ |
102 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
103 | ␉UInt32 patchLocation = 0, patchLocation1 = 0;␊ |
104 | ␉UInt32 i;␊ |
105 | ␉UInt32 switchaddr = 0;␊ |
106 | ␉UInt32 mask_family = 0, mask_model = 0;␊ |
107 | ␉UInt32 cpuid_family_addr = 0, cpuid_model_addr = 0;␊ |
108 | ␊ |
109 | ␉// Prelinked Extensions Patcher␊ |
110 | ␉if (KernelBooter_kexts)␊ |
111 | ␉{␊ |
112 | patch_BooterExtensions_64(kernelData);␊ |
113 | ␉}␊ |
114 | ␊ |
115 | ␉// Lapic Error␊ |
116 | ␉if (KernelLapicError && patch_lapic_init_64(kernelData))␊ |
117 | ␉{␊ |
118 | ␉␉verbose("\tLapic Error call removed.\n");␊ |
119 | ␉}␊ |
120 | ␊ |
121 | ␉// Lapic Version␊ |
122 | ␉if (KernelLapicVersion && patch_lapic_version_init_64(kernelData))␊ |
123 | ␉{␊ |
124 | ␉␉verbose("\tLapic Version call removed.\n");␊ |
125 | ␉}␊ |
126 | ␊ |
127 | ␉// Power Managment␊ |
128 | ␉if (KernelPm && patch_pm_init(kernelData))␊ |
129 | ␉{␊ |
130 | ␉␉verbose("\tPower Managment patch applied.\n");␊ |
131 | ␉}␊ |
132 | ␊ |
133 | ␉// Haswell Kernel Patcher␊ |
134 | ␉if ( KernelHaswell && (kernelOSVer >= MacOSVer2Int("10.8")) ) // Haswell "E" and "ULT" support␊ |
135 | ␉{␊ |
136 | ␉␉switch (Platform.CPU.Family)␊ |
137 | ␉␉{␊ |
138 | ␉␉␉case 0x06:␊ |
139 | ␉␉␉{␊ |
140 | ␉␉␉␉switch (Platform.CPU.Model)␊ |
141 | ␉␉␉␉{␊ |
142 | ␉␉␉␉␉case CPUID_MODEL_HASWELL_SVR: // Haswell-E Kernel Patcher␊ |
143 | ␉␉␉␉␉␉if (patch_haswell_E_init(kernelData))␊ |
144 | ␉␉␉␉␉␉{␊ |
145 | ␉␉␉␉␉␉␉verbose("\tHaswell-E Kernel patch applied.\n");␊ |
146 | ␉␉␉␉␉␉}␊ |
147 | ␉␉␉␉␉␉break;␊ |
148 | ␊ |
149 | ␉␉␉␉␉case CPUID_MODEL_HASWELL_ULT: // Haswell-ULT Kernel Patcher␊ |
150 | ␉␉␉␉␉␉if (patch_haswell_ULT_init(kernelData))␊ |
151 | ␉␉␉␉␉␉{␊ |
152 | ␉␉␉␉␉␉␉verbose("\tHaswell-ULT Kernel patch applied.\n");␊ |
153 | ␉␉␉␉␉␉}␊ |
154 | ␉␉␉␉␉␉break;␊ |
155 | ␊ |
156 | ␉␉␉␉␉default:␊ |
157 | ␉␉␉␉␉␉verbose("\tNo Haswell-ULT/-E Kernel patch applied for this CPU.\n");␊ |
158 | ␉␉␉␉␉␉break;␊ |
159 | ␉␉␉␉}␊ |
160 | ␉␉␉}␊ |
161 | ␉␉}␊ |
162 | ␉}␊ |
163 | ␊ |
164 | ␉if (KernelcpuFamily)␊ |
165 | ␉{␊ |
166 | ␉␉verbose("\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);␊ |
170 | ␉␉for (i=0; i<0x1000000; i++)␊ |
171 | ␉␉{␊ |
172 | ␉␉␉if (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␊ |
182 | ␉␉␉␉patchLocation = i-5;␊ |
183 | ␉␉␉␉break;␊ |
184 | ␉␉␉}␊ |
185 | ␉␉}␊ |
186 | ␊ |
187 | ␉␉if (!patchLocation)␊ |
188 | ␉␉{␊ |
189 | ␉␉␉verbose("\t_cpuid_set_info Unsupported CPU _panic not found \n");␊ |
190 | ␉␉␉return;␊ |
191 | ␉␉}␊ |
192 | ␊ |
193 | ␉␉// make sure only kernels for OSX 10.6.0 to 10.7.3 are being patched by this approach␊ |
194 | ␉␉if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer <= MacOSVer2Int("10.7.3"))␊ |
195 | ␉␉{␊ |
196 | ␊ |
197 | ␉␉␉verbose("\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␊ |
200 | ␉␉␉if (kernelOSVer < MacOSVer2Int("10.6.2"))␊ |
201 | ␉␉␉{␊ |
202 | ␉␉␉␉for (i=0; i<0x1000000; i++)␊ |
203 | {␊ |
204 | ␉␉␉␉␉// find _tsc_init panic address by byte sequence 488d3df4632a00␊ |
205 | ␉␉␉␉␉if (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 | ␉␉␉␉␉{␊ |
213 | ␉␉␉␉␉␉patchLocation1 = i+9;␊ |
214 | ␉␉␉␉␉␉verbose("\tFound _tsc_init _panic address at 0x%08x\n", (unsigned int)patchLocation1);␊ |
215 | ␉␉␉␉␉␉break;␊ |
216 | ␉␉␉␉␉}␊ |
217 | ␉␉␉␉}␊ |
218 | ␊ |
219 | ␉␉␉␉// NOP _panic call␊ |
220 | ␉␉␉␉if (patchLocation1)␊ |
221 | ␉␉␉␉{␊ |
222 | ␉␉␉␉␉bytes[patchLocation1 + 0] = 0x90;␊ |
223 | ␉␉␉␉␉bytes[patchLocation1 + 1] = 0x90;␊ |
224 | ␉␉␉␉␉bytes[patchLocation1 + 2] = 0x90;␊ |
225 | ␉␉␉␉␉bytes[patchLocation1 + 3] = 0x90;␊ |
226 | ␉␉␉␉␉bytes[patchLocation1 + 4] = 0x90;␊ |
227 | ␉␉␉␉}␊ |
228 | ␉␉␉}␊ |
229 | ␉␉␉else␊ |
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 | ␉␉␉␉ */␊ |
237 | ␉␉␉␉switchaddr = patchLocation - 19;␊ |
238 | ␉␉␉␉verbose("\tswitch statement patch location is 0x%08lx\n", (switchaddr+6));␊ |
239 | ␊ |
240 | ␉␉␉␉if (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␊ |
248 | ␉␉␉␉␉cpuid_family_addr =␊ |
249 | ␉␉␉␉␉␉bytes[switchaddr + 2] << 0 |␊ |
250 | ␉␉␉␉␉␉bytes[switchaddr + 3] << 8 |␊ |
251 | ␉␉␉␉␉␉bytes[switchaddr + 4] << 16 |␊ |
252 | ␉␉␉␉␉␉bytes[switchaddr + 5] << 24;␊ |
253 | ␉␉␉␉␉cpuid_family_addr = cpuid_family_addr + (switchaddr + 10);␊ |
254 | ␊ |
255 | ␉␉␉␉␉if (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␊ |
259 | ␉␉␉␉␉␉if (kernelOSVer == MacOSVer2Int("10.6.2"))␊ |
260 | ␉␉␉␉␉␉{␊ |
261 | ␉␉␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X12B;␊ |
262 | ␉␉␉␉␉␉}␊ |
263 | ␉␉␉␉␉␉// for 10.6.3 to 10.6.7 it's offset by 303 bytes␊ |
264 | ␉␉␉␉␉␉else if (kernelOSVer <= MacOSVer2Int("10.6.7"))␊ |
265 | ␉␉␉␉␉␉{␊ |
266 | ␉␉␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X12F;␊ |
267 | ␉␉␉␉␉␉}␊ |
268 | ␉␉␉␉␉␉// for 10.6.8 to 10.7.3 kernels - by 339 bytes␊ |
269 | ␉␉␉␉␉␉else␊ |
270 | ␉␉␉␉␉␉{␊ |
271 | ␉␉␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X153;␊ |
272 | ␉␉␉␉␉␉}␊ |
273 | ␊ |
274 | ␉␉␉␉␉␉verbose("\tcpuid_family address: 0x%08X\n", (unsigned int)cpuid_family_addr);␊ |
275 | ␉␉␉␉␉␉verbose("\tcpuid_model address: 0x%08X\n", (unsigned int)cpuid_model_addr);␊ |
276 | ␊ |
277 | ␉␉␉␉␉␉switchaddr += 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␊ |
280 | ␉␉␉␉␉␉mask_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");␊ |
284 | ␉␉␉␉␉␉bytes[switchaddr+0] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;␊ |
285 | ␉␉␉␉␉␉bytes[switchaddr+1] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;␊ |
286 | ␉␉␉␉␉␉bytes[switchaddr+2] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;␊ |
287 | ␉␉␉␉␉␉bytes[switchaddr+3] = (CPUFAMILY_INTEL_PENRYN & 0xFF000000) >> 24;␊ |
288 | ␊ |
289 | ␉␉␉␉␉␉// mov dword [ds:0xffffff80008a216d], 0x2000117␊ |
290 | ␉␉␉␉␉␉bytes[switchaddr+4] = 0xC7;␊ |
291 | ␉␉␉␉␉␉bytes[switchaddr+5] = 0x05;␊ |
292 | ␉␉␉␉␉␉bytes[switchaddr+6] = (UInt8)((mask_model & 0x000000FF) >> 0);␊ |
293 | ␉␉␉␉␉␉bytes[switchaddr+7] = (UInt8)((mask_model & 0x0000FF00) >> 8);␊ |
294 | ␉␉␉␉␉␉bytes[switchaddr+8] = (UInt8)((mask_model & 0x00FF0000) >> 16);␊ |
295 | ␉␉␉␉␉␉bytes[switchaddr+9] = (UInt8)((mask_model & 0xFF000000) >> 24);␊ |
296 | ␉␉␉␉␉␉bytes[switchaddr+10] = 0x17; // cpuid_model (Penryn)␊ |
297 | ␉␉␉␉␉␉bytes[switchaddr+11] = 0x01; // cpuid_extmodel␊ |
298 | ␉␉␉␉␉␉bytes[switchaddr+12] = 0x00; // cpuid_extfamily␊ |
299 | ␉␉␉␉␉␉bytes[switchaddr+13] = 0x02; // cpuid_stepping␊ |
300 | ␊ |
301 | ␉␉␉␉␉␉// fill remainder with 4 NOPs␊ |
302 | ␉␉␉␉␉␉for (i = 14; i < 18; i++)␊ |
303 | ␉␉␉␉␉␉{␊ |
304 | ␉␉␉␉␉␉␉bytes[switchaddr+i] = 0x90;␊ |
305 | ␉␉␉␉␉␉}␊ |
306 | ␉␉␉␉␉}␊ |
307 | ␉␉␉␉}␊ |
308 | ␉␉␉␉else␊ |
309 | ␉␉␉␉{␊ |
310 | ␉␉␉␉␉verbose("\tUnable to determine cpuid_family address, patching aborted\n");␊ |
311 | ␉␉␉␉␉return;␊ |
312 | ␉␉␉␉}␊ |
313 | ␉␉␉}␊ |
314 | ␊ |
315 | ␉␉␉// patch sse3␊ |
316 | ␉␉␉if (KernelSSE3 && (SNOW_LEOPARD))␊ |
317 | ␉␉␉{␊ |
318 | ␉␉␉␉patch_SSE3_6((void *)bytes);␊ |
319 | ␉␉␉}␊ |
320 | ␊ |
321 | ␉␉␉if (KernelSSE3 && (LION))␊ |
322 | ␉␉␉{␊ |
323 | ␉␉␉␉patch_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␊ |
329 | ␉␉else if (kernelOSVer >= MacOSVer2Int("10.7.4"))␊ |
330 | ␉␉{␊ |
331 | ␉␉␉verbose("\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 | ␉␉␉ */␊ |
338 | ␉␉␉switchaddr = patchLocation-45;␊ |
339 | ␉␉␉verbose("\tswitch statement patch location is 0x%08X\n", (unsigned int)switchaddr);␊ |
340 | ␊ |
341 | ␉␉␉if(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␊ |
350 | ␉␉␉␉cpuid_family_addr =␊ |
351 | ␉␉␉␉␉bytes[switchaddr - 4] << 0 |␊ |
352 | ␉␉␉␉␉bytes[switchaddr - 3] << 8 |␊ |
353 | ␉␉␉␉␉bytes[switchaddr - 2] << 16 |␊ |
354 | ␉␉␉␉␉bytes[switchaddr - 1] << 24;␊ |
355 | ␉␉␉␉cpuid_family_addr = cpuid_family_addr + switchaddr;␊ |
356 | ␊ |
357 | ␉␉␉␉if (cpuid_family_addr)␊ |
358 | ␉␉␉␉{␊ |
359 | ␉␉␉␉␉// Determine cpuid_model address␊ |
360 | ␉␉␉␉␉// for 10.6.8+ kernels it's 339 bytes apart from cpuid_family address␊ |
361 | ␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X153;␊ |
362 | ␊ |
363 | ␉␉␉␉␉verbose("\tcpuid_family address: 0x%08X\n", (unsigned int)cpuid_family_addr);␊ |
364 | ␉␉␉␉␉verbose("\tcpuid_model address: 0x%08X\n", (unsigned int)cpuid_model_addr);␊ |
365 | ␊ |
366 | ␉␉␉␉␉// Calculate masks for patching␊ |
367 | ␉␉␉␉␉mask_family = cpuid_family_addr - (switchaddr +15);␊ |
368 | ␉␉␉␉␉mask_model = cpuid_model_addr - (switchaddr +25);␊ |
369 | ␉␉␉␉␉verbose("\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␊ |
373 | ␉␉␉␉␉bytes[switchaddr+0] = bytes[patchLocation-13];␊ |
374 | ␉␉␉␉␉bytes[switchaddr+1] = bytes[patchLocation-12];␊ |
375 | ␉␉␉␉␉// retain original, but move jump offset by 20 bytes forward␊ |
376 | ␉␉␉␉␉// jne for above test␊ |
377 | ␉␉␉␉␉bytes[switchaddr+2] = bytes[patchLocation-11];␊ |
378 | ␉␉␉␉␉bytes[switchaddr+3] = bytes[patchLocation-10]+0x20;␊ |
379 | ␉␉␉␉␉// mov ebx, 0x78ea4fbc␊ |
380 | ␉␉␉␉␉bytes[switchaddr+4] = 0xBB;␊ |
381 | ␉␉␉␉␉bytes[switchaddr+5] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;␊ |
382 | ␉␉␉␉␉bytes[switchaddr+6] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;␊ |
383 | ␉␉␉␉␉bytes[switchaddr+7] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;␊ |
384 | ␉␉␉␉␉bytes[switchaddr+8] = (CPUFAMILY_INTEL_PENRYN & 0xFF000000) >> 24;␊ |
385 | ␊ |
386 | ␉␉␉␉␉// mov dword, ebx␊ |
387 | ␉␉␉␉␉bytes[switchaddr+9] = 0x89;␊ |
388 | ␉␉␉␉␉bytes[switchaddr+10] = 0x1D;␊ |
389 | ␉␉␉␉␉// cpuid_cpufamily address 0xffffff80008a21a0␊ |
390 | ␉␉␉␉␉bytes[switchaddr+11] = (UInt8)((mask_family & 0x000000FF) >> 0);␊ |
391 | ␉␉␉␉␉bytes[switchaddr+12] = (UInt8)((mask_family & 0x0000FF00) >> 8);␊ |
392 | ␉␉␉␉␉bytes[switchaddr+13] = (UInt8)((mask_family & 0x00FF0000) >> 16);␊ |
393 | ␉␉␉␉␉bytes[switchaddr+14] = (UInt8)((mask_family & 0xFF000000) >> 24);␊ |
394 | ␊ |
395 | ␉␉␉␉␉// mov dword␊ |
396 | ␉␉␉␉␉bytes[switchaddr+15] = 0xC7;␊ |
397 | ␉␉␉␉␉bytes[switchaddr+16] = 0x05;␊ |
398 | ␉␉␉␉␉// cpuid_model address 0xffffff80008b204d␊ |
399 | ␉␉␉␉␉bytes[switchaddr+17] = (UInt8)((mask_model & 0x000000FF) >> 0);␊ |
400 | ␉␉␉␉␉bytes[switchaddr+18] = (UInt8)((mask_model & 0x0000FF00) >> 8);␊ |
401 | ␉␉␉␉␉bytes[switchaddr+19] = (UInt8)((mask_model & 0x00FF0000) >> 16);␊ |
402 | ␉␉␉␉␉bytes[switchaddr+20] = (UInt8)((mask_model & 0xFF000000) >> 24);␊ |
403 | ␊ |
404 | ␉␉␉␉␉bytes[switchaddr+21] = 0x17; // cpuid_model␊ |
405 | ␉␉␉␉␉bytes[switchaddr+22] = 0x01; // cpuid_extmodel␊ |
406 | ␉␉␉␉␉bytes[switchaddr+23] = 0x00; // cpuid_extfamily␊ |
407 | ␉␉␉␉␉bytes[switchaddr+24] = 0x02; // cpuid_stepping␊ |
408 | ␊ |
409 | ␉␉␉␉␉// fill remainder with 25 NOPs␊ |
410 | ␉␉␉␉␉for (i=25; i<25+25; i++)␊ |
411 | ␉␉␉␉␉{␊ |
412 | ␉␉␉␉␉␉bytes[switchaddr+i] = 0x90;␊ |
413 | ␉␉␉␉␉}␊ |
414 | ␉␉␉␉}␊ |
415 | ␉␉␉}␊ |
416 | ␉␉␉else␊ |
417 | ␉␉␉{␊ |
418 | ␉␉␉␉verbose("\tUnable to determine cpuid_family address, patching aborted\n");␊ |
419 | ␉␉␉␉return;␊ |
420 | ␉␉␉}␊ |
421 | ␉␉}␊ |
422 | ␊ |
423 | ␉␉verbose("\n");␊ |
424 | ␉}␊ |
425 | }␊ |
426 | ␊ |
427 | // ===================================␊ |
428 | // patches for a 32-bit kernel.␊ |
429 | void patch_kernel_32(void *kernelData, u_int32_t uncompressed_size) // KernelPatcher_32␊ |
430 | {␊ |
431 | ␉DBG("[ 32-bit ]\n");␊ |
432 | ␊ |
433 | ␉UInt8 *bytes = ( UInt8 *)kernelData;␊ |
434 | ␉UInt32 patchLocation = 0, patchLocation1 = 0;␊ |
435 | ␉UInt32 i;␊ |
436 | ␉UInt32 jumpaddr;␊ |
437 | ␊ |
438 | ␉// Prelinked Extensions Patcher␊ |
439 | ␉if (KernelBooter_kexts)␊ |
440 | ␉{␊ |
441 | ␉␉patch_BooterExtensions_32(kernelData);␊ |
442 | ␉}␊ |
443 | ␊ |
444 | ␉// Lapic Error␊ |
445 | ␉if (KernelLapicError && patch_lapic_init_32(kernelData))␊ |
446 | ␉{␊ |
447 | ␉␉verbose("\tLapic Error call removed.\n");␊ |
448 | ␉}␊ |
449 | ␊ |
450 | ␉// Lapic Version␊ |
451 | ␉if (KernelLapicVersion && patch_lapic_version_init_32(kernelData))␊ |
452 | ␉{␊ |
453 | ␉␉verbose("\tLapic Version call removed.\n");␊ |
454 | ␉}␊ |
455 | ␊ |
456 | ␉if (KernelcpuFamily)␊ |
457 | ␉{␊ |
458 | ␉␉verbose("\t- Looking for _cpuid_set_info _panic ...\n");␊ |
459 | ␉␉// _cpuid_set_info _panic address␊ |
460 | ␉␉for (i = 0; i < 0x1000000; i++)␊ |
461 | ␉␉{␊ |
462 | ␉␉␉if (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 | ␉␉␉{␊ |
472 | ␉␉␉␉patchLocation = i-5;␊ |
473 | ␉␉␉␉verbose("\tFound _cpuid_set_info _panic address at 0x%08X\n", (unsigned int)patchLocation);␊ |
474 | ␉␉␉␉break;␊ |
475 | ␉␉␉}␊ |
476 | ␉␉}␊ |
477 | ␊ |
478 | ␉␉if (!patchLocation)␊ |
479 | ␉␉{␊ |
480 | ␉␉␉verbose("\tCan't find _cpuid_set_info _panic address, patch kernel abort.\n");␊ |
481 | ␉␉␉return;␊ |
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␊ |
487 | ␉␉for (i = 0; i < 0x1000000; i++)␊ |
488 | ␉␉{␊ |
489 | ␉␉␉// _cpuid_set_info _panic address␊ |
490 | ␉␉␉if (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 | ␉␉␉{␊ |
498 | ␉␉␉␉patchLocation1 = i+7;␊ |
499 | ␉␉␉␉verbose("\tFound _tsc_init _panic address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
500 | ␉␉␉␉break;␊ |
501 | ␉␉␉}␊ |
502 | ␉␉}␊ |
503 | ␊ |
504 | ␉␉// found _tsc_init panic addres and patch it␊ |
505 | ␉␉if (patchLocation1)␊ |
506 | ␉␉{␊ |
507 | ␉␉␉bytes[patchLocation1 + 0] = 0x90;␊ |
508 | ␉␉␉bytes[patchLocation1 + 1] = 0x90;␊ |
509 | ␉␉␉bytes[patchLocation1 + 2] = 0x90;␊ |
510 | ␉␉␉bytes[patchLocation1 + 3] = 0x90;␊ |
511 | ␉␉␉bytes[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␊ |
516 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
517 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
518 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
519 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
520 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
521 | ␊ |
522 | ␉␉jumpaddr = patchLocation;␊ |
523 | ␊ |
524 | ␉␉for (i = 0 ;i < 500; i++)␊ |
525 | ␉␉{␊ |
526 | ␉␉␉if (bytes[jumpaddr-i-3] == 0x85␊ |
527 | ␉␉␉␉&& bytes[jumpaddr-i-2] == 0xC0␊ |
528 | ␉␉␉␉&& bytes[jumpaddr-i-1] == 0x75 )␊ |
529 | ␉␉␉{␊ |
530 | ␉␉␉␉jumpaddr -= i;␊ |
531 | ␉␉␉␉bytes[jumpaddr-1] = 0x77;␊ |
532 | ␉␉␉␉if(bytes[patchLocation - 17] == 0xC7)␊ |
533 | ␉␉␉␉{␊ |
534 | ␉␉␉␉␉bytes[jumpaddr] -=10;␊ |
535 | ␉␉␉␉}␊ |
536 | ␉␉␉␉break;␊ |
537 | ␉␉␉}␊ |
538 | ␉␉}␊ |
539 | ␊ |
540 | ␉␉if (jumpaddr == patchLocation)␊ |
541 | ␉␉{␊ |
542 | ␉␉␉verbose("\tCan't Found jumpaddr address.\n");␊ |
543 | ␉␉␉return; //can't find jump location␊ |
544 | ␉␉}␊ |
545 | ␉␉// patch info_p->cpufamily to CPUFAMILY_INTEL_MEROM␊ |
546 | ␊ |
547 | ␉␉if (bytes[patchLocation - 17] == 0xC7)␊ |
548 | ␉␉{␊ |
549 | ␉␉␉bytes[patchLocation - 11] = (CPUFAMILY_INTEL_MEROM & 0x000000FF) >> 0;␊ |
550 | ␉␉␉bytes[patchLocation - 10] = (CPUFAMILY_INTEL_MEROM & 0x0000FF00) >> 8;␊ |
551 | ␉␉␉bytes[patchLocation - 9] = (CPUFAMILY_INTEL_MEROM & 0x00FF0000) >> 16;␊ |
552 | ␉␉␉bytes[patchLocation - 8] = (CPUFAMILY_INTEL_MEROM & 0xFF000000) >> 24;␊ |
553 | ␉␉}␊ |
554 | ␊ |
555 | ␉␉//patch info->cpuid_cpufamily␊ |
556 | ␉␉bytes[patchLocation - 7] = 0xC7;␊ |
557 | ␉␉bytes[patchLocation - 6] = 0x05;␊ |
558 | ␉␉bytes[patchLocation - 5] = bytes[jumpaddr + 3];␊ |
559 | ␉␉bytes[patchLocation - 4] = bytes[jumpaddr + 4];␊ |
560 | ␉␉bytes[patchLocation - 3] = bytes[jumpaddr + 5];␊ |
561 | ␉␉bytes[patchLocation - 2] = bytes[jumpaddr + 6];␊ |
562 | ␊ |
563 | ␉␉bytes[patchLocation - 1] = CPUIDFAMILY_DEFAULT; //cpuid_family need alway set 0x06␊ |
564 | ␉␉bytes[patchLocation + 0] = CPUID_MODEL_MEROM; //cpuid_model set CPUID_MODEL_MEROM␊ |
565 | ␉␉bytes[patchLocation + 1] = 0x01; //cpuid_extmodel alway set 0x01␊ |
566 | ␉␉bytes[patchLocation + 2] = 0x00; //cpuid_extfamily alway set 0x00␊ |
567 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
568 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
569 | ␊ |
570 | ␉␉if (KernelSSE3 && ( LION ))␊ |
571 | ␉␉{␊ |
572 | ␉␉␉patch_SSE3_6((void *)bytes);␊ |
573 | ␉␉}␊ |
574 | ␊ |
575 | ␉␉if (KernelSSE3 && ( LEOPARD ))␊ |
576 | ␉␉{␊ |
577 | ␉␉␉patch_SSE3_5((void *)bytes);␊ |
578 | ␉␉}␊ |
579 | ␉}␊ |
580 | }␊ |
581 | ␊ |
582 | // ===================================␊ |
583 | // Power Managment␊ |
584 | bool patch_pm_init(void *kernelData) // KernelPatchPm␊ |
585 | {␊ |
586 | ␉UInt8 *Ptr = (UInt8 *)kernelData;␊ |
587 | ␉UInt8 *End = Ptr + 0x1000000;␊ |
588 | ␉if (Ptr == NULL)␊ |
589 | ␉{␊ |
590 | ␉␉return false;␊ |
591 | ␉}␊ |
592 | ␊ |
593 | ␉// Credits to RehabMan for the kernel patch information␊ |
594 | ␉// XCPM (Xnu CPU Power Management)␊ |
595 | ␉verbose("\t- Patching kernel power management...\n");␊ |
596 | ␉while (Ptr < End)␊ |
597 | ␉{␊ |
598 | ␉␉if (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␊ |
601 | ␉␉␉if ((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!␊ |
605 | ␉␉␉␉memcpy(Ptr, KernelPatchPmRepl, 18 * sizeof(UInt8)); // Copy block of memory␊ |
606 | ␉␉␉␉memcpy(Ptr + 20 * sizeof(UInt8), KernelPatchPmRepl + 20 * sizeof(UInt8), sizeof(KernelPatchPmSrc) - 20 * sizeof(UInt8)); // Copy block of memory␊ |
607 | ␉␉␉␉verbose("\tKernel power management patch region 1 found and patched\n");␊ |
608 | ␉␉␉␉return true;␊ |
609 | ␉␉␉}␊ |
610 | ␉␉␉else if (memcmp(Ptr + sizeof(UInt64), KernelPatchPmSrc2 + sizeof(UInt64), sizeof(KernelPatchPmSrc2) - sizeof(UInt64)) == 0)␊ |
611 | ␉␉␉{␊ |
612 | ␉␉␉␉// Don't copy more than the source here!␊ |
613 | ␉␉␉␉memcpy(Ptr, KernelPatchPmRepl2, sizeof(KernelPatchPmSrc2)); // Copy block of memory␊ |
614 | ␉␉␉␉verbose("\tKernel power management patch region 2 found and patched\n");␊ |
615 | ␉␉␉␉return true;␊ |
616 | ␉␉␉}␊ |
617 | ␉␉}␊ |
618 | ␉␉// RehabMan: for 10.10 (data portion)␊ |
619 | ␉␉else if (0x00000002000000E2ULL == (*((UInt64 *)Ptr)))␊ |
620 | ␉␉{␊ |
621 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
622 | ␉␉␉verbose("\tKernel power management patch 10.1x(data1) found and patched\n");␊ |
623 | ␉␉}␊ |
624 | ␉␉else if (0x0000004C000000E2ULL == (*((UInt64 *)Ptr)))␊ |
625 | ␉␉{␊ |
626 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
627 | ␉␉␉verbose("\tKernel power management patch 10.1x(data2) found and patched\n");␊ |
628 | ␉␉}␊ |
629 | ␉␉else if (0x00000190000000E2ULL == (*((UInt64 *)Ptr)))␊ |
630 | ␉␉{␊ |
631 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
632 | ␉␉␉verbose("\tKernel power management patch 10.10(data3) found and patched\n");␊ |
633 | ␉␉␉return true;␊ |
634 | ␉␉}␊ |
635 | ␉␉// rehabman: change for 10.11.1 beta 15B38b␊ |
636 | ␉␉else if (0x00001390000000E2ULL == (*((UInt64 *)Ptr)))␊ |
637 | ␉␉{␊ |
638 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
639 | ␉␉␉verbose("\tKernel power management patch 10.11(data3) found and patched\n");␊ |
640 | ␉␉␉return true;␊ |
641 | ␉␉}␊ |
642 | ␉␉// sherlocks: change for 10.12 DP1␊ |
643 | ␉␉else if (0x00003390000000E2ULL == (*((UInt64 *)Ptr)))␊ |
644 | ␉␉{␊ |
645 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
646 | ␉␉␉verbose("\tKernel power management patch 10.12 DP1 found and patched\n");␊ |
647 | ␉␉␉return true;␊ |
648 | ␉␉}␊ |
649 | ␉␉// PMheart: change for 10.13 DP1 17A264c␊ |
650 | ␉␉else if (0x00004000000000E2ULL == (*((UInt64 *)Ptr)))␊ |
651 | ␉␉{␊ |
652 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
653 | ␉␉␉verbose("\tKernel power management patch 10.13 DP1 found and patched\n");␊ |
654 | ␉␉␉return true;␊ |
655 | ␉␉}␊ |
656 | ␉␉Ptr += 16;␊ |
657 | ␉}␊ |
658 | ␉verbose("\tKernel power management patch region not found!\n");␊ |
659 | ␉return false;␊ |
660 | }␊ |
661 | ␊ |
662 | // ===================================␊ |
663 | // Bronya: Lapic Panic Version 64␊ |
664 | bool patch_lapic_version_init_64(void *kernelData) // KernelLapicVersionPatch_64␊ |
665 | {␊ |
666 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
667 | ␉UInt32 patchLocation = 0;␊ |
668 | ␉UInt32 i;␊ |
669 | ␊ |
670 | ␉verbose("\t- Looking for Lapic Version panic call Start\n");␊ |
671 | ␊ |
672 | ␉for (i = 0; i < 0x1000000; i++)␊ |
673 | ␉{␊ |
674 | ␉␉// Bronya: Snow Leopard 10.6 Lapic Version␊ |
675 | ␉␉if (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 | ␉␉{␊ |
682 | ␉␉␉patchLocation = i + 59;␊ |
683 | ␉␉␉verbose("\tFound Snow Leopard Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
684 | ␉␉␉break;␊ |
685 | ␉␉}␊ |
686 | ␉␉// Bronya: Lion 10.7 Lapic Version␊ |
687 | ␉␉else 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 | ␉␉{␊ |
695 | ␉␉␉patchLocation = i + 63;␊ |
696 | ␉␉␉verbose("\tFound Lion, Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
697 | ␉␉␉break;␊ |
698 | ␉␉}␊ |
699 | ␉␉// Bronya: Mountain Lion 10.8 Lapic Version␊ |
700 | ␉␉else 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 | ␉␉{␊ |
713 | ␉␉␉patchLocation = i + 68;␊ |
714 | ␉␉␉verbose("\tFound Mountain Lion, Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
715 | ␉␉␉break;␊ |
716 | ␉␉}␊ |
717 | ␉␉// Bronya: Mavericks 10.9 Lapic Version␊ |
718 | ␉␉else 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 | ␉␉{␊ |
729 | ␉␉␉patchLocation = i + 90;␊ |
730 | ␉␉␉verbose("\tFound Mavericks Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
731 | ␉␉␉break;␊ |
732 | ␉␉}␊ |
733 | ␉␉// Bronya: Yosemite 10.10 lapic version␊ |
734 | ␉␉else 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 | ␉␉{␊ |
742 | ␉␉␉patchLocation = i + 42;␊ |
743 | ␉␉␉verbose("\tFound Yosemite Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
744 | ␉␉␉break;␊ |
745 | ␉␉}␊ |
746 | ␉␉// Bronya: El Capitan 10.11 Lapic Version/10.12/10.13␊ |
747 | ␉␉else 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 | ␉␉{␊ |
753 | ␉␉␉patchLocation = i + 40;␉␊ |
754 | ␊ |
755 | ␉␉␉if (kernelOSVer >= MacOSVer2Int("10.13") && kernelOSVer < MacOSVer2Int("10.14"))␊ |
756 | ␉␉␉{␊ |
757 | ␉␉␉␉verbose("\tFound High Sierra Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
758 | ␉␉␉}␊ |
759 | ␉␉␉else if (kernelOSVer >= MacOSVer2Int("10.12") && kernelOSVer < MacOSVer2Int("10.13"))␊ |
760 | ␉␉␉{␊ |
761 | ␉␉␉␉verbose("\tFound Sierra Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
762 | ␉␉␉}␊ |
763 | ␉␉␉else␊ |
764 | ␉␉␉{␊ |
765 | ␉␉␉␉verbose("\tFound El Capitan Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
766 | ␉␉␉}␊ |
767 | ␉␉␉␊ |
768 | ␉␉␉break;␊ |
769 | ␉␉}␊ |
770 | ␉}␊ |
771 | ␊ |
772 | ␉if (!patchLocation)␊ |
773 | ␉{␊ |
774 | ␉␉verbose("\tCan't find Lapic Version panic, kernel patch aborted.\n");␊ |
775 | ␉␉return false;␊ |
776 | ␉}␊ |
777 | ␊ |
778 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
779 | ␊ |
780 | ␉if (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 | ␉{␊ |
786 | ␉␉verbose("\tLapic Version panic already patched, kernel file manually patched?\n");␊ |
787 | ␉␉return false;␊ |
788 | ␉}␊ |
789 | ␉else␊ |
790 | ␉{␊ |
791 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
792 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
793 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
794 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
795 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
796 | ␉}␊ |
797 | ␉return true;␊ |
798 | }␊ |
799 | ␊ |
800 | // ===================================␊ |
801 | // Lapic Error Panic 64␊ |
802 | bool 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 | ␊ |
806 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
807 | ␉UInt32 patchLocation = 0;␊ |
808 | ␉UInt32 i;␊ |
809 | ␊ |
810 | ␉verbose("\t- Looking for Lapic panic call Start\n");␊ |
811 | ␊ |
812 | ␉for (i = 0; i < 0x1000000; i++)␊ |
813 | ␉{␊ |
814 | ␉␉if (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 | ␉␉{␊ |
832 | ␉␉␉patchLocation = i + 40;␊ |
833 | ␉␉␉verbose("\tFound Snow Leopard Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
834 | ␉␉␉break;␊ |
835 | ␉␉}␊ |
836 | ␉␉else 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 | ␉␉{␊ |
854 | ␉␉␉patchLocation = i + 30;␊ |
855 | ␉␉␉verbose("\tFound %sLion Lapic panic at 0x%08X\n", checkOSVersion("10.7") ? "" : "Mountain ", (unsigned int)patchLocation);␊ |
856 | ␉␉␉break;␊ |
857 | ␉␉}␊ |
858 | ␉␉else 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 | ␉␉{␊ |
876 | ␉␉␉patchLocation = i + 31;␊ |
877 | ␉␉␉verbose("\tFound Mavericks Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
878 | ␉␉␉break;␊ |
879 | ␉␉}␊ |
880 | // RehabMan: 10.10.DP1 lapic␊ |
881 | ␉␉else 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 | ␉␉{␊ |
899 | ␉␉␉patchLocation = i + 28;␊ |
900 | ␉␉␉verbose("\tFound Yosemite Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
901 | ␉␉␉break;␊ |
902 | ␉␉}␊ |
903 | ␉␉// sherlocks: 10.11.DB1␊ |
904 | ␉␉else 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 | ␉␉{␊ |
922 | ␉␉␉patchLocation = i + 1400;␊ |
923 | ␉␉␉verbose("\tFound El Capitan Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
924 | ␉␉␉break;␊ |
925 | ␉␉}␊ |
926 | ␉␉// sherlocks: 10.12.DP1␊ |
927 | ␉␉else 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 | ␉␉{␊ |
945 | ␉␉␉patchLocation = i+1398;␊ |
946 | ␉␉␉DBG("\tFound Sierra Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
947 | ␉␉␉break;␊ |
948 | ␉␉}␊ |
949 | ␉␉// sherlocks: 10.13.DP1␊ |
950 | ␉␉else 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 | ␉␉{␊ |
968 | ␉␉␉patchLocation = i+1396;␊ |
969 | ␉␉␉DBG("\tFound High Sierra Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
970 | ␉␉␉break;␊ |
971 | ␉␉}␊ |
972 | ␉}␊ |
973 | ␊ |
974 | ␉if (!patchLocation)␊ |
975 | ␉{␊ |
976 | ␉␉verbose("\tCan't find Lapic panic, kernel patch aborted.\n");␊ |
977 | ␉␉return false;␊ |
978 | ␉}␊ |
979 | ␊ |
980 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
981 | ␊ |
982 | ␉if (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 | ␉{␊ |
988 | ␉␉verbose("\tLapic panic already patched, kernel file manually patched?\n");␊ |
989 | ␉␉return false;␊ |
990 | ␉}␊ |
991 | ␉else␊ |
992 | ␉{␊ |
993 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
994 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
995 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
996 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
997 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
998 | ␉}␊ |
999 | ␉return true;␊ |
1000 | }␊ |
1001 | ␊ |
1002 | // ===================================␊ |
1003 | // Bronya: Lapic Panic Version 32 bit␊ |
1004 | bool patch_lapic_version_init_32(void *kernelData)␊ |
1005 | {␊ |
1006 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1007 | ␉UInt32 patchLocation = 0;␊ |
1008 | ␉UInt32 i;␊ |
1009 | ␊ |
1010 | ␉verbose("\t- Looking for Lapic Version panic call Start\n");␊ |
1011 | ␊ |
1012 | ␉for (i = 0; i < 0x1000000; i++)␊ |
1013 | ␉{␊ |
1014 | ␉␉// Bronya: Snow Leopard 10.6 Lapic Version␊ |
1015 | ␉␉if (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 | ␉␉{␊ |
1023 | ␉␉␉patchLocation = i+60;␊ |
1024 | ␉␉␉verbose("\tFound Snow Leopard Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
1025 | ␉␉␉break;␊ |
1026 | ␉␉}␊ |
1027 | ␉␉else␊ |
1028 | ␉␉{␊ |
1029 | ␉␉␉// Bronya: Lion 10.7 Lapic Version␊ |
1030 | ␉␉␉if (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 | ␉␉␉{␊ |
1038 | ␉␉␉␉patchLocation = i+63;␊ |
1039 | ␉␉␉␉verbose("\tFound Lion, Lion Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
1040 | ␉␉␉␉break;␊ |
1041 | ␉␉␉}␊ |
1042 | ␉␉}␊ |
1043 | ␉}␊ |
1044 | ␊ |
1045 | ␉if (!patchLocation)␊ |
1046 | ␉{␊ |
1047 | ␉␉verbose("\tCan't find Lapic Version panic, kernel patch aborted.\n");␊ |
1048 | ␉␉return false;␊ |
1049 | ␉}␊ |
1050 | ␊ |
1051 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
1052 | ␊ |
1053 | ␉if (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 | ␉{␊ |
1059 | ␉␉verbose("\tLapic Version panic already patched, kernel file manually patched?\n");␊ |
1060 | ␉␉return false;␊ |
1061 | ␉}␊ |
1062 | ␉else␊ |
1063 | ␉{␊ |
1064 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
1065 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
1066 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
1067 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
1068 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
1069 | ␉}␊ |
1070 | ␉return true;␊ |
1071 | }␊ |
1072 | ␊ |
1073 | // ===================================␊ |
1074 | // Lapic Error Panic 32␊ |
1075 | bool 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 | ␊ |
1079 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1080 | ␉UInt32 patchLocation=0;␊ |
1081 | ␉UInt32 i;␊ |
1082 | ␊ |
1083 | ␉verbose("\t- Looking for Lapic panic call Start\n");␊ |
1084 | ␊ |
1085 | ␉for (i = 0; i < 0x1000000; i++)␊ |
1086 | ␉{␊ |
1087 | ␉␉if (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 | ␉␉{␊ |
1100 | ␉␉␉patchLocation = i + 25;␊ |
1101 | ␉␉␉verbose("\tFound Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
1102 | ␉␉␉break;␊ |
1103 | ␉␉}␊ |
1104 | ␉}␊ |
1105 | ␊ |
1106 | ␉if (!patchLocation)␊ |
1107 | ␉{␊ |
1108 | ␉␉verbose("\tCan't find Lapic panic, kernel patch aborted.\n");␊ |
1109 | ␉␉return false;␊ |
1110 | ␉}␊ |
1111 | ␊ |
1112 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
1113 | ␊ |
1114 | ␉if (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 | ␉{␊ |
1120 | ␉␉verbose("\tLapic panic already patched, kernel file manually patched?\n");␊ |
1121 | ␉␉return false;␊ |
1122 | ␉}␊ |
1123 | ␉else␊ |
1124 | ␉{␊ |
1125 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
1126 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
1127 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
1128 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
1129 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
1130 | ␉}␊ |
1131 | ␉return true;␊ |
1132 | }␊ |
1133 | ␊ |
1134 | // ===================================␊ |
1135 | // Haswell-E Patch␊ |
1136 | bool 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 | ␊ |
1141 | ␉UInt8␉*Bytes;␊ |
1142 | ␉UInt32␉Index;␊ |
1143 | ␉bool␉PatchApplied;␊ |
1144 | ␊ |
1145 | ␉verbose("\t- Searching for Haswell-E patch pattern\n");␊ |
1146 | ␊ |
1147 | ␉Bytes = (UInt8 *)kernelData;␊ |
1148 | ␉PatchApplied = false;␊ |
1149 | ␊ |
1150 | ␉for (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␊ |
1153 | ␉␉if (Bytes[Index] == 0x74␊ |
1154 | ␉␉␉&& Bytes[Index + 1] == 0x11␊ |
1155 | ␉␉␉&& Bytes[Index + 2] == 0x83␊ |
1156 | ␉␉␉&& Bytes[Index + 3] == 0xF8␊ |
1157 | ␉␉␉&& Bytes[Index + 4] == 0x3C)␊ |
1158 | ␉␉{␊ |
1159 | ␉␉␉Bytes[Index + 4] = 0x3F;␊ |
1160 | ␊ |
1161 | ␉␉␉verbose("\tFound Haswell-E pattern #1; patched.\n");␊ |
1162 | ␊ |
1163 | ␉␉␉if (PatchApplied)␊ |
1164 | ␉␉␉{␊ |
1165 | ␉␉␉␉break;␊ |
1166 | ␉␉␉}␊ |
1167 | ␊ |
1168 | ␉␉␉PatchApplied = true;␊ |
1169 | ␉␉}␊ |
1170 | ␊ |
1171 | ␉␉// sudo perl -pi -e 's|\xEB\x0A\x83\xF8\x3A|\xEB\x0A\x83\xF8\x3F|g' /System/Library/Kernels/kernel␊ |
1172 | ␉␉if (Bytes[Index] == 0xEB␊ |
1173 | ␉␉␉&& Bytes[Index + 1] == 0x0A␊ |
1174 | ␉␉␉&& Bytes[Index + 2] == 0x83␊ |
1175 | ␉␉␉&& Bytes[Index + 3] == 0xF8␊ |
1176 | ␉␉␉&& Bytes[Index + 4] == 0x3A)␊ |
1177 | ␉␉{␊ |
1178 | ␉␉␉Bytes[Index + 4] = 0x3F;␊ |
1179 | ␊ |
1180 | ␉␉␉verbose("\tFound Haswell-E pattern #2; patched.\n");␊ |
1181 | ␊ |
1182 | ␉␉␉if (PatchApplied)␊ |
1183 | ␉␉␉{␊ |
1184 | ␉␉␉␉break;␊ |
1185 | ␉␉␉}␊ |
1186 | ␊ |
1187 | ␉␉␉PatchApplied = true;␊ |
1188 | ␉␉}␊ |
1189 | ␉}␊ |
1190 | ␊ |
1191 | ␉if (!PatchApplied)␊ |
1192 | ␉{␊ |
1193 | ␉␉verbose("\tCan't find Haswell-E patch pattern, patch not applied.\n");␊ |
1194 | ␉}␊ |
1195 | ␊ |
1196 | ␉return PatchApplied;␊ |
1197 | }␊ |
1198 | ␊ |
1199 | // ===================================␊ |
1200 | // Haswell-ULT Patch␊ |
1201 | bool 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 | ␊ |
1206 | ␉UInt8␉*Bytes;␊ |
1207 | ␉UInt32␉Index;␊ |
1208 | ␉bool␉PatchApplied;␊ |
1209 | ␊ |
1210 | ␉verbose("\t- Searching for Haswell-ULT patch pattern\n");␊ |
1211 | ␊ |
1212 | ␉Bytes = (UInt8 *)kernelData;␊ |
1213 | ␉PatchApplied = false;␊ |
1214 | ␊ |
1215 | ␉for (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␊ |
1218 | ␉␉if (Bytes[Index] == 0xBB␊ |
1219 | ␉␉␉&& Bytes[Index + 1] == 0xDC␊ |
1220 | ␉␉␉&& Bytes[Index + 2] == 0x82␊ |
1221 | ␉␉␉&& Bytes[Index + 3] == 0xB2␊ |
1222 | ␉␉␉&& Bytes[Index + 4] == 0xdc)␊ |
1223 | ␉␉{␊ |
1224 | ␉␉␉Bytes[Index + 1] = 0x35;␊ |
1225 | ␉␉␉Bytes[Index + 2] = 0xE8;␊ |
1226 | ␉␉␉Bytes[Index + 3] = 0x65;␊ |
1227 | ␉␉␉Bytes[Index + 4] = 0x1F;␊ |
1228 | ␊ |
1229 | ␉␉␉verbose("\tFound Haswell-ULT pattern #1; patched.\n");␊ |
1230 | ␊ |
1231 | ␉␉␉if (PatchApplied)␊ |
1232 | ␉␉␉{␊ |
1233 | ␉␉␉␉break;␊ |
1234 | ␉␉␉}␊ |
1235 | ␊ |
1236 | ␉␉␉PatchApplied = true;␊ |
1237 | ␉␉}␊ |
1238 | ␉}␊ |
1239 | ␊ |
1240 | ␉if (!PatchApplied)␊ |
1241 | ␉{␊ |
1242 | ␉␉verbose("\tCan't find Haswell-ULT patch pattern, patch not applied.\n");␊ |
1243 | ␉}␊ |
1244 | ␊ |
1245 | ␉return PatchApplied;␊ |
1246 | }␊ |
1247 | ␊ |
1248 | // ===================================␊ |
1249 | // Custom Kext injection from Extra/Extensions folder␊ |
1250 | void patch_BooterExtensions_32(void *kernelData)␊ |
1251 | {␊ |
1252 | ␉// KernelBooterExtensionsPatch to load extra kexts besides kernelcache␊ |
1253 | ␉UInt8 *Bytes;␊ |
1254 | ␉UInt32 Index;␊ |
1255 | ␉bool PatchApplied;␊ |
1256 | ␉int count = 0;␊ |
1257 | ␊ |
1258 | ␉verbose("\t- Searching for booter extensions pattern:\n");␊ |
1259 | ␊ |
1260 | ␉Bytes = (UInt8 *)kernelData;␊ |
1261 | ␉PatchApplied = false;␊ |
1262 | ␊ |
1263 | ␉if (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 };␊ |
1267 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1268 | ␉␉{␊ |
1269 | ␉␉␉if (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 | ␉␉␉{␊ |
1280 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1281 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1282 | ␉␉␉␉count ++;␊ |
1283 | ␊ |
1284 | ␉␉␉␉verbose("\tFound Lion pattern: patched!\n");␊ |
1285 | ␊ |
1286 | ␉␉␉␉if (PatchApplied)␊ |
1287 | ␉␉␉␉{␊ |
1288 | ␉␉␉␉␉break;␊ |
1289 | ␉␉␉␉}␊ |
1290 | ␊ |
1291 | ␉␉␉␉PatchApplied = 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 | ␉ */␊ |
1302 | ␉if (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 };␊ |
1306 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1307 | ␉␉{␊ |
1308 | ␉␉␉if (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 | ␉␉␉{␊ |
1319 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1320 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1321 | ␉␉␉␉count ++;␊ |
1322 | ␊ |
1323 | ␉␉␉␉verbose("\tFound Snow Leopard pattern: patched!\n");␊ |
1324 | ␊ |
1325 | ␉␉␉␉if (PatchApplied)␊ |
1326 | ␉␉␉␉{␊ |
1327 | ␉␉␉␉␉break;␊ |
1328 | ␉␉␉␉}␊ |
1329 | ␊ |
1330 | ␉␉␉␉PatchApplied = true;␊ |
1331 | ␉␉␉}␊ |
1332 | ␉␉}␊ |
1333 | ␉}␊ |
1334 | ␊ |
1335 | ␉if (!PatchApplied)␊ |
1336 | ␉{␊ |
1337 | ␉␉verbose("\tCan't find Booter Extensions patch location.\n");␊ |
1338 | ␉}␊ |
1339 | ␉else␊ |
1340 | ␉{␊ |
1341 | ␉␉verbose("\t%d substitution(s) made.\n", count);␊ |
1342 | ␉}␊ |
1343 | }␊ |
1344 | ␊ |
1345 | void patch_BooterExtensions_64(void *kernelData)␊ |
1346 | {␊ |
1347 | ␉// KernelBooterExtensionsPatch to load extra kexts besides kernelcache␊ |
1348 | ␉UInt8 *Bytes;␊ |
1349 | ␉UInt32 Index;␊ |
1350 | ␉bool PatchApplied; // does nothing␊ |
1351 | ␉int count = 0;␊ |
1352 | ␊ |
1353 | ␉verbose("\t- Searching for booter extensions pattern:\n");␊ |
1354 | ␊ |
1355 | ␉Bytes = (UInt8 *)kernelData;␊ |
1356 | ␉PatchApplied = 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"))␊ |
1360 | ␉if (kernelOSVer >= MacOSVer2Int("10.12"))␊ |
1361 | ␉{␊ |
1362 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1363 | ␉␉{␊ |
1364 | ␉␉␉// High Sierra␊ |
1365 | ␉␉␉if (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 | ␉␉␉{␊ |
1382 | ␉␉␉␉Bytes[Index + 4] = 0xEB;␊ |
1383 | ␉␉␉␉Bytes[Index + 5] = 0x12;␊ |
1384 | ␉␉␉␉count++;␊ |
1385 | ␊ |
1386 | ␉␉␉␉verbose("\tFound High Sierra SIP pattern: patched!\n");␊ |
1387 | ␊ |
1388 | ␉␉␉␉if (PatchApplied)␊ |
1389 | ␉␉␉␉{␊ |
1390 | ␉␉␉␉␉break;␊ |
1391 | ␉␉␉␉}␊ |
1392 | ␊ |
1393 | ␉␉␉␉PatchApplied = true;␊ |
1394 | ␉␉␉}␊ |
1395 | ␉␉}␊ |
1396 | ␉}␊ |
1397 | ␊ |
1398 | ␉// Sierra␊ |
1399 | ␉if (kernelOSVer >= MacOSVer2Int("10.12") && kernelOSVer < MacOSVer2Int("10.13"))␊ |
1400 | ␉{␊ |
1401 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1402 | ␉␉{␊ |
1403 | ␉␉␉// High Sierra␊ |
1404 | ␉␉␉if (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 | ␉␉␉{␊ |
1421 | ␉␉␉␉Bytes[Index + 4] = 0xEB;␊ |
1422 | ␉␉␉␉Bytes[Index + 5] = 0x12;␊ |
1423 | ␉␉␉␉count++;␊ |
1424 | ␊ |
1425 | ␉␉␉␉verbose("\tFound Sierra SIP pattern: patched!\n");␊ |
1426 | ␊ |
1427 | ␉␉␉␉if (PatchApplied)␊ |
1428 | ␉␉␉␉{␊ |
1429 | ␉␉␉␉␉break;␊ |
1430 | ␉␉␉␉}␊ |
1431 | ␊ |
1432 | ␉␉␉␉PatchApplied = true;␊ |
1433 | ␉␉␉}␊ |
1434 | ␉␉}␊ |
1435 | ␉}␊ |
1436 | ␊ |
1437 | ␉// Yosemite/El Capitan␊ |
1438 | ␉if (kernelOSVer >= MacOSVer2Int("10.10") && kernelOSVer < MacOSVer2Int("10.12"))␊ |
1439 | ␉{␊ |
1440 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1441 | ␉␉{␊ |
1442 | ␉␉␉// El Capitan␊ |
1443 | ␉␉␉if (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 | ␉␉␉{␊ |
1460 | ␉␉␉␉Bytes[Index + 4] = 0xEB;␊ |
1461 | ␉␉␉␉Bytes[Index + 5] = 0x12;␊ |
1462 | ␉␉␉␉count++;␊ |
1463 | ␊ |
1464 | ␉␉␉␉if (kernelOSVer >= MacOSVer2Int("10.11"))␊ |
1465 | ␉␉␉␉{␊ |
1466 | ␉␉␉␉␉verbose("\tFound El Capitan SIP pattern: patched!\n");␊ |
1467 | ␉␉␉␉}␊ |
1468 | ␉␉␉␉else␊ |
1469 | ␉␉␉␉{␊ |
1470 | ␉␉␉␉␉verbose("\tFound Yosemite SIP pattern: patched!\n");␊ |
1471 | ␉␉␉␉}␊ |
1472 | ␊ |
1473 | ␉␉␉␉if (PatchApplied)␊ |
1474 | ␉␉␉␉{␊ |
1475 | ␉␉␉␉␉break;␊ |
1476 | ␉␉␉␉}␊ |
1477 | ␊ |
1478 | ␉␉␉␉PatchApplied = 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"))␊ |
1486 | ␉if (kernelOSVer >= MacOSVer2Int("10.10"))␊ |
1487 | ␉{␊ |
1488 | ␊ |
1489 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1490 | ␉␉{␊ |
1491 | ␉␉␉if (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 | ␉␉␉{␊ |
1500 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1501 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1502 | ␉␉␉␉count++;␊ |
1503 | ␉␉␉␉␊ |
1504 | ␉␉␉␉if (kernelOSVer >= MacOSVer2Int("10.13") && kernelOSVer < MacOSVer2Int("10.14"))␊ |
1505 | ␉␉␉␉{␊ |
1506 | ␉␉␉␉␉verbose("\tFound High Sierra EXT pattern: patched!\n");␊ |
1507 | ␉␉␉␉}␊ |
1508 | ␉␉␉␉else if (kernelOSVer >= MacOSVer2Int("10.12") && kernelOSVer < MacOSVer2Int("10.13"))␊ |
1509 | ␉␉␉␉{␊ |
1510 | ␉␉␉␉␉verbose("\tFound Sierra EXT pattern: patched!\n");␊ |
1511 | ␉␉␉␉}␊ |
1512 | ␉␉␉␉else if (kernelOSVer >= MacOSVer2Int("10.11") && kernelOSVer < MacOSVer2Int("10.12"))␊ |
1513 | ␉␉␉␉{␊ |
1514 | ␉␉␉␉␉verbose("\tFound EL Capitan EXT pattern: patched!\n");␊ |
1515 | ␉␉␉␉}␊ |
1516 | ␉␉␉␉else␊ |
1517 | ␉␉␉␉{␊ |
1518 | ␉␉␉␉␉verbose("\tFound Yosemite EXT pattern: patched!\n");␊ |
1519 | ␉␉␉␉}␊ |
1520 | ␊ |
1521 | ␉␉␉␉if (PatchApplied)␊ |
1522 | ␉␉␉␉{␊ |
1523 | ␉␉␉␉␉break;␊ |
1524 | ␉␉␉␉}␊ |
1525 | ␊ |
1526 | ␉␉␉␉PatchApplied = true;␊ |
1527 | ␉␉␉}␊ |
1528 | ␉␉}␊ |
1529 | ␉}␊ |
1530 | ␊ |
1531 | ␉// Mountain Lion/Mavericks␊ |
1532 | ␉if (kernelOSVer >= MacOSVer2Int("10.8") && kernelOSVer < MacOSVer2Int("10.10"))␊ |
1533 | ␉{␊ |
1534 | ␊ |
1535 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1536 | ␉␉{␊ |
1537 | ␉␉␉if (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 | ␉␉␉{␊ |
1549 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1550 | ␉␉␉␉Bytes[Index + 7] = 0x90;␊ |
1551 | ␉␉␉␉count++;␊ |
1552 | ␊ |
1553 | ␉␉␉␉verbose("\tFound M%s EXT pattern: patched!\n", checkOSVersion("10.8") ? "ountain Lion" : "avericks");␊ |
1554 | ␊ |
1555 | ␉␉␉␉if (PatchApplied)␊ |
1556 | ␉␉␉␉{␊ |
1557 | ␉␉␉␉␉break;␊ |
1558 | ␉␉␉␉}␊ |
1559 | ␊ |
1560 | ␉␉␉␉PatchApplied = true;␊ |
1561 | ␉␉␉}␊ |
1562 | ␉␉}␊ |
1563 | ␉}␊ |
1564 | ␊ |
1565 | ␉// Lion 64␊ |
1566 | ␉if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))␊ |
1567 | ␉{␊ |
1568 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1569 | ␉␉{␊ |
1570 | ␉␉␉if (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 | ␉␉␉{␊ |
1581 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1582 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1583 | ␉␉␉␉count++;␊ |
1584 | ␊ |
1585 | ␉␉␉␉verbose("\tFound Lion EXT pattern: patched!\n");␊ |
1586 | ␊ |
1587 | ␉␉␉␉if (PatchApplied)␊ |
1588 | ␉␉␉␉{␊ |
1589 | ␉␉␉␉␉break;␊ |
1590 | ␉␉␉␉}␊ |
1591 | ␊ |
1592 | ␉␉␉␉PatchApplied = true;␊ |
1593 | ␉␉␉}␊ |
1594 | ␉␉}␊ |
1595 | ␉}␊ |
1596 | ␊ |
1597 | ␉// Snow Leopard 64␊ |
1598 | ␉if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))␊ |
1599 | ␉{␊ |
1600 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1601 | ␉␉{␊ |
1602 | ␉␉␉if (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 | ␉␉␉{␊ |
1613 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1614 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1615 | ␉␉␉␉verbose("\tFound Snow Leopard EXT pattern: patched!\n");␊ |
1616 | ␉␉␉␉count++;␊ |
1617 | ␊ |
1618 | ␉␉␉␉if (PatchApplied)␊ |
1619 | ␉␉␉␉{␊ |
1620 | ␉␉␉␉␉break;␊ |
1621 | ␉␉␉␉}␊ |
1622 | ␊ |
1623 | ␉␉␉␉PatchApplied = true;␊ |
1624 | ␉␉␉}␊ |
1625 | ␉␉}␊ |
1626 | ␉}␊ |
1627 | ␊ |
1628 | ␉if (!PatchApplied)␊ |
1629 | ␉{␊ |
1630 | ␉␉verbose("\tCan't find Booter Extensions patch location.\n");␊ |
1631 | ␉}␊ |
1632 | ␉else␊ |
1633 | ␉{␊ |
1634 | ␉␉verbose("\t%d substitution(s) made.\n", count);␊ |
1635 | ␉}␊ |
1636 | }␊ |
1637 | ␊ |
1638 | // ===================================␊ |
1639 | // Patch ssse3␊ |
1640 | void patch_SSE3_6(void *kernelData)␊ |
1641 | {␊ |
1642 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1643 | ␉UInt32 patchLocation1 = 0;␊ |
1644 | ␉UInt32 patchLocation2 = 0;␊ |
1645 | ␉UInt32 patchlast = 0;␊ |
1646 | ␉UInt32 i;␊ |
1647 | ␉//UInt32 Length = sizeof(kernelData);␊ |
1648 | ␊ |
1649 | ␉verbose("\t- Start find SSE3 address\n");␊ |
1650 | ␉i = 0;␊ |
1651 | ␉//for (i = 0; i < Length; i++)␊ |
1652 | ␉while(true)␊ |
1653 | ␉{␊ |
1654 | ␉␉if (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 | ␉␉{␊ |
1662 | ␉␉␉patchLocation1 = i-1664-32;␊ |
1663 | ␉␉␉verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
1664 | ␉␉}␊ |
1665 | ␊ |
1666 | ␉␉// hasSSE2+..... title␊ |
1667 | ␉␉if (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 | ␉␉{␊ |
1678 | ␉␉␉patchLocation2 = i;␊ |
1679 | ␉␉␉verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);␊ |
1680 | ␉␉␉break;␊ |
1681 | ␉␉}␊ |
1682 | ␉␉i++;␊ |
1683 | ␉}␊ |
1684 | ␊ |
1685 | ␉if (!patchLocation1 || !patchLocation2)␊ |
1686 | ␉{␊ |
1687 | ␉␉verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);␊ |
1688 | ␉␉return;␊ |
1689 | ␉}␊ |
1690 | ␊ |
1691 | ␉verbose("\tFound SSE3 last data addres Start\n");␊ |
1692 | ␉i = patchLocation1 + 1500;␊ |
1693 | ␉//for (i=(patchLocation1+1500); i<(patchLocation1+3000); i++)␊ |
1694 | ␉while(true)␊ |
1695 | ␉{␊ |
1696 | ␉␉if (bytes[i] == 0x90␊ |
1697 | ␉␉␉&& bytes[i + 1] == 0x90␊ |
1698 | ␉␉␉&& bytes[i + 2] == 0x55 )␊ |
1699 | ␉␉{␊ |
1700 | ␉␉␉patchlast = (i+1) - patchLocation1;␊ |
1701 | ␉␉␉verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1702 | ␉␉␉break;␊ |
1703 | ␉␉}␊ |
1704 | ␉␉i++;␊ |
1705 | ␉}␊ |
1706 | ␊ |
1707 | ␉if (!patchlast)␊ |
1708 | ␉{␊ |
1709 | ␉␉verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1710 | ␉␉return;␊ |
1711 | ␉}␊ |
1712 | ␉// patch sse3_64 data␊ |
1713 | ␊ |
1714 | ␉for (i = 0; i < patchlast; i++)␊ |
1715 | ␉{␊ |
1716 | ␉␉if (i < sizeof(sse3_patcher))␊ |
1717 | ␉␉{␊ |
1718 | ␉␉␉bytes[patchLocation1 + i] = sse3_patcher[i];␊ |
1719 | ␉␉}␊ |
1720 | ␉␉else␊ |
1721 | ␉␉{␊ |
1722 | ␉␉␉bytes[patchLocation1 + i] = 0x90;␊ |
1723 | ␉␉}␊ |
1724 | ␉}␊ |
1725 | ␊ |
1726 | ␉// patch kHasSSE3 title␊ |
1727 | ␉bytes[patchLocation2 + 0] = 0xFC;␊ |
1728 | ␉bytes[patchLocation2 + 1] = 0x05;␊ |
1729 | ␉bytes[patchLocation2 + 8] = 0x2C;␊ |
1730 | ␉bytes[patchLocation2 + 9] = 0x00;␊ |
1731 | ␊ |
1732 | }␊ |
1733 | ␊ |
1734 | // ===================================␊ |
1735 | //␊ |
1736 | void patch_SSE3_5(void *kernelData)␊ |
1737 | {␊ |
1738 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1739 | ␉UInt32 patchLocation1 = 0;␊ |
1740 | ␉UInt32 patchLocation2 = 0;␊ |
1741 | ␉UInt32 patchlast=0;␊ |
1742 | ␉UInt32 Length = sizeof(kernelData);␊ |
1743 | ␉UInt32 i;␊ |
1744 | ␊ |
1745 | ␉verbose("\t- Start find SSE3 address\n");␊ |
1746 | ␊ |
1747 | ␉for (i = 256; i < (Length-256); i++)␊ |
1748 | ␉{␊ |
1749 | ␉␉if (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 | ␉␉{␊ |
1757 | ␉␉␉patchLocation1 = i-1680-32;␊ |
1758 | ␉␉␉verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
1759 | ␉␉}␊ |
1760 | ␊ |
1761 | ␉␉// khasSSE2+..... title␊ |
1762 | ␉␉if (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 | ␉␉{␊ |
1773 | ␉␉␉patchLocation2 = i;␊ |
1774 | ␉␉␉verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);␊ |
1775 | ␉␉␉break;␊ |
1776 | ␉␉}␊ |
1777 | ␉}␊ |
1778 | ␊ |
1779 | ␉if (!patchLocation1 || !patchLocation2)␊ |
1780 | ␉{␊ |
1781 | ␉␉verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);␊ |
1782 | ␉␉return;␊ |
1783 | ␉}␊ |
1784 | ␊ |
1785 | ␉verbose("\tFound SSE3 last data addres Start\n");␊ |
1786 | ␊ |
1787 | ␉for (i = (patchLocation1+1500);i < Length;i++)␊ |
1788 | ␉{␊ |
1789 | ␉␉if (bytes[i] == 0x90␊ |
1790 | ␉␉␉&& bytes[i + 1] == 0x90␊ |
1791 | ␉␉␉&& bytes[i + 2] == 0x55)␊ |
1792 | ␉␉{␊ |
1793 | ␉␉␉patchlast = (i+1) - patchLocation1;␊ |
1794 | ␉␉␉verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1795 | ␉␉␉break;␊ |
1796 | ␉␉}␊ |
1797 | ␉}␊ |
1798 | ␊ |
1799 | ␉if (!patchlast)␊ |
1800 | ␉{␊ |
1801 | ␉␉verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1802 | ␉␉return;␊ |
1803 | ␉}␊ |
1804 | ␊ |
1805 | ␉// patech sse3_64 data␊ |
1806 | ␊ |
1807 | ␉for (i = 0; i < patchlast; i++)␊ |
1808 | ␉{␊ |
1809 | ␉␉if (i < sizeof(sse3_5_patcher))␊ |
1810 | ␉␉{␊ |
1811 | ␉␉␉bytes[patchLocation1 + i] = sse3_5_patcher[i];␊ |
1812 | ␉␉}␊ |
1813 | ␉␉else␊ |
1814 | ␉␉{␊ |
1815 | ␉␉␉bytes[patchLocation1 + i] = 0x90;␊ |
1816 | ␉␉}␊ |
1817 | ␉}␊ |
1818 | ␊ |
1819 | ␉// patch kHasSSE3 title␊ |
1820 | ␉bytes[patchLocation2 + 0] = 0x0C;␊ |
1821 | ␉bytes[patchLocation2 + 1] = 0x06;␊ |
1822 | ␉bytes[patchLocation2 + 8] = 0x2C;␊ |
1823 | ␉bytes[patchLocation2 + 9] = 0x00;␊ |
1824 | ␊ |
1825 | }␊ |
1826 | ␊ |
1827 | // ===================================␊ |
1828 | //␊ |
1829 | void patch_SSE3_7(void *kernelData)␊ |
1830 | {␊ |
1831 | ␉// not support yet␊ |
1832 | ␉return;␊ |
1833 | }␊ |
1834 | ␊ |
1835 | // ===================================␊ |
1836 | // root:xnu text replacement Patch␊ |
1837 | bool patch_string_XNU_init(void *kernelData) //␊ |
1838 | {␊ |
1839 | ␊ |
1840 | ␉UInt8␉*Bytes;␊ |
1841 | ␉UInt32␉Index;␊ |
1842 | ␉bool␉PatchApplied;␊ |
1843 | ␊ |
1844 | ␉DBG("\t- Searching for \"root:xnu-\" string pattern\n");␊ |
1845 | ␊ |
1846 | ␉Bytes = (UInt8 *)kernelData;␊ |
1847 | ␉PatchApplied = false;␊ |
1848 | ␊ |
1849 | ␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1850 | ␉{␊ |
1851 | ␉␉// search for root:xnu- and replace it with ***Enoch-␊ |
1852 | ␉␉if (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 | ␉␉{␊ |
1863 | ␉␉␉Bytes[Index + 1] = '*';␊ |
1864 | ␉␉␉Bytes[Index + 2] = '*';␊ |
1865 | ␉␉␉Bytes[Index + 3] = '*';␊ |
1866 | ␉␉␉Bytes[Index + 4] = 'E';␊ |
1867 | ␉␉␉Bytes[Index + 5] = 'n';␊ |
1868 | ␉␉␉Bytes[Index + 6] = 'o';␊ |
1869 | ␉␉␉Bytes[Index + 7] = 'c';␊ |
1870 | ␉␉␉Bytes[Index + 8] = 'h';␊ |
1871 | ␊ |
1872 | ␉␉␉DBG("\tFound \"root:xnu-\" pattern; patched.\n");␊ |
1873 | ␊ |
1874 | ␉␉␉if (PatchApplied)␊ |
1875 | ␉␉␉{␊ |
1876 | ␉␉␉␉break;␊ |
1877 | ␉␉␉}␊ |
1878 | ␊ |
1879 | ␉␉␉PatchApplied = true;␊ |
1880 | ␉␉}␊ |
1881 | ␉}␊ |
1882 | ␊ |
1883 | ␉if (!PatchApplied)␊ |
1884 | ␉{␊ |
1885 | ␉␉DBG("\tCan't find \"root:xnu-\" string pattern: patch not applied.\n");␊ |
1886 | ␉}␊ |
1887 | ␊ |
1888 | ␉return PatchApplied;␊ |
1889 | }␊ |
1890 | ␊ |
1891 | // ===================================␊ |
1892 | // (Clover)␊ |
1893 | // Patching AppleRTC to prevent CMOS reset␊ |
1894 | unsigned 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␊ |
1957 | unsigned 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␊ |
2027 | unsigned 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)␊ |
2045 | unsigned 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␊ |
2063 | unsigned 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␊ |
2102 | void 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␊ |
2256 | ␉␉␉␉patchBooterDefinedKext(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 | ␊ |
2288 | void patchBooterDefinedKext(const char *kext, void *driverAddr, UInt32 DriverSize, UInt32 StartLocation)␊ |
2289 | {␊ |
2290 | ␉if ((!strcmp(kext, "AppleRTC")) && AppleRTCPatch)␊ |
2291 | ␉{␊ |
2292 | ␉␉verbose("\tPatching %s:", kext);␊ |
2293 | ␊ |
2294 | ␉␉unsigned int numPatches = AppleRTC_Patch(driverAddr, DriverSize, StartLocation);␊ |
2295 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2296 | ␉}␊ |
2297 | ␊ |
2298 | ␉if ((!strcmp(kext, "AppleIntelCPUPowerManagement")) && AICPMPatch)␊ |
2299 | ␉{␊ |
2300 | ␉␉verbose("\tPatching %s (locked msr):\n", kext);␊ |
2301 | ␊ |
2302 | ␉␉unsigned int numPatches = AsusAICPUPMPatch(driverAddr, DriverSize, StartLocation);␊ |
2303 | ␉␉verbose("\t %d substitutions made!\n", numPatches);␊ |
2304 | ␉}␊ |
2305 | ␊ |
2306 | ␉if ((!strcmp(kext, "NVDAStartupWeb")) && NVIDIAWebDrv)␊ |
2307 | ␉{␊ |
2308 | ␉␉verbose("\tPatching %s (force load w/o nvram):\n", kext);␊ |
2309 | ␊ |
2310 | ␉␉unsigned int numPatches = patch_NVDAStartupWeb(driverAddr, DriverSize, StartLocation);␊ |
2311 | ␉␉verbose("\t %d substitutions made!\n", numPatches);␊ |
2312 | ␉}␊ |
2313 | ␊ |
2314 | ␉if ((!strcmp(kext, "IOAHCIBlockStorage")) && TrimEnablerSata)␊ |
2315 | ␉{␊ |
2316 | ␉␉verbose("\tPatching %s (trim enabler SATA):", kext);␊ |
2317 | ␊ |
2318 | ␉␉unsigned int numPatches = trimEnablerSata(driverAddr, DriverSize, StartLocation);␊ |
2319 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2320 | ␉}␊ |
2321 | ␊ |
2322 | ␉if ((!strcmp(kext, "AppleAHCIPort")) && OrangeIconFixSata)␊ |
2323 | ␉{␊ |
2324 | ␉␉verbose("\tPatching %s (orange icon fix):", kext);␊ |
2325 | ␊ |
2326 | ␉␉unsigned int numPatches = patch_AppleAHCIPort_OrangeFix(driverAddr, DriverSize, StartLocation);␊ |
2327 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2328 | ␉}␊ |
2329 | }␊ |
2330 | ␊ |
2331 | // ===================================␊ |
2332 | // Boolean function to check the full OSX match version␊ |
2333 | bool checkFullOSVer(const char *version)␊ |
2334 | {␊ |
2335 | ␉// We are in a version with 7 char ?␊ |
2336 | ␉if ( (sizeof(version) == 7) && ('.' == version[5]) && ('\0' != version[6]) ) // 10.xx.x␊ |
2337 | ␉{␊ |
2338 | ␉␉return ( (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 ?␊ |
2349 | ␉if ( (sizeof(version) == 7) && ('.' == version[4]) && ('\0' != version[6]) ) // 10.4.11␊ |
2350 | ␉{␊ |
2351 | ␉␉return ( (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 ?␊ |
2362 | ␉if ( (sizeof(version) == 6) && ('.' == version[4]) && ('\0' != version[5]) ) // 10.x.x␊ |
2363 | ␉{␊ |
2364 | ␉␉return ( (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 ?␊ |
2374 | ␉if ( (sizeof(version) == 5) && ('.' != version[4]) && ('\0' != version[4]) ) // 10.xx␊ |
2375 | ␉{␊ |
2376 | ␉␉return ( (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 ?␊ |
2385 | ␉if ( (sizeof(version) == 4) && ('\0' != version[3]) ) // 10.x␊ |
2386 | ␉{␊ |
2387 | ␉␉return ( (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␊ |
2395 | ␉return false;␊ |
2396 | }␊ |
2397 | |