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 | ␉␉Ptr += 16;␊ |
650 | ␉}␊ |
651 | ␉verbose("\tKernel power management patch region not found!\n");␊ |
652 | ␉return false;␊ |
653 | }␊ |
654 | ␊ |
655 | // ===================================␊ |
656 | // Bronya: Lapic Panic Version 64␊ |
657 | bool patch_lapic_version_init_64(void *kernelData) // KernelLapicVersionPatch_64␊ |
658 | {␊ |
659 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
660 | ␉UInt32 patchLocation = 0;␊ |
661 | ␉UInt32 i;␊ |
662 | ␊ |
663 | ␉verbose("\t- Looking for Lapic Version panic call Start\n");␊ |
664 | ␊ |
665 | ␉for (i = 0; i < 0x1000000; i++)␊ |
666 | ␉{␊ |
667 | ␉␉// Bronya: Snow Leopard 10.6 Lapic Version␊ |
668 | ␉␉if (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 | ␉␉{␊ |
675 | ␉␉␉patchLocation = i + 59;␊ |
676 | ␉␉␉verbose("\tFound Snow Leopard Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
677 | ␉␉␉break;␊ |
678 | ␉␉}␊ |
679 | ␉␉// Bronya: Lion 10.7 Lapic Version␊ |
680 | ␉␉else 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 | ␉␉{␊ |
688 | ␉␉␉patchLocation = i + 63;␊ |
689 | ␉␉␉verbose("\tFound Lion, Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
690 | ␉␉␉break;␊ |
691 | ␉␉}␊ |
692 | ␉␉// Bronya: Mountain Lion 10.8 Lapic Version␊ |
693 | ␉␉else 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 | ␉␉{␊ |
706 | ␉␉␉patchLocation = i + 68;␊ |
707 | ␉␉␉verbose("\tFound Mountain Lion, Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
708 | ␉␉␉break;␊ |
709 | ␉␉}␊ |
710 | ␉␉// Bronya: Mavericks 10.9 Lapic Version␊ |
711 | ␉␉else 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 | ␉␉{␊ |
722 | ␉␉␉patchLocation = i + 90;␊ |
723 | ␉␉␉verbose("\tFound Mavericks Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
724 | ␉␉␉break;␊ |
725 | ␉␉}␊ |
726 | ␉␉// Bronya: Yosemite 10.10 lapic version␊ |
727 | ␉␉else 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 | ␉␉{␊ |
735 | ␉␉␉patchLocation = i + 42;␊ |
736 | ␉␉␉verbose("\tFound Yosemite Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
737 | ␉␉␉break;␊ |
738 | ␉␉}␊ |
739 | ␉␉// Bronya: El Capitan 10.11 Lapic Version␊ |
740 | ␉␉else 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 | ␉␉{␊ |
746 | ␉␉␉patchLocation = i + 40;␊ |
747 | ␉␉␉verbose("\tFound El Capitan Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
748 | ␉␉␉break;␊ |
749 | ␉␉}␊ |
750 | ␉}␊ |
751 | ␊ |
752 | ␉if (!patchLocation)␊ |
753 | ␉{␊ |
754 | ␉␉verbose("\tCan't find Lapic Version panic, kernel patch aborted.\n");␊ |
755 | ␉␉return false;␊ |
756 | ␉}␊ |
757 | ␊ |
758 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
759 | ␊ |
760 | ␉if (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 | ␉{␊ |
766 | ␉␉verbose("\tLapic Version panic already patched, kernel file manually patched?\n");␊ |
767 | ␉␉return false;␊ |
768 | ␉}␊ |
769 | ␉else␊ |
770 | ␉{␊ |
771 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
772 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
773 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
774 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
775 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
776 | ␉}␊ |
777 | ␉return true;␊ |
778 | }␊ |
779 | ␊ |
780 | // ===================================␊ |
781 | // Lapic Error Panic 64␊ |
782 | bool 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 | ␊ |
786 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
787 | ␉UInt32 patchLocation = 0;␊ |
788 | ␉UInt32 i;␊ |
789 | ␊ |
790 | ␉verbose("\t- Looking for Lapic panic call Start\n");␊ |
791 | ␊ |
792 | ␉for (i = 0; i < 0x1000000; i++)␊ |
793 | ␉{␊ |
794 | ␉␉if (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 | ␉␉{␊ |
812 | ␉␉␉patchLocation = i + 40;␊ |
813 | ␉␉␉verbose("\tFound Snow Leopard Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
814 | ␉␉␉break;␊ |
815 | ␉␉}␊ |
816 | ␉␉else 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 | ␉␉{␊ |
834 | ␉␉␉patchLocation = i + 30;␊ |
835 | ␉␉␉verbose("\tFound %sLion Lapic panic at 0x%08X\n", checkOSVersion("10.7") ? "" : "Mountain ", (unsigned int)patchLocation);␊ |
836 | ␉␉␉break;␊ |
837 | ␉␉}␊ |
838 | ␉␉else 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 | ␉␉{␊ |
856 | ␉␉␉patchLocation = i + 31;␊ |
857 | ␉␉␉verbose("\tFound Mavericks Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
858 | ␉␉␉break;␊ |
859 | ␉␉}␊ |
860 | // RehabMan: 10.10.DP1 lapic␊ |
861 | ␉␉else 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 | ␉␉{␊ |
879 | ␉␉␉patchLocation = i + 28;␊ |
880 | ␉␉␉verbose("\tFound Yosemite Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
881 | ␉␉␉break;␊ |
882 | ␉␉}␊ |
883 | ␉␉// sherlocks: 10.11.DB1␊ |
884 | ␉␉else 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 | ␉␉{␊ |
902 | ␉␉␉patchLocation = i + 1400;␊ |
903 | ␉␉␉verbose("\tFound El Capitan Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
904 | ␉␉␉break;␊ |
905 | ␉␉}␊ |
906 | ␉␉// sherlocks: 10.12.DP1␊ |
907 | ␉␉else 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 | ␉␉{␊ |
925 | ␉␉␉patchLocation = i+1398;␊ |
926 | ␉␉␉DBG("\tFound Sierra Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
927 | ␉␉␉break;␊ |
928 | ␉␉}␊ |
929 | ␉}␊ |
930 | ␊ |
931 | ␉if (!patchLocation)␊ |
932 | ␉{␊ |
933 | ␉␉verbose("\tCan't find Lapic panic, kernel patch aborted.\n");␊ |
934 | ␉␉return false;␊ |
935 | ␉}␊ |
936 | ␊ |
937 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
938 | ␊ |
939 | ␉if (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 | ␉{␊ |
945 | ␉␉verbose("\tLapic panic already patched, kernel file manually patched?\n");␊ |
946 | ␉␉return false;␊ |
947 | ␉}␊ |
948 | ␉else␊ |
949 | ␉{␊ |
950 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
951 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
952 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
953 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
954 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
955 | ␉}␊ |
956 | ␉return true;␊ |
957 | }␊ |
958 | ␊ |
959 | // ===================================␊ |
960 | // Bronya: Lapic Panic Version 32 bit␊ |
961 | bool patch_lapic_version_init_32(void *kernelData)␊ |
962 | {␊ |
963 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
964 | ␉UInt32 patchLocation = 0;␊ |
965 | ␉UInt32 i;␊ |
966 | ␊ |
967 | ␉verbose("\t- Looking for Lapic Version panic call Start\n");␊ |
968 | ␊ |
969 | ␉for (i = 0; i < 0x1000000; i++)␊ |
970 | ␉{␊ |
971 | ␉␉// Bronya: Snow Leopard 10.6 Lapic Version␊ |
972 | ␉␉if (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 | ␉␉{␊ |
980 | ␉␉␉patchLocation = i+60;␊ |
981 | ␉␉␉verbose("\tFound Snow Leopard Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
982 | ␉␉␉break;␊ |
983 | ␉␉}␊ |
984 | ␉␉else␊ |
985 | ␉␉{␊ |
986 | ␉␉␉// Bronya: Lion 10.7 Lapic Version␊ |
987 | ␉␉␉if (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 | ␉␉␉{␊ |
995 | ␉␉␉␉patchLocation = i+63;␊ |
996 | ␉␉␉␉verbose("\tFound Lion, Lion Lapic Version panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
997 | ␉␉␉␉break;␊ |
998 | ␉␉␉}␊ |
999 | ␉␉}␊ |
1000 | ␉}␊ |
1001 | ␊ |
1002 | ␉if (!patchLocation)␊ |
1003 | ␉{␊ |
1004 | ␉␉verbose("\tCan't find Lapic Version panic, kernel patch aborted.\n");␊ |
1005 | ␉␉return false;␊ |
1006 | ␉}␊ |
1007 | ␊ |
1008 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
1009 | ␊ |
1010 | ␉if (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 | ␉{␊ |
1016 | ␉␉verbose("\tLapic Version panic already patched, kernel file manually patched?\n");␊ |
1017 | ␉␉return false;␊ |
1018 | ␉}␊ |
1019 | ␉else␊ |
1020 | ␉{␊ |
1021 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
1022 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
1023 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
1024 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
1025 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
1026 | ␉}␊ |
1027 | ␉return true;␊ |
1028 | }␊ |
1029 | ␊ |
1030 | // ===================================␊ |
1031 | // Lapic Error Panic 32␊ |
1032 | bool 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 | ␊ |
1036 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1037 | ␉UInt32 patchLocation=0;␊ |
1038 | ␉UInt32 i;␊ |
1039 | ␊ |
1040 | ␉verbose("\t- Looking for Lapic panic call Start\n");␊ |
1041 | ␊ |
1042 | ␉for (i = 0; i < 0x1000000; i++)␊ |
1043 | ␉{␊ |
1044 | ␉␉if (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 | ␉␉{␊ |
1057 | ␉␉␉patchLocation = i + 25;␊ |
1058 | ␉␉␉verbose("\tFound Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
1059 | ␉␉␉break;␊ |
1060 | ␉␉}␊ |
1061 | ␉}␊ |
1062 | ␊ |
1063 | ␉if (!patchLocation)␊ |
1064 | ␉{␊ |
1065 | ␉␉verbose("\tCan't find Lapic panic, kernel patch aborted.\n");␊ |
1066 | ␉␉return false;␊ |
1067 | ␉}␊ |
1068 | ␊ |
1069 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
1070 | ␊ |
1071 | ␉if (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 | ␉{␊ |
1077 | ␉␉verbose("\tLapic panic already patched, kernel file manually patched?\n");␊ |
1078 | ␉␉return false;␊ |
1079 | ␉}␊ |
1080 | ␉else␊ |
1081 | ␉{␊ |
1082 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
1083 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
1084 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
1085 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
1086 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
1087 | ␉}␊ |
1088 | ␉return true;␊ |
1089 | }␊ |
1090 | ␊ |
1091 | // ===================================␊ |
1092 | // Haswell-E Patch␊ |
1093 | bool 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 | ␊ |
1098 | ␉UInt8␉*Bytes;␊ |
1099 | ␉UInt32␉Index;␊ |
1100 | ␉bool␉PatchApplied;␊ |
1101 | ␊ |
1102 | ␉verbose("\t- Searching for Haswell-E patch pattern\n");␊ |
1103 | ␊ |
1104 | ␉Bytes = (UInt8 *)kernelData;␊ |
1105 | ␉PatchApplied = false;␊ |
1106 | ␊ |
1107 | ␉for (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␊ |
1110 | ␉␉if (Bytes[Index] == 0x74␊ |
1111 | ␉␉␉&& Bytes[Index + 1] == 0x11␊ |
1112 | ␉␉␉&& Bytes[Index + 2] == 0x83␊ |
1113 | ␉␉␉&& Bytes[Index + 3] == 0xF8␊ |
1114 | ␉␉␉&& Bytes[Index + 4] == 0x3C)␊ |
1115 | ␉␉{␊ |
1116 | ␉␉␉Bytes[Index + 4] = 0x3F;␊ |
1117 | ␊ |
1118 | ␉␉␉verbose("\tFound Haswell-E pattern #1; patched.\n");␊ |
1119 | ␊ |
1120 | ␉␉␉if (PatchApplied)␊ |
1121 | ␉␉␉{␊ |
1122 | ␉␉␉␉break;␊ |
1123 | ␉␉␉}␊ |
1124 | ␊ |
1125 | ␉␉␉PatchApplied = true;␊ |
1126 | ␉␉}␊ |
1127 | ␊ |
1128 | ␉␉// sudo perl -pi -e 's|\xEB\x0A\x83\xF8\x3A|\xEB\x0A\x83\xF8\x3F|g' /System/Library/Kernels/kernel␊ |
1129 | ␉␉if (Bytes[Index] == 0xEB␊ |
1130 | ␉␉␉&& Bytes[Index + 1] == 0x0A␊ |
1131 | ␉␉␉&& Bytes[Index + 2] == 0x83␊ |
1132 | ␉␉␉&& Bytes[Index + 3] == 0xF8␊ |
1133 | ␉␉␉&& Bytes[Index + 4] == 0x3A)␊ |
1134 | ␉␉{␊ |
1135 | ␉␉␉Bytes[Index + 4] = 0x3F;␊ |
1136 | ␊ |
1137 | ␉␉␉verbose("\tFound Haswell-E pattern #2; patched.\n");␊ |
1138 | ␊ |
1139 | ␉␉␉if (PatchApplied)␊ |
1140 | ␉␉␉{␊ |
1141 | ␉␉␉␉break;␊ |
1142 | ␉␉␉}␊ |
1143 | ␊ |
1144 | ␉␉␉PatchApplied = true;␊ |
1145 | ␉␉}␊ |
1146 | ␉}␊ |
1147 | ␊ |
1148 | ␉if (!PatchApplied)␊ |
1149 | ␉{␊ |
1150 | ␉␉verbose("\tCan't find Haswell-E patch pattern, patch not applied.\n");␊ |
1151 | ␉}␊ |
1152 | ␊ |
1153 | ␉return PatchApplied;␊ |
1154 | }␊ |
1155 | ␊ |
1156 | // ===================================␊ |
1157 | // Haswell-ULT Patch␊ |
1158 | bool 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 | ␊ |
1163 | ␉UInt8␉*Bytes;␊ |
1164 | ␉UInt32␉Index;␊ |
1165 | ␉bool␉PatchApplied;␊ |
1166 | ␊ |
1167 | ␉verbose("\t- Searching for Haswell-ULT patch pattern\n");␊ |
1168 | ␊ |
1169 | ␉Bytes = (UInt8 *)kernelData;␊ |
1170 | ␉PatchApplied = false;␊ |
1171 | ␊ |
1172 | ␉for (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␊ |
1175 | ␉␉if (Bytes[Index] == 0xBB␊ |
1176 | ␉␉␉&& Bytes[Index + 1] == 0xDC␊ |
1177 | ␉␉␉&& Bytes[Index + 2] == 0x82␊ |
1178 | ␉␉␉&& Bytes[Index + 3] == 0xB2␊ |
1179 | ␉␉␉&& Bytes[Index + 4] == 0xdc)␊ |
1180 | ␉␉{␊ |
1181 | ␉␉␉Bytes[Index + 1] = 0x35;␊ |
1182 | ␉␉␉Bytes[Index + 2] = 0xE8;␊ |
1183 | ␉␉␉Bytes[Index + 3] = 0x65;␊ |
1184 | ␉␉␉Bytes[Index + 4] = 0x1F;␊ |
1185 | ␊ |
1186 | ␉␉␉verbose("\tFound Haswell-ULT pattern #1; patched.\n");␊ |
1187 | ␊ |
1188 | ␉␉␉if (PatchApplied)␊ |
1189 | ␉␉␉{␊ |
1190 | ␉␉␉␉break;␊ |
1191 | ␉␉␉}␊ |
1192 | ␊ |
1193 | ␉␉␉PatchApplied = true;␊ |
1194 | ␉␉}␊ |
1195 | ␉}␊ |
1196 | ␊ |
1197 | ␉if (!PatchApplied)␊ |
1198 | ␉{␊ |
1199 | ␉␉verbose("\tCan't find Haswell-ULT patch pattern, patch not applied.\n");␊ |
1200 | ␉}␊ |
1201 | ␊ |
1202 | ␉return PatchApplied;␊ |
1203 | }␊ |
1204 | ␊ |
1205 | // ===================================␊ |
1206 | // Custom Kext injection from Extra/Extensions folder␊ |
1207 | void patch_BooterExtensions_32(void *kernelData)␊ |
1208 | {␊ |
1209 | ␉// KernelBooterExtensionsPatch to load extra kexts besides kernelcache␊ |
1210 | ␉UInt8 *Bytes;␊ |
1211 | ␉UInt32 Index;␊ |
1212 | ␉bool PatchApplied;␊ |
1213 | ␉int count = 0;␊ |
1214 | ␊ |
1215 | ␉verbose("\t- Searching for booter extensions pattern:\n");␊ |
1216 | ␊ |
1217 | ␉Bytes = (UInt8 *)kernelData;␊ |
1218 | ␉PatchApplied = false;␊ |
1219 | ␊ |
1220 | ␉if (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 };␊ |
1224 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1225 | ␉␉{␊ |
1226 | ␉␉␉if (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 | ␉␉␉{␊ |
1237 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1238 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1239 | ␉␉␉␉count ++;␊ |
1240 | ␊ |
1241 | ␉␉␉␉verbose("\tFound Lion pattern: patched!\n");␊ |
1242 | ␊ |
1243 | ␉␉␉␉if (PatchApplied)␊ |
1244 | ␉␉␉␉{␊ |
1245 | ␉␉␉␉␉break;␊ |
1246 | ␉␉␉␉}␊ |
1247 | ␊ |
1248 | ␉␉␉␉PatchApplied = 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 | ␉ */␊ |
1259 | ␉if (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 };␊ |
1263 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1264 | ␉␉{␊ |
1265 | ␉␉␉if (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 | ␉␉␉{␊ |
1276 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1277 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1278 | ␉␉␉␉count ++;␊ |
1279 | ␊ |
1280 | ␉␉␉␉verbose("\tFound Snow Leopard pattern: patched!\n");␊ |
1281 | ␊ |
1282 | ␉␉␉␉if (PatchApplied)␊ |
1283 | ␉␉␉␉{␊ |
1284 | ␉␉␉␉␉break;␊ |
1285 | ␉␉␉␉}␊ |
1286 | ␊ |
1287 | ␉␉␉␉PatchApplied = true;␊ |
1288 | ␉␉␉}␊ |
1289 | ␉␉}␊ |
1290 | ␉}␊ |
1291 | ␊ |
1292 | ␉if (!PatchApplied)␊ |
1293 | ␉{␊ |
1294 | ␉␉verbose("\tCan't find Booter Extensions patch location.\n");␊ |
1295 | ␉}␊ |
1296 | ␉else␊ |
1297 | ␉{␊ |
1298 | ␉␉verbose("\t%d substitution(s) made.\n", count);␊ |
1299 | ␉}␊ |
1300 | }␊ |
1301 | ␊ |
1302 | void patch_BooterExtensions_64(void *kernelData)␊ |
1303 | {␊ |
1304 | ␉// KernelBooterExtensionsPatch to load extra kexts besides kernelcache␊ |
1305 | ␉UInt8 *Bytes;␊ |
1306 | ␉UInt32 Index;␊ |
1307 | ␉bool PatchApplied; // does nothing␊ |
1308 | ␉int count = 0;␊ |
1309 | ␊ |
1310 | ␉verbose("\t- Searching for booter extensions pattern:\n");␊ |
1311 | ␊ |
1312 | ␉Bytes = (UInt8 *)kernelData;␊ |
1313 | ␉PatchApplied = false;␊ |
1314 | ␊ |
1315 | ␉// Sierra onward␊ |
1316 | ␉if (kernelOSVer >= MacOSVer2Int("10.12"))␊ |
1317 | ␉{␊ |
1318 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1319 | ␉␉{␊ |
1320 | ␉␉␉if ((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 | ␉␉␉{␊ |
1338 | ␉␉␉␉Bytes[Index + 4] = 0xEB;␊ |
1339 | ␉␉␉␉Bytes[Index + 5] = 0x12;␊ |
1340 | ␉␉␉␉count++;␊ |
1341 | ␊ |
1342 | ␉␉␉␉verbose("\tFound Sierra SIP pattern: patched!\n");␊ |
1343 | ␉␉␉␉PatchApplied = true;␊ |
1344 | ␉␉␉␉break;␊ |
1345 | ␉␉␉}␊ |
1346 | ␉␉}␊ |
1347 | ␉}␊ |
1348 | ␊ |
1349 | ␉if (kernelOSVer >= MacOSVer2Int("10.12"))␊ |
1350 | ␉{␊ |
1351 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1352 | ␉␉{␊ |
1353 | ␉␉␉if (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 | ␉␉␉{␊ |
1366 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1367 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1368 | ␉␉␉␉count++;␊ |
1369 | ␊ |
1370 | ␉␉␉␉verbose("\tFound Sierra EXT (Yosemite) pattern: patched!\n");␊ |
1371 | ␉␉␉␉PatchApplied = true;␊ |
1372 | ␉␉␉␉break;␊ |
1373 | ␉␉␉}␊ |
1374 | ␉␉}␊ |
1375 | ␉}␊ |
1376 | ␊ |
1377 | ␉if (kernelOSVer <= MacOSVer2Int("10.12.3"))␊ |
1378 | ␉{␊ |
1379 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1380 | ␉␉{␊ |
1381 | ␉␉␉if (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 | ␉␉␉{␊ |
1394 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1395 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1396 | ␉␉␉␉count++;␊ |
1397 | ␊ |
1398 | ␉␉␉␉verbose("\tFound Sierra EXT (<= 10.12.4) pattern: patched!\n");␊ |
1399 | ␉␉␉␉PatchApplied = true;␊ |
1400 | ␉␉␉␉break;␊ |
1401 | ␉␉␉}␊ |
1402 | ␉␉}␊ |
1403 | ␉}␊ |
1404 | ␊ |
1405 | ␉if (kernelOSVer >= MacOSVer2Int("10.12.4"))␊ |
1406 | ␉{␊ |
1407 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1408 | ␉␉{␊ |
1409 | ␉␉␉if (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 | ␉␉␉{␊ |
1422 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1423 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1424 | ␉␉␉␉count++;␊ |
1425 | ␊ |
1426 | ␉␉␉␉verbose("\tFound Sierra (> = 10.12.4) EXT pattern: patched!\n");␊ |
1427 | ␉␉␉␉PatchApplied = true;␊ |
1428 | ␉␉␉␉break;␊ |
1429 | ␉␉␉}␊ |
1430 | ␉␉}␊ |
1431 | ␉}␊ |
1432 | ␊ |
1433 | ␉// El Capitan/Yosemite␊ |
1434 | ␉if (kernelOSVer >= MacOSVer2Int("10.10") && kernelOSVer < MacOSVer2Int("10.12"))␊ |
1435 | ␉{␊ |
1436 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1437 | ␉␉{␊ |
1438 | ␉␉␉// El Capitan␊ |
1439 | ␉␉␉if (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 | ␉␉␉{␊ |
1456 | ␉␉␉␉Bytes[Index + 4] = 0xEB;␊ |
1457 | ␉␉␉␉Bytes[Index + 5] = 0x12;␊ |
1458 | ␉␉␉␉count++;␊ |
1459 | ␊ |
1460 | ␉␉␉␉if (kernelOSVer >= MacOSVer2Int("10.11"))␊ |
1461 | ␉␉␉␉{␊ |
1462 | ␉␉␉␉␉verbose("\tFound El Capitan SIP pattern: patched!\n");␊ |
1463 | ␉␉␉␉}␊ |
1464 | ␉␉␉␉else␊ |
1465 | ␉␉␉␉{␊ |
1466 | ␉␉␉␉␉verbose("\tFound Yosemite SIP pattern: patched!\n");␊ |
1467 | ␉␉␉␉}␊ |
1468 | ␊ |
1469 | ␉␉␉␉if (PatchApplied)␊ |
1470 | ␉␉␉␉{␊ |
1471 | ␉␉␉␉␉break;␊ |
1472 | ␉␉␉␉}␊ |
1473 | ␊ |
1474 | ␉␉␉␉PatchApplied = true;␊ |
1475 | ␉␉␉}␊ |
1476 | ␉␉␉// Yosemite and El Capitan␊ |
1477 | ␉␉␉if ((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 | ␉␉␉{␊ |
1491 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1492 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1493 | ␉␉␉␉count++;␊ |
1494 | ␉␉␉␉if (kernelOSVer < MacOSVer2Int("10.11"))␊ |
1495 | {␊ |
1496 | ␉␉␉␉␉verbose("\tFound Yosemite EXT pattern: patched!\n");␊ |
1497 | ␉␉␉␉}␊ |
1498 | ␉␉␉␉else␊ |
1499 | ␉␉␉␉{␊ |
1500 | ␉␉␉␉␉verbose("\tFound EL Capitan EXT pattern: patched!\n");␊ |
1501 | ␉␉␉␉}␊ |
1502 | ␊ |
1503 | ␉␉␉␉if (PatchApplied)␊ |
1504 | ␉␉␉␉{␊ |
1505 | ␉␉␉␉␉break;␊ |
1506 | ␉␉␉␉}␊ |
1507 | ␊ |
1508 | ␉␉␉␉PatchApplied = true;␊ |
1509 | ␉␉␉}␊ |
1510 | ␉␉}␊ |
1511 | ␉}␊ |
1512 | ␊ |
1513 | ␉// Mountain Lion/Mavericks␊ |
1514 | ␉if (kernelOSVer >= MacOSVer2Int("10.8") && kernelOSVer < MacOSVer2Int("10.10"))␊ |
1515 | ␉{␊ |
1516 | ␊ |
1517 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1518 | ␉␉{␊ |
1519 | ␉␉␉if (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 | ␉␉␉{␊ |
1531 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1532 | ␉␉␉␉Bytes[Index + 7] = 0x90;␊ |
1533 | ␉␉␉␉count++;␊ |
1534 | ␊ |
1535 | ␉␉␉␉verbose("\tFound M%s EXT pattern: patched!\n", checkOSVersion("10.8") ? "ountain Lion" : "avericks");␊ |
1536 | ␊ |
1537 | ␉␉␉␉if (PatchApplied)␊ |
1538 | ␉␉␉␉{␊ |
1539 | ␉␉␉␉␉break;␊ |
1540 | ␉␉␉␉}␊ |
1541 | ␊ |
1542 | ␉␉␉␉PatchApplied = true;␊ |
1543 | ␉␉␉}␊ |
1544 | ␉␉}␊ |
1545 | ␉}␊ |
1546 | ␊ |
1547 | ␉// Lion 64␊ |
1548 | ␉if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))␊ |
1549 | ␉{␊ |
1550 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1551 | ␉␉{␊ |
1552 | ␉␉␉if (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 | ␉␉␉{␊ |
1563 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1564 | ␉␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1565 | ␉␉␉␉count++;␊ |
1566 | ␊ |
1567 | ␉␉␉␉verbose("\tFound Lion EXT pattern: patched!\n");␊ |
1568 | ␊ |
1569 | ␉␉␉␉if (PatchApplied)␊ |
1570 | ␉␉␉␉{␊ |
1571 | ␉␉␉␉␉break;␊ |
1572 | ␉␉␉␉}␊ |
1573 | ␊ |
1574 | ␉␉␉␉PatchApplied = true;␊ |
1575 | ␉␉␉}␊ |
1576 | ␉␉}␊ |
1577 | ␉}␊ |
1578 | ␊ |
1579 | ␉// Snow Leopard 64␊ |
1580 | ␉if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))␊ |
1581 | ␉{␊ |
1582 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1583 | ␉␉{␊ |
1584 | ␉␉␉if (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 | ␉␉␉{␊ |
1595 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1596 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1597 | ␉␉␉␉verbose("\tFound Snow Leopard EXT pattern: patched!\n");␊ |
1598 | ␉␉␉␉count++;␊ |
1599 | ␊ |
1600 | ␉␉␉␉if (PatchApplied)␊ |
1601 | ␉␉␉␉{␊ |
1602 | ␉␉␉␉␉break;␊ |
1603 | ␉␉␉␉}␊ |
1604 | ␊ |
1605 | ␉␉␉␉PatchApplied = true;␊ |
1606 | ␉␉␉}␊ |
1607 | ␉␉}␊ |
1608 | ␉}␊ |
1609 | ␊ |
1610 | ␉if (!PatchApplied)␊ |
1611 | ␉{␊ |
1612 | ␉␉verbose("\tCan't find Booter Extensions patch location.\n");␊ |
1613 | ␉}␊ |
1614 | ␉else␊ |
1615 | ␉{␊ |
1616 | ␉␉verbose("\t%d substitution(s) made.\n", count);␊ |
1617 | ␉}␊ |
1618 | }␊ |
1619 | ␊ |
1620 | // ===================================␊ |
1621 | // Patch ssse3␊ |
1622 | void patch_SSE3_6(void *kernelData)␊ |
1623 | {␊ |
1624 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1625 | ␉UInt32 patchLocation1 = 0;␊ |
1626 | ␉UInt32 patchLocation2 = 0;␊ |
1627 | ␉UInt32 patchlast = 0;␊ |
1628 | ␉UInt32 i;␊ |
1629 | ␉//UInt32 Length = sizeof(kernelData);␊ |
1630 | ␊ |
1631 | ␉verbose("\t- Start find SSE3 address\n");␊ |
1632 | ␉i = 0;␊ |
1633 | ␉//for (i = 0; i < Length; i++)␊ |
1634 | ␉while(true)␊ |
1635 | ␉{␊ |
1636 | ␉␉if (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 | ␉␉{␊ |
1644 | ␉␉␉patchLocation1 = i-1664-32;␊ |
1645 | ␉␉␉verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
1646 | ␉␉}␊ |
1647 | ␊ |
1648 | ␉␉// hasSSE2+..... title␊ |
1649 | ␉␉if (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 | ␉␉{␊ |
1660 | ␉␉␉patchLocation2 = i;␊ |
1661 | ␉␉␉verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);␊ |
1662 | ␉␉␉break;␊ |
1663 | ␉␉}␊ |
1664 | ␉␉i++;␊ |
1665 | ␉}␊ |
1666 | ␊ |
1667 | ␉if (!patchLocation1 || !patchLocation2)␊ |
1668 | ␉{␊ |
1669 | ␉␉verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);␊ |
1670 | ␉␉return;␊ |
1671 | ␉}␊ |
1672 | ␊ |
1673 | ␉verbose("\tFound SSE3 last data addres Start\n");␊ |
1674 | ␉i = patchLocation1 + 1500;␊ |
1675 | ␉//for (i=(patchLocation1+1500); i<(patchLocation1+3000); i++)␊ |
1676 | ␉while(true)␊ |
1677 | ␉{␊ |
1678 | ␉␉if (bytes[i] == 0x90␊ |
1679 | ␉␉␉&& bytes[i + 1] == 0x90␊ |
1680 | ␉␉␉&& bytes[i + 2] == 0x55 )␊ |
1681 | ␉␉{␊ |
1682 | ␉␉␉patchlast = (i+1) - patchLocation1;␊ |
1683 | ␉␉␉verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1684 | ␉␉␉break;␊ |
1685 | ␉␉}␊ |
1686 | ␉␉i++;␊ |
1687 | ␉}␊ |
1688 | ␊ |
1689 | ␉if (!patchlast)␊ |
1690 | ␉{␊ |
1691 | ␉␉verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1692 | ␉␉return;␊ |
1693 | ␉}␊ |
1694 | ␉// patch sse3_64 data␊ |
1695 | ␊ |
1696 | ␉for (i = 0; i < patchlast; i++)␊ |
1697 | ␉{␊ |
1698 | ␉␉if (i < sizeof(sse3_patcher))␊ |
1699 | ␉␉{␊ |
1700 | ␉␉␉bytes[patchLocation1 + i] = sse3_patcher[i];␊ |
1701 | ␉␉}␊ |
1702 | ␉␉else␊ |
1703 | ␉␉{␊ |
1704 | ␉␉␉bytes[patchLocation1 + i] = 0x90;␊ |
1705 | ␉␉}␊ |
1706 | ␉}␊ |
1707 | ␊ |
1708 | ␉// patch kHasSSE3 title␊ |
1709 | ␉bytes[patchLocation2 + 0] = 0xFC;␊ |
1710 | ␉bytes[patchLocation2 + 1] = 0x05;␊ |
1711 | ␉bytes[patchLocation2 + 8] = 0x2C;␊ |
1712 | ␉bytes[patchLocation2 + 9] = 0x00;␊ |
1713 | ␊ |
1714 | }␊ |
1715 | ␊ |
1716 | // ===================================␊ |
1717 | //␊ |
1718 | void patch_SSE3_5(void *kernelData)␊ |
1719 | {␊ |
1720 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1721 | ␉UInt32 patchLocation1 = 0;␊ |
1722 | ␉UInt32 patchLocation2 = 0;␊ |
1723 | ␉UInt32 patchlast=0;␊ |
1724 | ␉UInt32 Length = sizeof(kernelData);␊ |
1725 | ␉UInt32 i;␊ |
1726 | ␊ |
1727 | ␉verbose("\t- Start find SSE3 address\n");␊ |
1728 | ␊ |
1729 | ␉for (i = 256; i < (Length-256); i++)␊ |
1730 | ␉{␊ |
1731 | ␉␉if (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 | ␉␉{␊ |
1739 | ␉␉␉patchLocation1 = i-1680-32;␊ |
1740 | ␉␉␉verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
1741 | ␉␉}␊ |
1742 | ␊ |
1743 | ␉␉// khasSSE2+..... title␊ |
1744 | ␉␉if (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 | ␉␉{␊ |
1755 | ␉␉␉patchLocation2 = i;␊ |
1756 | ␉␉␉verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);␊ |
1757 | ␉␉␉break;␊ |
1758 | ␉␉}␊ |
1759 | ␉}␊ |
1760 | ␊ |
1761 | ␉if (!patchLocation1 || !patchLocation2)␊ |
1762 | ␉{␊ |
1763 | ␉␉verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);␊ |
1764 | ␉␉return;␊ |
1765 | ␉}␊ |
1766 | ␊ |
1767 | ␉verbose("\tFound SSE3 last data addres Start\n");␊ |
1768 | ␊ |
1769 | ␉for (i = (patchLocation1+1500);i < Length;i++)␊ |
1770 | ␉{␊ |
1771 | ␉␉if (bytes[i] == 0x90␊ |
1772 | ␉␉␉&& bytes[i + 1] == 0x90␊ |
1773 | ␉␉␉&& bytes[i + 2] == 0x55)␊ |
1774 | ␉␉{␊ |
1775 | ␉␉␉patchlast = (i+1) - patchLocation1;␊ |
1776 | ␉␉␉verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1777 | ␉␉␉break;␊ |
1778 | ␉␉}␊ |
1779 | ␉}␊ |
1780 | ␊ |
1781 | ␉if (!patchlast)␊ |
1782 | ␉{␊ |
1783 | ␉␉verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1784 | ␉␉return;␊ |
1785 | ␉}␊ |
1786 | ␊ |
1787 | ␉// patech sse3_64 data␊ |
1788 | ␊ |
1789 | ␉for (i = 0; i < patchlast; i++)␊ |
1790 | ␉{␊ |
1791 | ␉␉if (i < sizeof(sse3_5_patcher))␊ |
1792 | ␉␉{␊ |
1793 | ␉␉␉bytes[patchLocation1 + i] = sse3_5_patcher[i];␊ |
1794 | ␉␉}␊ |
1795 | ␉␉else␊ |
1796 | ␉␉{␊ |
1797 | ␉␉␉bytes[patchLocation1 + i] = 0x90;␊ |
1798 | ␉␉}␊ |
1799 | ␉}␊ |
1800 | ␊ |
1801 | ␉// patch kHasSSE3 title␊ |
1802 | ␉bytes[patchLocation2 + 0] = 0x0C;␊ |
1803 | ␉bytes[patchLocation2 + 1] = 0x06;␊ |
1804 | ␉bytes[patchLocation2 + 8] = 0x2C;␊ |
1805 | ␉bytes[patchLocation2 + 9] = 0x00;␊ |
1806 | ␊ |
1807 | }␊ |
1808 | ␊ |
1809 | // ===================================␊ |
1810 | //␊ |
1811 | void patch_SSE3_7(void *kernelData)␊ |
1812 | {␊ |
1813 | ␉// not support yet␊ |
1814 | ␉return;␊ |
1815 | }␊ |
1816 | ␊ |
1817 | // ===================================␊ |
1818 | // root:xnu text replacement Patch␊ |
1819 | bool patch_string_XNU_init(void *kernelData) //␊ |
1820 | {␊ |
1821 | ␊ |
1822 | ␉UInt8␉*Bytes;␊ |
1823 | ␉UInt32␉Index;␊ |
1824 | ␉bool␉PatchApplied;␊ |
1825 | ␊ |
1826 | ␉DBG("\t- Searching for \"root:xnu-\" string pattern\n");␊ |
1827 | ␊ |
1828 | ␉Bytes = (UInt8 *)kernelData;␊ |
1829 | ␉PatchApplied = false;␊ |
1830 | ␊ |
1831 | ␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1832 | ␉{␊ |
1833 | ␉␉// search for root:xnu- and replace it with ***Enoch-␊ |
1834 | ␉␉if (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 | ␉␉{␊ |
1845 | ␉␉␉Bytes[Index + 1] = '*';␊ |
1846 | ␉␉␉Bytes[Index + 2] = '*';␊ |
1847 | ␉␉␉Bytes[Index + 3] = '*';␊ |
1848 | ␉␉␉Bytes[Index + 4] = 'E';␊ |
1849 | ␉␉␉Bytes[Index + 5] = 'n';␊ |
1850 | ␉␉␉Bytes[Index + 6] = 'o';␊ |
1851 | ␉␉␉Bytes[Index + 7] = 'c';␊ |
1852 | ␉␉␉Bytes[Index + 8] = 'h';␊ |
1853 | ␊ |
1854 | ␉␉␉DBG("\tFound \"root:xnu-\" pattern; patched.\n");␊ |
1855 | ␊ |
1856 | ␉␉␉if (PatchApplied)␊ |
1857 | ␉␉␉{␊ |
1858 | ␉␉␉␉break;␊ |
1859 | ␉␉␉}␊ |
1860 | ␊ |
1861 | ␉␉␉PatchApplied = true;␊ |
1862 | ␉␉}␊ |
1863 | ␉}␊ |
1864 | ␊ |
1865 | ␉if (!PatchApplied)␊ |
1866 | ␉{␊ |
1867 | ␉␉DBG("\tCan't find \"root:xnu-\" string pattern: patch not applied.\n");␊ |
1868 | ␉}␊ |
1869 | ␊ |
1870 | ␉return PatchApplied;␊ |
1871 | }␊ |
1872 | ␊ |
1873 | // ===================================␊ |
1874 | // (Clover)␊ |
1875 | // Patching AppleRTC to prevent CMOS reset␊ |
1876 | unsigned 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␊ |
1939 | unsigned 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␊ |
2009 | unsigned 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)␊ |
2027 | unsigned 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␊ |
2045 | unsigned 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␊ |
2084 | void 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␊ |
2238 | ␉␉␉␉patchBooterDefinedKext(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 | ␊ |
2270 | void patchBooterDefinedKext(const char *kext, void *driverAddr, UInt32 DriverSize, UInt32 StartLocation)␊ |
2271 | {␊ |
2272 | ␉if ((!strcmp(kext, "AppleRTC")) && AppleRTCPatch)␊ |
2273 | ␉{␊ |
2274 | ␉␉verbose("\tPatching %s:", kext);␊ |
2275 | ␊ |
2276 | ␉␉unsigned int numPatches = AppleRTC_Patch(driverAddr, DriverSize, StartLocation);␊ |
2277 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2278 | ␉}␊ |
2279 | ␊ |
2280 | ␉if ((!strcmp(kext, "AppleIntelCPUPowerManagement")) && AICPMPatch)␊ |
2281 | ␉{␊ |
2282 | ␉␉verbose("\tPatching %s (locked msr):\n", kext);␊ |
2283 | ␊ |
2284 | ␉␉unsigned int numPatches = AsusAICPUPMPatch(driverAddr, DriverSize, StartLocation);␊ |
2285 | ␉␉verbose("\t %d substitutions made!\n", numPatches);␊ |
2286 | ␉}␊ |
2287 | ␊ |
2288 | ␉if ((!strcmp(kext, "NVDAStartupWeb")) && NVIDIAWebDrv)␊ |
2289 | ␉{␊ |
2290 | ␉␉verbose("\tPatching %s (force load w/o nvram):\n", kext);␊ |
2291 | ␊ |
2292 | ␉␉unsigned int numPatches = patch_NVDAStartupWeb(driverAddr, DriverSize, StartLocation);␊ |
2293 | ␉␉verbose("\t %d substitutions made!\n", numPatches);␊ |
2294 | ␉}␊ |
2295 | ␊ |
2296 | ␉if ((!strcmp(kext, "IOAHCIBlockStorage")) && TrimEnablerSata)␊ |
2297 | ␉{␊ |
2298 | ␉␉verbose("\tPatching %s (trim enabler SATA):", kext);␊ |
2299 | ␊ |
2300 | ␉␉unsigned int numPatches = trimEnablerSata(driverAddr, DriverSize, StartLocation);␊ |
2301 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2302 | ␉}␊ |
2303 | ␊ |
2304 | ␉if ((!strcmp(kext, "AppleAHCIPort")) && OrangeIconFixSata)␊ |
2305 | ␉{␊ |
2306 | ␉␉verbose("\tPatching %s (orange icon fix):", kext);␊ |
2307 | ␊ |
2308 | ␉␉unsigned int numPatches = patch_AppleAHCIPort_OrangeFix(driverAddr, DriverSize, StartLocation);␊ |
2309 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2310 | ␉}␊ |
2311 | }␊ |
2312 | ␊ |
2313 | // ===================================␊ |
2314 | // Boolean function to check the full OSX match version␊ |
2315 | bool checkFullOSVer(const char *version)␊ |
2316 | {␊ |
2317 | ␉// We are in a version with 7 char ?␊ |
2318 | ␉if ( (sizeof(version) == 7) && ('.' == version[5]) && ('\0' != version[6]) ) // 10.xx.x␊ |
2319 | ␉{␊ |
2320 | ␉␉return ( (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 ?␊ |
2331 | ␉if ( (sizeof(version) == 7) && ('.' == version[4]) && ('\0' != version[6]) ) // 10.4.11␊ |
2332 | ␉{␊ |
2333 | ␉␉return ( (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 ?␊ |
2344 | ␉if ( (sizeof(version) == 6) && ('.' == version[4]) && ('\0' != version[5]) ) // 10.x.x␊ |
2345 | ␉{␊ |
2346 | ␉␉return ( (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 ?␊ |
2356 | ␉if ( (sizeof(version) == 5) && ('.' != version[4]) && ('\0' != version[4]) ) // 10.xx␊ |
2357 | ␉{␊ |
2358 | ␉␉return ( (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 ?␊ |
2367 | ␉if ( (sizeof(version) == 4) && ('\0' != version[3]) ) // 10.x␊ |
2368 | ␉{␊ |
2369 | ␉␉return ( (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␊ |
2377 | ␉return false;␊ |
2378 | }␊ |
2379 | |