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