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("\tKernelHaswell state: %s!\n", KernelHaswell ? " enabled" : "disabled");␊ |
61 | ␉verbose("\tKernelcpuFamily state: %s!\n", KernelcpuFamily ? " enabled" : "disabled");␊ |
62 | ␉verbose("\tKernelSSE3 state: %s!\n", KernelSSE3 ? " enabled" : "disabled");␊ |
63 | ␊ |
64 | u_int32_t sizeToScan = uncompressed_size; // for further expansion␊ |
65 | ␊ |
66 | ␉// Select machine arch␊ |
67 | ␉if (archCpuType == CPU_TYPE_I386)␊ |
68 | ␉{␊ |
69 | ␉␉patch_kernel_32((void *)kernelData, sizeToScan);␊ |
70 | ␉}␊ |
71 | ␉else␊ |
72 | ␉{␊ |
73 | ␉␉patch_kernel_64((void *)kernelData, sizeToScan);␊ |
74 | ␉}␊ |
75 | ␊ |
76 | ␉/* VMware issue␊ |
77 | ␉if (patch_string_XNU_init(kernelData))␊ |
78 | ␉{␊ |
79 | ␉␉DBG("\tKernel string replaced.\n");␊ |
80 | ␉}␊ |
81 | ␉*/␊ |
82 | ␊ |
83 | // do user's defined patches␊ |
84 | if (bootInfo->kernelConfig.dictionary) {␊ |
85 | pach_binaryUsingDictionary(kernelData,␊ |
86 | (UInt32)uncompressed_size,␊ |
87 | 0,␊ |
88 | "KernelPatches",␊ |
89 | bootInfo->kernelConfig.dictionary);␊ |
90 | }␊ |
91 | ␊ |
92 | ␉verbose("Kernel patcher: end!\n\n");␊ |
93 | }␊ |
94 | ␊ |
95 | // ===================================␊ |
96 | // patches for a 64-bit kernel.␊ |
97 | void patch_kernel_64(void *kernelData, u_int32_t uncompressed_size) // KernelPatcher_64␊ |
98 | {␊ |
99 | ␉DBG("[ 64-bit ]\n");␊ |
100 | ␊ |
101 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
102 | ␉UInt32 patchLocation = 0, patchLocation1 = 0;␊ |
103 | ␉UInt32 i;␊ |
104 | ␉UInt32 switchaddr = 0;␊ |
105 | ␉UInt32 mask_family = 0, mask_model = 0;␊ |
106 | ␉UInt32 cpuid_family_addr = 0, cpuid_model_addr = 0;␊ |
107 | ␊ |
108 | ␉// Prelinked Extensions Patcher␊ |
109 | ␉if (KernelBooter_kexts)␊ |
110 | ␉{␊ |
111 | patch_BooterExtensions_64(kernelData);␊ |
112 | ␉}␊ |
113 | ␊ |
114 | ␉// Lapic Error␊ |
115 | ␉if (KernelLapicError && patch_lapic_init_64(kernelData))␊ |
116 | ␉{␊ |
117 | ␉␉verbose("\tLapic Error call removed.\n");␊ |
118 | ␉}␊ |
119 | ␊ |
120 | ␉// Power Managment␊ |
121 | ␉if (KernelPm && patch_pm_init(kernelData))␊ |
122 | ␉{␊ |
123 | ␉␉verbose("\tPower Managment patch applied.\n");␊ |
124 | ␉}␊ |
125 | ␊ |
126 | ␉// Haswell Kernel Patcher␊ |
127 | ␉if ( KernelHaswell && (kernelOSVer >= MacOSVer2Int("10.8")) ) // Haswell "E" and "ULT" support␊ |
128 | ␉{␊ |
129 | ␉␉switch (Platform.CPU.Family)␊ |
130 | ␉␉{␊ |
131 | ␉␉␉case 0x06:␊ |
132 | ␉␉␉{␊ |
133 | ␉␉␉␉switch (Platform.CPU.Model)␊ |
134 | ␉␉␉␉{␊ |
135 | ␉␉␉␉␉case CPUID_MODEL_HASWELL_SVR: // Haswell-E Kernel Patcher␊ |
136 | ␉␉␉␉␉␉if (patch_haswell_E_init(kernelData))␊ |
137 | ␉␉␉␉␉␉{␊ |
138 | ␉␉␉␉␉␉␉verbose("\tHaswell-E Kernel patch applied.\n");␊ |
139 | ␉␉␉␉␉␉}␊ |
140 | ␉␉␉␉␉␉break;␊ |
141 | ␊ |
142 | ␉␉␉␉␉case CPUID_MODEL_HASWELL_ULT: // Haswell-ULT Kernel Patcher␊ |
143 | ␉␉␉␉␉␉if (patch_haswell_ULT_init(kernelData))␊ |
144 | ␉␉␉␉␉␉{␊ |
145 | ␉␉␉␉␉␉␉verbose("\tHaswell-ULT Kernel patch applied.\n");␊ |
146 | ␉␉␉␉␉␉}␊ |
147 | ␉␉␉␉␉␉break;␊ |
148 | ␊ |
149 | ␉␉␉␉␉default:␊ |
150 | ␉␉␉␉␉␉verbose("\tNo Haswell-ULT/-E Kernel patch applied for this CPU.\n");␊ |
151 | ␉␉␉␉␉␉break;␊ |
152 | ␉␉␉␉}␊ |
153 | ␉␉␉}␊ |
154 | ␉␉}␊ |
155 | ␉}␊ |
156 | ␊ |
157 | ␉if (KernelcpuFamily)␊ |
158 | ␉{␊ |
159 | ␉␉verbose("\t- Looking for _cpuid_set_info _panic ...\n");␊ |
160 | ␊ |
161 | ␉␉// Determine location of _cpuid_set_info _panic call for reference␊ |
162 | ␉␉// basically looking for info_p->cpuid_model = bitfield32(reg[eax], 7, 4);␊ |
163 | ␉␉for (i = 0; i < 0x1000000; i++)␊ |
164 | ␉␉{␊ |
165 | ␉␉␉if (bytes[i + 0] == 0xC7␊ |
166 | ␉␉␉␉&& bytes[i + 1] == 0x05␊ |
167 | ␉␉␉␉&& bytes[i + 5] == 0x00␊ |
168 | ␉␉␉␉&& bytes[i + 6] == 0x07␊ |
169 | ␉␉␉␉&& bytes[i + 7] == 0x00␊ |
170 | ␉␉␉␉&& bytes[i + 8] == 0x00␊ |
171 | ␉␉␉␉&& bytes[i + 9] == 0x00␊ |
172 | ␉␉␉␉&& bytes[i - 5] == 0xE8)␊ |
173 | ␉␉␉{␊ |
174 | ␉␉␉␉// matching 0xE8 for _panic call start␊ |
175 | ␉␉␉␉patchLocation = i-5;␊ |
176 | ␉␉␉␉break;␊ |
177 | ␉␉␉}␊ |
178 | ␉␉}␊ |
179 | ␊ |
180 | ␉␉if (!patchLocation)␊ |
181 | ␉␉{␊ |
182 | ␉␉␉verbose("\t_cpuid_set_info Unsupported CPU _panic not found \n");␊ |
183 | ␉␉␉return;␊ |
184 | ␉␉}␊ |
185 | ␊ |
186 | ␉␉// make sure only kernels for OSX 10.6.0 to 10.7.3 are being patched by this approach␊ |
187 | ␉␉if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer <= MacOSVer2Int("10.7.3"))␊ |
188 | ␉␉{␊ |
189 | ␊ |
190 | ␉␉␉verbose("\t- will patch kernel for OSX 10.6.0 to 10.7.3\n");␊ |
191 | ␊ |
192 | ␉␉␉// remove tsc_init: unknown CPU family panic for kernels prior to 10.6.2 which still had Atom support␊ |
193 | ␉␉␉if (kernelOSVer < MacOSVer2Int("10.6.2"))␊ |
194 | ␉␉␉{␊ |
195 | ␉␉␉␉for (i=0; i<0x1000000; i++)␊ |
196 | {␊ |
197 | ␉␉␉␉␉// find _tsc_init panic address by byte sequence 488d3df4632a00␊ |
198 | ␉␉␉␉␉if (bytes[i] == 0x48␊ |
199 | ␉␉␉␉␉␉&& bytes[i + 1] == 0x8D␊ |
200 | ␉␉␉␉␉␉&& bytes[i + 2] == 0x3D␊ |
201 | ␉␉␉␉␉␉&& bytes[i + 3] == 0xF4␊ |
202 | ␉␉␉␉␉␉&& bytes[i + 4] == 0x63␊ |
203 | ␉␉␉␉␉␉&& bytes[i + 5] == 0x2A␊ |
204 | ␉␉␉␉␉␉&& bytes[i + 6] == 0x00)␊ |
205 | ␉␉␉␉␉{␊ |
206 | ␉␉␉␉␉␉patchLocation1 = i+9;␊ |
207 | ␉␉␉␉␉␉verbose("\tFound _tsc_init _panic address at 0x%08x\n", (unsigned int)patchLocation1);␊ |
208 | ␉␉␉␉␉␉break;␊ |
209 | ␉␉␉␉␉}␊ |
210 | ␉␉␉␉}␊ |
211 | ␊ |
212 | ␉␉␉␉// NOP _panic call␊ |
213 | ␉␉␉␉if (patchLocation1)␊ |
214 | ␉␉␉␉{␊ |
215 | ␉␉␉␉␉bytes[patchLocation1 + 0] = 0x90;␊ |
216 | ␉␉␉␉␉bytes[patchLocation1 + 1] = 0x90;␊ |
217 | ␉␉␉␉␉bytes[patchLocation1 + 2] = 0x90;␊ |
218 | ␉␉␉␉␉bytes[patchLocation1 + 3] = 0x90;␊ |
219 | ␉␉␉␉␉bytes[patchLocation1 + 4] = 0x90;␊ |
220 | ␉␉␉␉}␊ |
221 | ␉␉␉}␊ |
222 | ␉␉␉else␊ |
223 | ␉␉␉{␊ |
224 | ␉␉␉␉// assume patching logic for OSX 10.6.2 to 10.7.3␊ |
225 | ␊ |
226 | ␉␉␉␉/*␊ |
227 | ␉␉␉␉ * Here is our case from CPUID switch statement, it sets CPUFAMILY_UNKNOWN␊ |
228 | ␉␉␉␉ * C7051C2C5F0000000000 mov dword [ds:0xffffff80008a22c0], 0x0 (example from 10.7)␊ |
229 | ␉␉␉␉ */␊ |
230 | ␉␉␉␉switchaddr = patchLocation - 19;␊ |
231 | ␉␉␉␉verbose("\tswitch statement patch location is 0x%08lx\n", (switchaddr+6));␊ |
232 | ␊ |
233 | ␉␉␉␉if (bytes[switchaddr + 0] == 0xC7␊ |
234 | ␉␉␉␉␉&& bytes[switchaddr + 1] == 0x05␊ |
235 | ␉␉␉␉␉&& bytes[switchaddr + 5] == 0x00␊ |
236 | ␉␉␉␉␉&& bytes[switchaddr + 6] == 0x00␊ |
237 | ␉␉␉␉␉&& bytes[switchaddr + 7] == 0x00␊ |
238 | ␉␉␉␉␉&& bytes[switchaddr + 8] == 0x00)␊ |
239 | ␉␉␉␉{␊ |
240 | ␉␉␉␉␉// Determine cpuid_family address from above mov operation␊ |
241 | ␉␉␉␉␉cpuid_family_addr =␊ |
242 | ␉␉␉␉␉␉bytes[switchaddr + 2] << 0 |␊ |
243 | ␉␉␉␉␉␉bytes[switchaddr + 3] << 8 |␊ |
244 | ␉␉␉␉␉␉bytes[switchaddr + 4] << 16 |␊ |
245 | ␉␉␉␉␉␉bytes[switchaddr + 5] << 24;␊ |
246 | ␉␉␉␉␉cpuid_family_addr = cpuid_family_addr + (switchaddr + 10);␊ |
247 | ␊ |
248 | ␉␉␉␉␉if (cpuid_family_addr)␊ |
249 | ␉␉␉␉␉{␊ |
250 | ␉␉␉␉␉␉// Determine cpuid_model address␊ |
251 | ␉␉␉␉␉␉// for 10.6.2 kernels it's offset by 299 bytes from cpuid_family address␊ |
252 | ␉␉␉␉␉␉if (kernelOSVer == MacOSVer2Int("10.6.2"))␊ |
253 | ␉␉␉␉␉␉{␊ |
254 | ␉␉␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X12B;␊ |
255 | ␉␉␉␉␉␉}␊ |
256 | ␉␉␉␉␉␉// for 10.6.3 to 10.6.7 it's offset by 303 bytes␊ |
257 | ␉␉␉␉␉␉else if (kernelOSVer <= MacOSVer2Int("10.6.7"))␊ |
258 | ␉␉␉␉␉␉{␊ |
259 | ␉␉␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X12F;␊ |
260 | ␉␉␉␉␉␉}␊ |
261 | ␉␉␉␉␉␉// for 10.6.8 to 10.7.3 kernels - by 339 bytes␊ |
262 | ␉␉␉␉␉␉else␊ |
263 | ␉␉␉␉␉␉{␊ |
264 | ␉␉␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X153;␊ |
265 | ␉␉␉␉␉␉}␊ |
266 | ␊ |
267 | ␉␉␉␉␉␉verbose("\tcpuid_family address: 0x%08X\n", (unsigned int)cpuid_family_addr);␊ |
268 | ␉␉␉␉␉␉verbose("\tcpuid_model address: 0x%08X\n", (unsigned int)cpuid_model_addr);␊ |
269 | ␊ |
270 | ␉␉␉␉␉␉switchaddr += 6; // offset 6 bytes in mov operation to write a dword instead of zero␊ |
271 | ␊ |
272 | ␉␉␉␉␉␉// calculate mask for patching, cpuid_family mask not needed as we offset on a valid mask␊ |
273 | ␉␉␉␉␉␉mask_model = cpuid_model_addr - (switchaddr+14);␊ |
274 | ␉␉␉␉␉␉//verbose("\tmodel mask 0x%08x\n", (unsigned int)mask_model);␊ |
275 | ␊ |
276 | ␉␉␉␉␉␉//verbose("\toverriding cpuid_family and cpuid_model as CPUID_INTEL_PENRYN\n");␊ |
277 | ␉␉␉␉␉␉bytes[switchaddr+0] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;␊ |
278 | ␉␉␉␉␉␉bytes[switchaddr+1] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;␊ |
279 | ␉␉␉␉␉␉bytes[switchaddr+2] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;␊ |
280 | ␉␉␉␉␉␉bytes[switchaddr+3] = (CPUFAMILY_INTEL_PENRYN & 0xFF000000) >> 24;␊ |
281 | ␊ |
282 | ␉␉␉␉␉␉// mov dword [ds:0xffffff80008a216d], 0x2000117␊ |
283 | ␉␉␉␉␉␉bytes[switchaddr+4] = 0xC7;␊ |
284 | ␉␉␉␉␉␉bytes[switchaddr+5] = 0x05;␊ |
285 | ␉␉␉␉␉␉bytes[switchaddr+6] = (UInt8)((mask_model & 0x000000FF) >> 0);␊ |
286 | ␉␉␉␉␉␉bytes[switchaddr+7] = (UInt8)((mask_model & 0x0000FF00) >> 8);␊ |
287 | ␉␉␉␉␉␉bytes[switchaddr+8] = (UInt8)((mask_model & 0x00FF0000) >> 16);␊ |
288 | ␉␉␉␉␉␉bytes[switchaddr+9] = (UInt8)((mask_model & 0xFF000000) >> 24);␊ |
289 | ␉␉␉␉␉␉bytes[switchaddr+10] = 0x17; // cpuid_model (Penryn)␊ |
290 | ␉␉␉␉␉␉bytes[switchaddr+11] = 0x01; // cpuid_extmodel␊ |
291 | ␉␉␉␉␉␉bytes[switchaddr+12] = 0x00; // cpuid_extfamily␊ |
292 | ␉␉␉␉␉␉bytes[switchaddr+13] = 0x02; // cpuid_stepping␊ |
293 | ␊ |
294 | ␉␉␉␉␉␉// fill remainder with 4 NOPs␊ |
295 | ␉␉␉␉␉␉for (i = 14; i < 18; i++)␊ |
296 | ␉␉␉␉␉␉{␊ |
297 | ␉␉␉␉␉␉␉bytes[switchaddr+i] = 0x90;␊ |
298 | ␉␉␉␉␉␉}␊ |
299 | ␉␉␉␉␉}␊ |
300 | ␉␉␉␉}␊ |
301 | ␉␉␉␉else␊ |
302 | ␉␉␉␉{␊ |
303 | ␉␉␉␉␉verbose("\tUnable to determine cpuid_family address, patching aborted\n");␊ |
304 | ␉␉␉␉␉return;␊ |
305 | ␉␉␉␉}␊ |
306 | ␉␉␉}␊ |
307 | ␊ |
308 | ␉␉␉// patch sse3␊ |
309 | ␉␉␉if (KernelSSE3 && (SNOW_LEOPARD))␊ |
310 | ␉␉␉{␊ |
311 | ␉␉␉␉patch_SSE3_6((void *)bytes);␊ |
312 | ␉␉␉}␊ |
313 | ␊ |
314 | ␉␉␉if (KernelSSE3 && (LION))␊ |
315 | ␉␉␉{␊ |
316 | ␉␉␉␉patch_SSE3_7((void *)bytes);␊ |
317 | ␉␉␉}␊ |
318 | ␉␉}␊ |
319 | ␊ |
320 | ␉␉// all 10.7.4+ kernels share common CPUID switch statement logic,␊ |
321 | ␉␉// it needs to be exploited in diff manner due to the lack of space␊ |
322 | ␉␉else if (kernelOSVer >= MacOSVer2Int("10.7.4"))␊ |
323 | ␉␉{␊ |
324 | ␉␉␉verbose("\t- will patch kernel for OSX %s (from 10.7.4 and newer)\n", gBootVolume->OSFullVer);␊ |
325 | ␊ |
326 | ␉␉␉/*␊ |
327 | ␉␉␉ * Here is our switchaddress location ... it should be case 20 from CPUID switch statement␊ |
328 | ␉␉␉ * 833D78945F0000 cmp dword [ds:0xffffff80008a21d0], 0x0;␊ |
329 | ␉␉␉ * 7417 je 0xffffff80002a8d71␊ |
330 | ␉␉␉ */␊ |
331 | ␉␉␉switchaddr = patchLocation-45;␊ |
332 | ␉␉␉verbose("\tswitch statement patch location is 0x%08X\n", (unsigned int)switchaddr);␊ |
333 | ␊ |
334 | ␉␉␉if(bytes[switchaddr + 0] == 0x83␊ |
335 | ␉␉␉␉&& bytes[switchaddr + 1] == 0x3D␊ |
336 | ␉␉␉␉&& bytes[switchaddr + 5] == 0x00␊ |
337 | ␉␉␉␉&& bytes[switchaddr + 6] == 0x00␊ |
338 | ␉␉␉␉&& bytes[switchaddr + 7] == 0x74)␊ |
339 | ␉␉␉{␊ |
340 | ␊ |
341 | ␉␉␉␉// Determine cpuid_family address␊ |
342 | ␉␉␉␉// 891D4F945F00 mov dword [ds:0xffffff80008a21a0], ebx␊ |
343 | ␉␉␉␉cpuid_family_addr =␊ |
344 | ␉␉␉␉␉bytes[switchaddr - 4] << 0 |␊ |
345 | ␉␉␉␉␉bytes[switchaddr - 3] << 8 |␊ |
346 | ␉␉␉␉␉bytes[switchaddr - 2] << 16 |␊ |
347 | ␉␉␉␉␉bytes[switchaddr - 1] << 24;␊ |
348 | ␉␉␉␉cpuid_family_addr = cpuid_family_addr + switchaddr;␊ |
349 | ␊ |
350 | ␉␉␉␉if (cpuid_family_addr)␊ |
351 | ␉␉␉␉{␊ |
352 | ␉␉␉␉␉// Determine cpuid_model address␊ |
353 | ␉␉␉␉␉// for 10.6.8+ kernels it's 339 bytes apart from cpuid_family address␊ |
354 | ␉␉␉␉␉cpuid_model_addr = cpuid_family_addr - 0X153;␊ |
355 | ␊ |
356 | ␉␉␉␉␉verbose("\tcpuid_family address: 0x%08X\n", (unsigned int)cpuid_family_addr);␊ |
357 | ␉␉␉␉␉verbose("\tcpuid_model address: 0x%08X\n", (unsigned int)cpuid_model_addr);␊ |
358 | ␊ |
359 | ␉␉␉␉␉// Calculate masks for patching␊ |
360 | ␉␉␉␉␉mask_family = cpuid_family_addr - (switchaddr +15);␊ |
361 | ␉␉␉␉␉mask_model = cpuid_model_addr - (switchaddr +25);␊ |
362 | ␉␉␉␉␉verbose("\tfamily mask: 0x%08X \n\tmodel mask: 0x%08X\n", (unsigned int)mask_family, (unsigned int)mask_model);␊ |
363 | ␊ |
364 | ␉␉␉␉␉// retain original␊ |
365 | ␉␉␉␉␉// test ebx, ebx␊ |
366 | ␉␉␉␉␉bytes[switchaddr+0] = bytes[patchLocation-13];␊ |
367 | ␉␉␉␉␉bytes[switchaddr+1] = bytes[patchLocation-12];␊ |
368 | ␉␉␉␉␉// retain original, but move jump offset by 20 bytes forward␊ |
369 | ␉␉␉␉␉// jne for above test␊ |
370 | ␉␉␉␉␉bytes[switchaddr+2] = bytes[patchLocation-11];␊ |
371 | ␉␉␉␉␉bytes[switchaddr+3] = bytes[patchLocation-10]+0x20;␊ |
372 | ␉␉␉␉␉// mov ebx, 0x78ea4fbc␊ |
373 | ␉␉␉␉␉bytes[switchaddr+4] = 0xBB;␊ |
374 | ␉␉␉␉␉bytes[switchaddr+5] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;␊ |
375 | ␉␉␉␉␉bytes[switchaddr+6] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;␊ |
376 | ␉␉␉␉␉bytes[switchaddr+7] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;␊ |
377 | ␉␉␉␉␉bytes[switchaddr+8] = (CPUFAMILY_INTEL_PENRYN & 0xFF000000) >> 24;␊ |
378 | ␊ |
379 | ␉␉␉␉␉// mov dword, ebx␊ |
380 | ␉␉␉␉␉bytes[switchaddr+9] = 0x89;␊ |
381 | ␉␉␉␉␉bytes[switchaddr+10] = 0x1D;␊ |
382 | ␉␉␉␉␉// cpuid_cpufamily address 0xffffff80008a21a0␊ |
383 | ␉␉␉␉␉bytes[switchaddr+11] = (UInt8)((mask_family & 0x000000FF) >> 0);␊ |
384 | ␉␉␉␉␉bytes[switchaddr+12] = (UInt8)((mask_family & 0x0000FF00) >> 8);␊ |
385 | ␉␉␉␉␉bytes[switchaddr+13] = (UInt8)((mask_family & 0x00FF0000) >> 16);␊ |
386 | ␉␉␉␉␉bytes[switchaddr+14] = (UInt8)((mask_family & 0xFF000000) >> 24);␊ |
387 | ␊ |
388 | ␉␉␉␉␉// mov dword␊ |
389 | ␉␉␉␉␉bytes[switchaddr+15] = 0xC7;␊ |
390 | ␉␉␉␉␉bytes[switchaddr+16] = 0x05;␊ |
391 | ␉␉␉␉␉// cpuid_model address 0xffffff80008b204d␊ |
392 | ␉␉␉␉␉bytes[switchaddr+17] = (UInt8)((mask_model & 0x000000FF) >> 0);␊ |
393 | ␉␉␉␉␉bytes[switchaddr+18] = (UInt8)((mask_model & 0x0000FF00) >> 8);␊ |
394 | ␉␉␉␉␉bytes[switchaddr+19] = (UInt8)((mask_model & 0x00FF0000) >> 16);␊ |
395 | ␉␉␉␉␉bytes[switchaddr+20] = (UInt8)((mask_model & 0xFF000000) >> 24);␊ |
396 | ␊ |
397 | ␉␉␉␉␉bytes[switchaddr+21] = 0x17; // cpuid_model␊ |
398 | ␉␉␉␉␉bytes[switchaddr+22] = 0x01; // cpuid_extmodel␊ |
399 | ␉␉␉␉␉bytes[switchaddr+23] = 0x00; // cpuid_extfamily␊ |
400 | ␉␉␉␉␉bytes[switchaddr+24] = 0x02; // cpuid_stepping␊ |
401 | ␊ |
402 | ␉␉␉␉␉// fill remainder with 25 NOPs␊ |
403 | ␉␉␉␉␉for (i=25; i<25+25; i++)␊ |
404 | ␉␉␉␉␉{␊ |
405 | ␉␉␉␉␉␉bytes[switchaddr+i] = 0x90;␊ |
406 | ␉␉␉␉␉}␊ |
407 | ␉␉␉␉}␊ |
408 | ␉␉␉}␊ |
409 | ␉␉␉else␊ |
410 | ␉␉␉{␊ |
411 | ␉␉␉␉verbose("\tUnable to determine cpuid_family address, patching aborted\n");␊ |
412 | ␉␉␉␉return;␊ |
413 | ␉␉␉}␊ |
414 | ␉␉}␊ |
415 | ␊ |
416 | ␉␉verbose("\n");␊ |
417 | ␉}␊ |
418 | }␊ |
419 | ␊ |
420 | // ===================================␊ |
421 | // patches for a 32-bit kernel.␊ |
422 | void patch_kernel_32(void *kernelData, u_int32_t uncompressed_size) // KernelPatcher_32␊ |
423 | {␊ |
424 | ␉DBG("[ 32-bit ]\n");␊ |
425 | ␊ |
426 | ␉UInt8 *bytes = ( UInt8 *)kernelData;␊ |
427 | ␉UInt32 patchLocation = 0, patchLocation1 = 0;␊ |
428 | ␉UInt32 i;␊ |
429 | ␉UInt32 jumpaddr;␊ |
430 | ␊ |
431 | ␉// Prelinked Extensions Patcher␊ |
432 | ␉if (KernelBooter_kexts)␊ |
433 | ␉{␊ |
434 | ␉␉patch_BooterExtensions_32(kernelData);␊ |
435 | ␉}␊ |
436 | ␊ |
437 | ␉// Lapic Error␊ |
438 | ␉if (KernelLapicError && patch_lapic_init_32(kernelData))␊ |
439 | ␉{␊ |
440 | ␉␉verbose("\tLapic Error call removed.\n");␊ |
441 | ␉}␊ |
442 | ␊ |
443 | ␉if (KernelcpuFamily)␊ |
444 | ␉{␊ |
445 | ␉␉verbose("\t- Looking for _cpuid_set_info _panic ...\n");␊ |
446 | ␉␉// _cpuid_set_info _panic address␊ |
447 | ␉␉for (i = 0; i < 0x1000000; i++)␊ |
448 | ␉␉{␊ |
449 | ␉␉␉if (bytes[i] == 0xC7␊ |
450 | ␉␉␉␉&& bytes[i + 1] == 0x05␊ |
451 | ␉␉␉␉&& bytes[i + 6] == 0x07␊ |
452 | ␉␉␉␉&& bytes[i + 7] == 0x00␊ |
453 | ␉␉␉␉&& bytes[i + 8] == 0x00␊ |
454 | ␉␉␉␉&& bytes[i + 9] == 0x00␊ |
455 | ␉␉␉␉&& bytes[i + 10] == 0xC7␊ |
456 | ␉␉␉␉&& bytes[i + 11] == 0x05␊ |
457 | ␉␉␉␉&& bytes[i - 5] == 0xE8)␊ |
458 | ␉␉␉{␊ |
459 | ␉␉␉␉patchLocation = i-5;␊ |
460 | ␉␉␉␉verbose("\tFound _cpuid_set_info _panic address at 0x%08X\n", (unsigned int)patchLocation);␊ |
461 | ␉␉␉␉break;␊ |
462 | ␉␉␉}␊ |
463 | ␉␉}␊ |
464 | ␊ |
465 | ␉␉if (!patchLocation)␊ |
466 | ␉␉{␊ |
467 | ␉␉␉verbose("\tCan't find _cpuid_set_info _panic address, patch kernel abort.\n");␊ |
468 | ␉␉␉return;␊ |
469 | ␉␉}␊ |
470 | ␊ |
471 | ␉␉// this for 10.6.0 and 10.6.1 kernel and remove tsc.c unknow cpufamily panic␊ |
472 | ␉␉// c70424540e5900␊ |
473 | ␉␉// find _tsc_init panic address␊ |
474 | ␉␉for (i = 0; i < 0x1000000; i++)␊ |
475 | ␉␉{␊ |
476 | ␉␉␉// _cpuid_set_info _panic address␊ |
477 | ␉␉␉if (bytes[i] == 0xC7␊ |
478 | ␉␉␉␉&& bytes[i + 1] == 0x04␊ |
479 | ␉␉␉␉&& bytes[i + 2] == 0x24␊ |
480 | ␉␉␉␉&& bytes[i + 3] == 0x54␊ |
481 | ␉␉␉␉&& bytes[i + 4] == 0x0E␊ |
482 | ␉␉␉␉&& bytes[i + 5] == 0x59␊ |
483 | ␉␉␉␉&& bytes[i + 6] == 0x00)␊ |
484 | ␉␉␉{␊ |
485 | ␉␉␉␉patchLocation1 = i+7;␊ |
486 | ␉␉␉␉verbose("\tFound _tsc_init _panic address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
487 | ␉␉␉␉break;␊ |
488 | ␉␉␉}␊ |
489 | ␉␉}␊ |
490 | ␊ |
491 | ␉␉// found _tsc_init panic addres and patch it␊ |
492 | ␉␉if (patchLocation1)␊ |
493 | ␉␉{␊ |
494 | ␉␉␉bytes[patchLocation1 + 0] = 0x90;␊ |
495 | ␉␉␉bytes[patchLocation1 + 1] = 0x90;␊ |
496 | ␉␉␉bytes[patchLocation1 + 2] = 0x90;␊ |
497 | ␉␉␉bytes[patchLocation1 + 3] = 0x90;␊ |
498 | ␉␉␉bytes[patchLocation1 + 4] = 0x90;␊ |
499 | ␉␉}␊ |
500 | ␉␉// end tsc.c panic␊ |
501 | ␊ |
502 | ␉␉//first move panic code total 5 bytes, if patch cpuid fail still can boot with kernel␊ |
503 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
504 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
505 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
506 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
507 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
508 | ␊ |
509 | ␉␉jumpaddr = patchLocation;␊ |
510 | ␊ |
511 | ␉␉for (i = 0 ;i < 500; i++)␊ |
512 | ␉␉{␊ |
513 | ␉␉␉if (bytes[jumpaddr-i-3] == 0x85␊ |
514 | ␉␉␉␉&& bytes[jumpaddr-i-2] == 0xC0␊ |
515 | ␉␉␉␉&& bytes[jumpaddr-i-1] == 0x75 )␊ |
516 | ␉␉␉{␊ |
517 | ␉␉␉␉jumpaddr -= i;␊ |
518 | ␉␉␉␉bytes[jumpaddr-1] = 0x77;␊ |
519 | ␉␉␉␉if(bytes[patchLocation - 17] == 0xC7)␊ |
520 | ␉␉␉␉{␊ |
521 | ␉␉␉␉␉bytes[jumpaddr] -=10;␊ |
522 | ␉␉␉␉}␊ |
523 | ␉␉␉␉break;␊ |
524 | ␉␉␉}␊ |
525 | ␉␉}␊ |
526 | ␊ |
527 | ␉␉if (jumpaddr == patchLocation)␊ |
528 | ␉␉{␊ |
529 | ␉␉␉verbose("\tCan't Found jumpaddr address.\n");␊ |
530 | ␉␉␉return; //can't find jump location␊ |
531 | ␉␉}␊ |
532 | ␉␉// patch info_p->cpufamily to CPUFAMILY_INTEL_MEROM␊ |
533 | ␊ |
534 | ␉␉if (bytes[patchLocation - 17] == 0xC7)␊ |
535 | ␉␉{␊ |
536 | ␉␉␉bytes[patchLocation - 11] = (CPUFAMILY_INTEL_MEROM & 0x000000FF) >> 0;␊ |
537 | ␉␉␉bytes[patchLocation - 10] = (CPUFAMILY_INTEL_MEROM & 0x0000FF00) >> 8;␊ |
538 | ␉␉␉bytes[patchLocation - 9] = (CPUFAMILY_INTEL_MEROM & 0x00FF0000) >> 16;␊ |
539 | ␉␉␉bytes[patchLocation - 8] = (CPUFAMILY_INTEL_MEROM & 0xFF000000) >> 24;␊ |
540 | ␉␉}␊ |
541 | ␊ |
542 | ␉␉//patch info->cpuid_cpufamily␊ |
543 | ␉␉bytes[patchLocation - 7] = 0xC7;␊ |
544 | ␉␉bytes[patchLocation - 6] = 0x05;␊ |
545 | ␉␉bytes[patchLocation - 5] = bytes[jumpaddr + 3];␊ |
546 | ␉␉bytes[patchLocation - 4] = bytes[jumpaddr + 4];␊ |
547 | ␉␉bytes[patchLocation - 3] = bytes[jumpaddr + 5];␊ |
548 | ␉␉bytes[patchLocation - 2] = bytes[jumpaddr + 6];␊ |
549 | ␊ |
550 | ␉␉bytes[patchLocation - 1] = CPUIDFAMILY_DEFAULT; //cpuid_family need alway set 0x06␊ |
551 | ␉␉bytes[patchLocation + 0] = CPUID_MODEL_MEROM; //cpuid_model set CPUID_MODEL_MEROM␊ |
552 | ␉␉bytes[patchLocation + 1] = 0x01; //cpuid_extmodel alway set 0x01␊ |
553 | ␉␉bytes[patchLocation + 2] = 0x00; //cpuid_extfamily alway set 0x00␊ |
554 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
555 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
556 | ␊ |
557 | ␉␉if (KernelSSE3 && ( LION ))␊ |
558 | ␉␉{␊ |
559 | ␉␉␉patch_SSE3_6((void *)bytes);␊ |
560 | ␉␉}␊ |
561 | ␊ |
562 | ␉␉if (KernelSSE3 && ( LEOPARD ))␊ |
563 | ␉␉{␊ |
564 | ␉␉␉patch_SSE3_5((void *)bytes);␊ |
565 | ␉␉}␊ |
566 | ␉}␊ |
567 | }␊ |
568 | ␊ |
569 | // ===================================␊ |
570 | // Power Managment␊ |
571 | bool patch_pm_init(void *kernelData) // KernelPatchPm␊ |
572 | {␊ |
573 | ␉UInt8 *Ptr = (UInt8 *)kernelData;␊ |
574 | ␉UInt8 *End = Ptr + 0x1000000;␊ |
575 | ␉if (Ptr == NULL)␊ |
576 | ␉{␊ |
577 | ␉␉return false;␊ |
578 | ␉}␊ |
579 | ␊ |
580 | ␉// Credits to RehabMan for the kernel patch information␊ |
581 | ␉// XCPM (Xnu CPU Power Management)␊ |
582 | ␉verbose("\t- Patching kernel power management...\n");␊ |
583 | ␉while (Ptr < End)␊ |
584 | ␉{␊ |
585 | ␉␉if (KERNEL_PATCH_SIGNATURE == (*((UInt64 *)Ptr)))␊ |
586 | ␉␉{␊ |
587 | ␉␉␉// Bytes 19,20 of KernelPm patch for kernel 13.x change between kernel versions, so we skip them in search&replace␊ |
588 | ␉␉␉if ((memcmp(Ptr + sizeof(UInt64), KernelPatchPmSrc + sizeof(UInt64), 18 * sizeof(UInt8) - sizeof(UInt64)) == 0) &&␊ |
589 | ␉␉␉␉(memcmp(Ptr + 20 * sizeof(UInt8), KernelPatchPmSrc + 20 * sizeof(UInt8), sizeof(KernelPatchPmSrc) - 20 * sizeof(UInt8)) == 0))␊ |
590 | ␉␉␉{␊ |
591 | ␉␉␉␉// Don't copy more than the source here!␊ |
592 | ␉␉␉␉memcpy(Ptr, KernelPatchPmRepl, 18 * sizeof(UInt8)); // Copy block of memory␊ |
593 | ␉␉␉␉memcpy(Ptr + 20 * sizeof(UInt8), KernelPatchPmRepl + 20 * sizeof(UInt8), sizeof(KernelPatchPmSrc) - 20 * sizeof(UInt8)); // Copy block of memory␊ |
594 | ␉␉␉␉verbose("\tKernel power management patch region 1 found and patched\n");␊ |
595 | ␉␉␉␉return true;␊ |
596 | ␉␉␉}␊ |
597 | ␉␉␉else if (memcmp(Ptr + sizeof(UInt64), KernelPatchPmSrc2 + sizeof(UInt64), sizeof(KernelPatchPmSrc2) - sizeof(UInt64)) == 0)␊ |
598 | ␉␉␉{␊ |
599 | ␉␉␉␉// Don't copy more than the source here!␊ |
600 | ␉␉␉␉memcpy(Ptr, KernelPatchPmRepl2, sizeof(KernelPatchPmSrc2)); // Copy block of memory␊ |
601 | ␉␉␉␉verbose("\tKernel power management patch region 2 found and patched\n");␊ |
602 | ␉␉␉␉return true;␊ |
603 | ␉␉␉}␊ |
604 | ␉␉}␊ |
605 | ␉␉// RehabMan: for 10.10 (data portion)␊ |
606 | ␉␉else if (0x00000002000000E2ULL == (*((UInt64 *)Ptr)))␊ |
607 | ␉␉{␊ |
608 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
609 | ␉␉␉verbose("\tKernel power management patch 10.1x(data1) found and patched\n");␊ |
610 | ␉␉}␊ |
611 | ␉␉else if (0x0000004C000000E2ULL == (*((UInt64 *)Ptr)))␊ |
612 | ␉␉{␊ |
613 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
614 | ␉␉␉verbose("\tKernel power management patch 10.1x(data2) found and patched\n");␊ |
615 | ␉␉}␊ |
616 | ␉␉else if (0x00000190000000E2ULL == (*((UInt64 *)Ptr)))␊ |
617 | ␉␉{␊ |
618 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
619 | ␉␉␉verbose("\tKernel power management patch 10.10(data3) found and patched\n");␊ |
620 | ␉␉␉return true;␊ |
621 | ␉␉}␊ |
622 | ␉␉// rehabman: change for 10.11.1 beta 15B38b␊ |
623 | ␉␉else if (0x00001390000000E2ULL == (*((UInt64 *)Ptr)))␊ |
624 | ␉␉{␊ |
625 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
626 | ␉␉␉verbose("\tKernel power management patch 10.11(data3) found and patched\n");␊ |
627 | ␉␉␉return true;␊ |
628 | ␉␉}␊ |
629 | ␉␉//rehabman: change for 10.11.6 security update 2017-003 15G1611␊ |
630 | ␉␉else if (0x00001b90000000E2ULL == (*((UInt64 *)Ptr)))␊ |
631 | ␉␉{␊ |
632 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
633 | ␉␉␉verbose("\tKernel power management patch 10.11.6(2017-003 15G1611)(data3) found and patched\n");␊ |
634 | ␉␉␉return true;␊ |
635 | ␉␉}␊ |
636 | ␉␉// sherlocks: change for 10.12 DP1␊ |
637 | ␉␉else if (0x00003390000000E2ULL == (*((UInt64 *)Ptr)))␊ |
638 | ␉␉{␊ |
639 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
640 | ␉␉␉verbose("\tKernel power management patch 10.12 DP1 found and patched\n");␊ |
641 | ␉␉␉return true;␊ |
642 | ␉␉}␊ |
643 | ␉␉// PMheart: change for 10.13 DP1 17A264c␊ |
644 | ␉␉else if (0x00004000000000E2ULL == (*((UInt64 *)Ptr)))␊ |
645 | ␉␉{␊ |
646 | ␉␉␉(*((UInt64 *)Ptr)) = 0x0000000000000000ULL;␊ |
647 | ␉␉␉verbose("\tKernel power management patch 10.13 DP1 found and patched\n");␊ |
648 | ␉␉␉return true;␊ |
649 | ␉␉}␊ |
650 | ␉␉Ptr += 16;␊ |
651 | ␉}␊ |
652 | ␉verbose("\tKernel power management patch region not found!\n");␊ |
653 | ␉return false;␊ |
654 | }␊ |
655 | ␊ |
656 | // ===================================␊ |
657 | // Lapic Error Panic 64␊ |
658 | bool patch_lapic_init_64(void *kernelData) // KernelLapicPatch_64␊ |
659 | {␊ |
660 | ␉// Credits to donovan6000 and Sherlocks for providing the lapic kernel patch source used to build this function␊ |
661 | ␊ |
662 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
663 | ␉UInt32 patchLocation = 0;␊ |
664 | ␉UInt32 patchLocation2 = 0;␊ |
665 | ␉UInt32 i;␊ |
666 | ␉UInt32 y;␊ |
667 | ␊ |
668 | ␉verbose("\t- Looking for Lapic panic call Start\n");␊ |
669 | ␊ |
670 | ␉for (i = 0; i < 0x1000000; i++)␊ |
671 | ␉{␊ |
672 | ␉␉if (KernelLapicError␊ |
673 | ␉␉␉&& (bytes[i + 0] == 0x65␊ |
674 | ␉␉␉&& bytes[i + 1] == 0x8B␊ |
675 | ␉␉␉&& bytes[i + 2] == 0x04␊ |
676 | ␉␉␉&& bytes[i + 3] == 0x25␊ |
677 | ␉␉␉&& bytes[i + 4] == 0x3C␊ |
678 | ␉␉␉&& bytes[i + 5] == 0x00␊ |
679 | ␉␉␉&& bytes[i + 6] == 0x00␊ |
680 | ␉␉␉&& bytes[i + 7] == 0x00␊ |
681 | ␉␉␉&& bytes[i + 45] == 0x65␊ |
682 | ␉␉␉&& bytes[i + 46] == 0x8B␊ |
683 | ␉␉␉&& bytes[i + 47] == 0x04␊ |
684 | ␉␉␉&& bytes[i + 48] == 0x25␊ |
685 | ␉␉␉&& bytes[i + 49] == 0x3C␊ |
686 | ␉␉␉&& bytes[i + 50] == 0x00␊ |
687 | ␉␉␉&& bytes[i + 51] == 0x00␊ |
688 | ␉␉␉&& bytes[i + 52] == 0x00))␊ |
689 | ␉␉{␊ |
690 | ␉␉␉patchLocation = i + 40;␊ |
691 | ␉␉␉verbose("\tFound Lapic panic (10.6) at 0x%08X\n", (unsigned int)patchLocation);␊ |
692 | ␉␉␉break;␊ |
693 | ␉␉}␊ |
694 | ␉␉else if (KernelLapicError␊ |
695 | ␉␉␉&& (bytes[i + 0] == 0x65␊ |
696 | ␉␉␉&& bytes[i + 1] == 0x8B␊ |
697 | ␉␉␉&& bytes[i + 2] == 0x04␊ |
698 | ␉␉␉&& bytes[i + 3] == 0x25␊ |
699 | ␉␉␉&& bytes[i + 4] == 0x14␊ |
700 | ␉␉␉&& bytes[i + 5] == 0x00␊ |
701 | ␉␉␉&& bytes[i + 6] == 0x00␊ |
702 | ␉␉␉&& bytes[i + 7] == 0x00␊ |
703 | ␉␉␉&& bytes[i + 35] == 0x65␊ |
704 | ␉␉␉&& bytes[i + 36] == 0x8B␊ |
705 | ␉␉␉&& bytes[i + 37] == 0x04␊ |
706 | ␉␉␉&& bytes[i + 38] == 0x25␊ |
707 | ␉␉␉&& bytes[i + 39] == 0x14␊ |
708 | ␉␉␉&& bytes[i + 40] == 0x00␊ |
709 | ␉␉␉&& bytes[i + 41] == 0x00␊ |
710 | ␉␉␉&& bytes[i + 42] == 0x00))␊ |
711 | ␉␉{␊ |
712 | ␉␉␉patchLocation = i + 30;␊ |
713 | ␉␉␉verbose("\tFound Lapic panic (10.7 - 10.8) at 0x%08X\n", (unsigned int)patchLocation);␊ |
714 | ␉␉␉break;␊ |
715 | ␉␉}␊ |
716 | ␉␉else if (KernelLapicError␊ |
717 | ␉␉␉&& (bytes[i + 0] == 0x65␊ |
718 | ␉␉␉&& bytes[i + 1] == 0x8B␊ |
719 | ␉␉␉&& bytes[i + 2] == 0x04␊ |
720 | ␉␉␉&& bytes[i + 3] == 0x25␊ |
721 | ␉␉␉&& bytes[i + 4] == 0x1C␊ |
722 | ␉␉␉&& bytes[i + 5] == 0x00␊ |
723 | ␉␉␉&& bytes[i + 6] == 0x00␊ |
724 | ␉␉␉&& bytes[i + 7] == 0x00␊ |
725 | ␉␉␉&& bytes[i + 36] == 0x65␊ |
726 | ␉␉␉&& bytes[i + 37] == 0x8B␊ |
727 | ␉␉␉&& bytes[i + 38] == 0x04␊ |
728 | ␉␉␉&& bytes[i + 39] == 0x25␊ |
729 | ␉␉␉&& bytes[i + 40] == 0x1C␊ |
730 | ␉␉␉&& bytes[i + 41] == 0x00␊ |
731 | ␉␉␉&& bytes[i + 42] == 0x00␊ |
732 | ␉␉␉&& bytes[i + 43] == 0x00))␊ |
733 | ␉␉{␊ |
734 | ␉␉␉patchLocation = i + 31;␊ |
735 | ␉␉␉verbose("\tFound Lapic panic (10.9) at 0x%08X\n", (unsigned int)patchLocation);␊ |
736 | ␉␉␉break;␊ |
737 | ␉␉}␊ |
738 | ␉ // 00 29 C7 78 XX 31 DB 8D 47 FA 83␊ |
739 | ␉␉else if (bytes[i+0] == 0x00 ␊ |
740 | ␉␉␉&& bytes[i+1] == 0x29 ␊ |
741 | ␉␉␉&& bytes[i+2] == 0xC7 ␊ |
742 | ␉␉␉&& bytes[i+3] == 0x78 ␊ |
743 | ␉ //(bytes[i+4] == 0x3F || bytes[i+4] == 0x4F) && // 3F:10.10-10.12/4F:10.13+␊ |
744 | ␉␉␉&& bytes[i+5] == 0x31␊ |
745 | ␉␉␉&& bytes[i+6] == 0xDB ␊ |
746 | ␉␉␉&& bytes[i+7] == 0x8D ␊ |
747 | ␉␉␉&& bytes[i+8] == 0x47 ␊ |
748 | ␉␉␉&& bytes[i+9] == 0xFA␊ |
749 | ␉␉␉&& bytes[i+10] == 0x83) {␊ |
750 | ␉ for (y = i; y < 0x1000000; y++) {␊ |
751 | ␉ // Lapic panic patch, by vit9696␊ |
752 | ␉ // mov eax, gs:1Ch␊ |
753 | ␉ // cmp eax, cs:_master_cpu␊ |
754 | ␉ // 65 8B 04 25 1C 00 00 00 3B 05 XX XX XX 00␊ |
755 | ␉ if (bytes[y+0] == 0x65 ␊ |
756 | ␉ ␉&& bytes[y+1] == 0x8B ␊ |
757 | ␉ ␉&& bytes[y+2] == 0x04 ␊ |
758 | ␉ ␉&& bytes[y+3] == 0x25 ␊ |
759 | ␉ ␉&& bytes[y+4] == 0x1C ␊ |
760 | ␉ ␉&& bytes[y+5] == 0x00 ␊ |
761 | ␉ ␉&& bytes[y+6] == 0x00 ␊ |
762 | ␉ ␉&& bytes[y+7] == 0x00 ␊ |
763 | ␉ ␉&& bytes[y+8] == 0x3B ␊ |
764 | ␉ ␉&& bytes[y+9] == 0x05 ␊ |
765 | ␉ ␉&& bytes[y+13] == 0x00) {␊ |
766 | ␉ ␉patchLocation = y;␊ |
767 | ␉␉ verbose("\tFound Lapic panic (10.10 - recent macOS) at 0x%08X\n", (unsigned int)patchLocation);␊ |
768 | ␉␉ break;␊ |
769 | ␉␉ }␊ |
770 | ␉ }␊ |
771 | ␉ break;␊ |
772 | ␉ }␊ |
773 | ␉}␊ |
774 | ␊ |
775 | ␉if (!patchLocation)␊ |
776 | ␉{␊ |
777 | ␉␉verbose("\tCan't find Lapic panic, kernel patch aborted.\n");␊ |
778 | ␉␉return false;␊ |
779 | ␉}␊ |
780 | ␊ |
781 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
782 | ␊ |
783 | ␉if (bytes[patchLocation + 0] == 0x90␊ |
784 | ␉␉&& bytes[patchLocation + 1] == 0x90␊ |
785 | ␉␉&& bytes[patchLocation + 2] == 0x90␊ |
786 | ␉␉&& bytes[patchLocation + 3] == 0x90␊ |
787 | ␉␉&& bytes[patchLocation + 4] == 0x90)␊ |
788 | ␉{␊ |
789 | ␉␉verbose("\tLapic panic already patched, kernel file (10.6 - 10.9) manually patched?\n");␊ |
790 | ␉␉return false;␊ |
791 | ␉} else if (bytes[patchLocation + 0] == 0x31 ␊ |
792 | ␉␉ && bytes[patchLocation + 1] == 0xC0 ␊ |
793 | ␉␉ && bytes[patchLocation + 2] == 0x90 ␊ |
794 | && bytes[patchLocation + 3] == 0x90) ␊ |
795 | ␉{␊ |
796 | ␉␉verbose("\tLapic panic already patched, kernel file (10.10 - recent macOS) manually patched?\n");␊ |
797 | ␉␉return false;␊ |
798 | ␉} else {␊ |
799 | if (bytes[patchLocation + 8] == 0x3B ␊ |
800 | ␉&& bytes[patchLocation + 9] == 0x05 ␊ |
801 | ␉&& bytes[patchLocation + 13] == 0x00) {␊ |
802 | // 65 8B 04 25 1C 00 00 00 3B XX XX XX XX 00␊ |
803 | // 31 C0 90 90 90 90 90 90 90 90 90 90 90 90␊ |
804 | verbose("\tPatched Lapic panic (10.10 - recent macOS)\n");␊ |
805 | bytes[patchLocation + 0] = 0x31;␊ |
806 | bytes[patchLocation + 1] = 0xC0;␊ |
807 | for (i = 2; i < 14; i++) {␊ |
808 | bytes[patchLocation + i] = 0x90;␊ |
809 | }␊ |
810 | ␊ |
811 | for (i = 0; i < 0x1000000; i++) {␊ |
812 | // 00 29 C7 78 XX 31 DB 8D 47 FA 83␊ |
813 | if (bytes[i+0] == 0x00 ␊ |
814 | ␉&& bytes[i+1] == 0x29 ␊ |
815 | ␉&& bytes[i+2] == 0xC7 ␊ |
816 | ␉&& bytes[i+3] == 0x78 ␊ |
817 | //(bytes[i+4] == 0x3F || bytes[i+4] == 0x4F) && // 3F:10.10-10.12/4F:10.13+␊ |
818 | && bytes[i+5] == 0x31 ␊ |
819 | && bytes[i+6] == 0xDB ␊ |
820 | && bytes[i+7] == 0x8D ␊ |
821 | && bytes[i+8] == 0x47 ␊ |
822 | && bytes[i+9] == 0xFA ␊ |
823 | && bytes[i+10] == 0x83) {␊ |
824 | for (y = i; y < 0x1000000; y++) {␊ |
825 | // Lapic panic master patch, by vit9696␊ |
826 | // cmp cs:_debug_boot_arg, 0␊ |
827 | // E8 XX XX FF FF 83 XX XX XX XX 00 00␊ |
828 | if (bytes[y+0] == 0xE8 ␊ |
829 | ␉&& bytes[y+3] == 0xFF ␊ |
830 | ␉&& bytes[y+4] == 0xFF ␊ |
831 | ␉&& bytes[y+5] == 0x83 ␊ |
832 | ␉&& bytes[y+10] == 0x00 ␊ |
833 | ␉&& bytes[y+11] == 0x00) {␊ |
834 | patchLocation2 = y;␊ |
835 | ␉␉ verbose("\tFound Lapic panic master (10.10 - recent macOS) at 0x%08X\n", (unsigned int)patchLocation2);␊ |
836 | break;␊ |
837 | }␊ |
838 | }␊ |
839 | break;␊ |
840 | }␊ |
841 | }␊ |
842 | ␊ |
843 | if (!patchLocation2) {␊ |
844 | verbose("\tCan't find Lapic panic master (10.10 - recent macOS), kernel patch aborted.\n");␊ |
845 | return false;␊ |
846 | }␊ |
847 | ␊ |
848 | // Already patched? May be running a non-vanilla kernel already?␊ |
849 | if (bytes[patchLocation2 + 5] == 0x31 ␊ |
850 | ␉ && bytes[patchLocation2 + 6] == 0xC0) {␊ |
851 | verbose("\tLapic panic master already patched, kernel file (10.6 - 10.9) manually patched?\n");␊ |
852 | return false;␊ |
853 | } else {␊ |
854 | verbose("\tPatched Lapic panic master (10.10 - recent macOS)\n");␊ |
855 | // E8 XX XX FF FF 83 XX XX XX XX 00 00␊ |
856 | // E8 XX XX FF FF 31 C0 90 90 90 90 90␊ |
857 | bytes[patchLocation2 + 5] = 0x31;␊ |
858 | bytes[patchLocation2 + 6] = 0xC0;␊ |
859 | for (i = 7; i < 12; i++) {␊ |
860 | bytes[patchLocation2 + i] = 0x90;␊ |
861 | }␊ |
862 | }␊ |
863 | } else {␊ |
864 | verbose("\tPatched Lapic panic (10.6 - 10.9)\n");␊ |
865 | for (i = 0; i < 5; i++) {␊ |
866 | bytes[patchLocation + i] = 0x90;␊ |
867 | }␊ |
868 | }␊ |
869 | }␊ |
870 | ␉return true;␊ |
871 | }␊ |
872 | ␊ |
873 | // ===================================␊ |
874 | // Lapic Error Panic 32␊ |
875 | bool patch_lapic_init_32(void *kernelData) // KernelLapicPatch_32␊ |
876 | {␊ |
877 | ␉// Credits to donovan6000 and sherlocks for providing the lapic kernel patch source used to build this function␊ |
878 | ␊ |
879 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
880 | ␉UInt32 patchLocation=0;␊ |
881 | ␉UInt32 i;␊ |
882 | ␊ |
883 | ␉verbose("\t- Looking for Lapic panic call Start\n");␊ |
884 | ␊ |
885 | ␉for (i = 0; i < 0x1000000; i++)␊ |
886 | ␉{␊ |
887 | ␉␉if (bytes[i+0] == 0x65␊ |
888 | ␉␉␉&& bytes[i+1] == 0xA1␊ |
889 | ␉␉␉&& bytes[i+2] == 0x0C␊ |
890 | ␉␉␉&& bytes[i+3] == 0x00␊ |
891 | ␉␉␉&& bytes[i+4] == 0x00␊ |
892 | ␉␉␉&& bytes[i+5] == 0x00␊ |
893 | ␉␉␉&& bytes[i+30] == 0x65␊ |
894 | ␉␉␉&& bytes[i+31] == 0xA1␊ |
895 | ␉␉␉&& bytes[i+32] == 0x0C␊ |
896 | ␉␉␉&& bytes[i+33] == 0x00␊ |
897 | ␉␉␉&& bytes[i+34] == 0x00␊ |
898 | ␉␉␉&& bytes[i+35] == 0x00)␊ |
899 | ␉␉{␊ |
900 | ␉␉␉patchLocation = i + 25;␊ |
901 | ␉␉␉verbose("\tFound Lapic panic at 0x%08X\n", (unsigned int)patchLocation);␊ |
902 | ␉␉␉break;␊ |
903 | ␉␉}␊ |
904 | ␉}␊ |
905 | ␊ |
906 | ␉if (!patchLocation)␊ |
907 | ␉{␊ |
908 | ␉␉verbose("\tCan't find Lapic panic, kernel patch aborted.\n");␊ |
909 | ␉␉return false;␊ |
910 | ␉}␊ |
911 | ␊ |
912 | ␉// Already patched? May be running a non-vanilla kernel already?␊ |
913 | ␊ |
914 | ␉if (bytes[patchLocation + 0] == 0x90␊ |
915 | ␉␉&& bytes[patchLocation + 1] == 0x90␊ |
916 | ␉␉&& bytes[patchLocation + 2] == 0x90␊ |
917 | ␉␉&& bytes[patchLocation + 3] == 0x90␊ |
918 | ␉␉&& bytes[patchLocation + 4] == 0x90)␊ |
919 | ␉{␊ |
920 | ␉␉verbose("\tLapic panic already patched, kernel file manually patched?\n");␊ |
921 | ␉␉return false;␊ |
922 | ␉}␊ |
923 | ␉else␊ |
924 | ␉{␊ |
925 | ␉␉bytes[patchLocation + 0] = 0x90;␊ |
926 | ␉␉bytes[patchLocation + 1] = 0x90;␊ |
927 | ␉␉bytes[patchLocation + 2] = 0x90;␊ |
928 | ␉␉bytes[patchLocation + 3] = 0x90;␊ |
929 | ␉␉bytes[patchLocation + 4] = 0x90;␊ |
930 | ␉}␊ |
931 | ␉return true;␊ |
932 | }␊ |
933 | ␊ |
934 | // ===================================␊ |
935 | // Haswell-E Patch␊ |
936 | bool patch_haswell_E_init(void *kernelData) // KernelHaswellEPatch␊ |
937 | {␊ |
938 | ␉// Credit to stinga11 for the patches used below␊ |
939 | ␉// Based on Pike R. Alpha's Haswell patch for Mavericks␊ |
940 | ␊ |
941 | ␉UInt8␉*Bytes;␊ |
942 | ␉UInt32␉Index;␊ |
943 | ␉bool␉PatchApplied;␊ |
944 | ␊ |
945 | ␉verbose("\t- Searching for Haswell-E patch pattern\n");␊ |
946 | ␊ |
947 | ␉Bytes = (UInt8 *)kernelData;␊ |
948 | ␉PatchApplied = false;␊ |
949 | ␊ |
950 | ␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
951 | ␉{␊ |
952 | ␉␉// sudo perl -pi -e 's|\x74\x11\x83\xF8\x3C|\x74\x11\x83\xF8\x3F|g' /System/Library/Kernels/kernel␊ |
953 | ␉␉if (Bytes[Index] == 0x74␊ |
954 | ␉␉␉&& Bytes[Index + 1] == 0x11␊ |
955 | ␉␉␉&& Bytes[Index + 2] == 0x83␊ |
956 | ␉␉␉&& Bytes[Index + 3] == 0xF8␊ |
957 | ␉␉␉&& Bytes[Index + 4] == 0x3C)␊ |
958 | ␉␉{␊ |
959 | ␉␉␉Bytes[Index + 4] = 0x3F;␊ |
960 | ␊ |
961 | ␉␉␉verbose("\tFound Haswell-E pattern #1; patched.\n");␊ |
962 | ␊ |
963 | ␉␉␉if (PatchApplied)␊ |
964 | ␉␉␉{␊ |
965 | ␉␉␉␉break;␊ |
966 | ␉␉␉}␊ |
967 | ␊ |
968 | ␉␉␉PatchApplied = true;␊ |
969 | ␉␉}␊ |
970 | ␊ |
971 | ␉␉// sudo perl -pi -e 's|\xEB\x0A\x83\xF8\x3A|\xEB\x0A\x83\xF8\x3F|g' /System/Library/Kernels/kernel␊ |
972 | ␉␉if (Bytes[Index] == 0xEB␊ |
973 | ␉␉␉&& Bytes[Index + 1] == 0x0A␊ |
974 | ␉␉␉&& Bytes[Index + 2] == 0x83␊ |
975 | ␉␉␉&& Bytes[Index + 3] == 0xF8␊ |
976 | ␉␉␉&& Bytes[Index + 4] == 0x3A)␊ |
977 | ␉␉{␊ |
978 | ␉␉␉Bytes[Index + 4] = 0x3F;␊ |
979 | ␊ |
980 | ␉␉␉verbose("\tFound Haswell-E pattern #2; patched.\n");␊ |
981 | ␊ |
982 | ␉␉␉if (PatchApplied)␊ |
983 | ␉␉␉{␊ |
984 | ␉␉␉␉break;␊ |
985 | ␉␉␉}␊ |
986 | ␊ |
987 | ␉␉␉PatchApplied = true;␊ |
988 | ␉␉}␊ |
989 | ␉}␊ |
990 | ␊ |
991 | ␉if (!PatchApplied)␊ |
992 | ␉{␊ |
993 | ␉␉verbose("\tCan't find Haswell-E patch pattern, patch not applied.\n");␊ |
994 | ␉}␊ |
995 | ␊ |
996 | ␉return PatchApplied;␊ |
997 | }␊ |
998 | ␊ |
999 | // ===================================␊ |
1000 | // Haswell-ULT Patch␊ |
1001 | bool patch_haswell_ULT_init(void *kernelData) // Fake CPUFAMILY To IVYBRIDGE Patch␊ |
1002 | {␊ |
1003 | ␉// Credit to Tora Chi Yo for the patches used below␊ |
1004 | ␉// http://www.insanelymac.com/forum/topic/307721-haswell-ult-kernel-patch-for-yosemite-mavericks␊ |
1005 | ␊ |
1006 | ␉UInt8␉*Bytes;␊ |
1007 | ␉UInt32␉Index;␊ |
1008 | ␉bool␉PatchApplied;␊ |
1009 | ␊ |
1010 | ␉verbose("\t- Searching for Haswell-ULT patch pattern\n");␊ |
1011 | ␊ |
1012 | ␉Bytes = (UInt8 *)kernelData;␊ |
1013 | ␉PatchApplied = false;␊ |
1014 | ␊ |
1015 | ␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1016 | ␉{␊ |
1017 | ␉␉// sudo perl -pi -e 's|\xbb\xdc\x82\xb2\xdc|\xbb\x35\xe8\x65\x1f|g' /System/Library/Kernels/kernel␊ |
1018 | ␉␉if (Bytes[Index] == 0xBB␊ |
1019 | ␉␉␉&& Bytes[Index + 1] == 0xDC␊ |
1020 | ␉␉␉&& Bytes[Index + 2] == 0x82␊ |
1021 | ␉␉␉&& Bytes[Index + 3] == 0xB2␊ |
1022 | ␉␉␉&& Bytes[Index + 4] == 0xdc)␊ |
1023 | ␉␉{␊ |
1024 | ␉␉␉Bytes[Index + 1] = 0x35;␊ |
1025 | ␉␉␉Bytes[Index + 2] = 0xE8;␊ |
1026 | ␉␉␉Bytes[Index + 3] = 0x65;␊ |
1027 | ␉␉␉Bytes[Index + 4] = 0x1F;␊ |
1028 | ␊ |
1029 | ␉␉␉verbose("\tFound Haswell-ULT pattern #1; patched.\n");␊ |
1030 | ␊ |
1031 | ␉␉␉if (PatchApplied)␊ |
1032 | ␉␉␉{␊ |
1033 | ␉␉␉␉break;␊ |
1034 | ␉␉␉}␊ |
1035 | ␊ |
1036 | ␉␉␉PatchApplied = true;␊ |
1037 | ␉␉}␊ |
1038 | ␉}␊ |
1039 | ␊ |
1040 | ␉if (!PatchApplied)␊ |
1041 | ␉{␊ |
1042 | ␉␉verbose("\tCan't find Haswell-ULT patch pattern, patch not applied.\n");␊ |
1043 | ␉}␊ |
1044 | ␊ |
1045 | ␉return PatchApplied;␊ |
1046 | }␊ |
1047 | ␊ |
1048 | // ===================================␊ |
1049 | // Custom Kext injection from Extra/Extensions folder␊ |
1050 | void patch_BooterExtensions_32(void *kernelData)␊ |
1051 | {␊ |
1052 | ␉// KernelBooterExtensionsPatch to load extra kexts besides kernelcache␊ |
1053 | ␉UInt8 *Bytes;␊ |
1054 | ␉UInt32 Index;␊ |
1055 | ␉bool PatchApplied;␊ |
1056 | ␉int count = 0;␊ |
1057 | ␊ |
1058 | ␉verbose("\t- Searching for booter extensions pattern:\n");␊ |
1059 | ␊ |
1060 | ␉Bytes = (UInt8 *)kernelData;␊ |
1061 | ␉PatchApplied = false;␊ |
1062 | ␊ |
1063 | ␉if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))␊ |
1064 | ␉{␊ |
1065 | ␉//UInt8 KBELionSearch_i386[] = { 0xE8, 0xAA, 0xFB, 0xFF, 0xFF, 0xEB, 0x08, 0x89, 0x34, 0x24 };␊ |
1066 | ␉//UInt8 KBELionReplace_i386[] = { 0xE8, 0xAA, 0xFB, 0xFF, 0xFF, 0x90, 0x90, 0x89, 0x34, 0x24 };␊ |
1067 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1068 | ␉␉{␊ |
1069 | ␉␉␉if (Bytes[Index] == 0xE8␊ |
1070 | ␉␉␉␉&& Bytes[Index + 1] == 0xAA␊ |
1071 | ␉␉␉␉&& Bytes[Index + 2] == 0xFB␊ |
1072 | ␉␉␉␉&& Bytes[Index + 3] == 0xFF␊ |
1073 | ␉␉␉␉&& Bytes[Index + 4] == 0xFF␊ |
1074 | ␉␉␉␉&& Bytes[Index + 5] == 0xEB␊ |
1075 | ␉␉␉␉&& Bytes[Index + 6] == 0x08␊ |
1076 | ␉␉␉␉&& Bytes[Index + 7] == 0x89␊ |
1077 | ␉␉␉␉&& Bytes[Index + 8] == 0x34␊ |
1078 | ␉␉␉␉&& Bytes[Index + 9] == 0x24)␊ |
1079 | ␉␉␉{␊ |
1080 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1081 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1082 | ␉␉␉␉count ++;␊ |
1083 | ␊ |
1084 | ␉␉␉␉verbose("\tFound Lion pattern: patched!\n");␊ |
1085 | ␊ |
1086 | ␉␉␉␉if (PatchApplied)␊ |
1087 | ␉␉␉␉{␊ |
1088 | ␉␉␉␉␉break;␊ |
1089 | ␉␉␉␉}␊ |
1090 | ␊ |
1091 | ␉␉␉␉PatchApplied = true;␊ |
1092 | ␉␉␉}␊ |
1093 | ␉␉}␊ |
1094 | ␉}␊ |
1095 | ␊ |
1096 | ␉/* UNDER REVIEW, crazybirdy test this patch on Snow leopard:␊ |
1097 | ␉ 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!␊ |
1098 | ␉ 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␊ |
1099 | ␊ |
1100 | ␉ need to re-try later.␊ |
1101 | ␉ */␊ |
1102 | ␉if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))␊ |
1103 | ␉{␊ |
1104 | ␉␉//UInt8 KBESnowSearch_i386[] = { 0xE8, 0xED, 0xF9, 0xFF, 0xFF, 0xEB, 0x08, 0x89, 0x1C, 0x24 };␊ |
1105 | ␉␉//UInt8 KBESnowReplace_i386[] = { 0xE8, 0xED, 0xF9, 0xFF, 0xFF, 0x90, 0x90, 0x89, 0x1C, 0x24 };␊ |
1106 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1107 | ␉␉{␊ |
1108 | ␉␉␉if (Bytes[Index] == 0xE8␊ |
1109 | ␉␉␉␉&& Bytes[Index + 1] == 0xED␊ |
1110 | ␉␉␉␉&& Bytes[Index + 2] == 0xF9␊ |
1111 | ␉␉␉␉&& Bytes[Index + 3] == 0xFF␊ |
1112 | ␉␉␉␉&& Bytes[Index + 4] == 0xFF␊ |
1113 | ␉␉␉␉&& Bytes[Index + 5] == 0xEB␊ |
1114 | ␉␉␉␉&& Bytes[Index + 6] == 0x08␊ |
1115 | ␉␉␉␉&& Bytes[Index + 7] == 0x89␊ |
1116 | ␉␉␉␉&& Bytes[Index + 8] == 0x1C␊ |
1117 | ␉␉␉␉&& Bytes[Index + 9] == 0x24)␊ |
1118 | ␉␉␉{␊ |
1119 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1120 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1121 | ␉␉␉␉count ++;␊ |
1122 | ␊ |
1123 | ␉␉␉␉verbose("\tFound Snow Leopard pattern: patched!\n");␊ |
1124 | ␊ |
1125 | ␉␉␉␉if (PatchApplied)␊ |
1126 | ␉␉␉␉{␊ |
1127 | ␉␉␉␉␉break;␊ |
1128 | ␉␉␉␉}␊ |
1129 | ␊ |
1130 | ␉␉␉␉PatchApplied = true;␊ |
1131 | ␉␉␉}␊ |
1132 | ␉␉}␊ |
1133 | ␉}␊ |
1134 | ␊ |
1135 | ␉if (!PatchApplied)␊ |
1136 | ␉{␊ |
1137 | ␉␉verbose("\tCan't find Booter Extensions patch location.\n");␊ |
1138 | ␉}␊ |
1139 | ␉else␊ |
1140 | ␉{␊ |
1141 | ␉␉verbose("\t%d substitution(s) made.\n", count);␊ |
1142 | ␉}␊ |
1143 | }␊ |
1144 | ␊ |
1145 | void patch_BooterExtensions_64(void *kernelData)␊ |
1146 | {␊ |
1147 | ␉// Port from Clover 4979␊ |
1148 | ␉UInt32 i;␊ |
1149 | ␉UInt32 y;␊ |
1150 | ␉UInt32 patchLocation = 0;␊ |
1151 | ␉UInt32 patchLocation2 = 0;␊ |
1152 | ␉// Port from Clover 4979␊ |
1153 | ␊ |
1154 | ␉// KernelBooterExtensionsPatch to load extra kexts besides kernelcache␊ |
1155 | ␉UInt8 *Bytes;␊ |
1156 | ␉UInt32 Index;␊ |
1157 | ␉bool PatchApplied; // does nothing␊ |
1158 | ␉int count = 0;␊ |
1159 | ␊ |
1160 | ␉verbose("\t- Searching for booter extensions pattern:\n");␊ |
1161 | ␊ |
1162 | ␉Bytes = (UInt8 *)kernelData;␊ |
1163 | ␉PatchApplied = false;␊ |
1164 | ␊ |
1165 | ␉// Port from Clover 4979 start.␊ |
1166 | ␉// EXT - 10.8 - recent macOS␊ |
1167 | ␉if (kernelOSVer >= MacOSVer2Int("10.8"))␊ |
1168 | ␉{␊ |
1169 | // EXT - load extra kexts besides kernelcache.␊ |
1170 | for (i = 0; i < 0x1000000; i++) {␊ |
1171 | // 01 00 31 FF BE 14 00 05␊ |
1172 | if (Bytes[i+0] == 0x01 && Bytes[i+1] == 0x00 && Bytes[i+2] == 0x31 &&␊ |
1173 | Bytes[i+3] == 0xFF && Bytes[i+4] == 0xBE && Bytes[i+5] == 0x14 &&␊ |
1174 | Bytes[i+6] == 0x00 && Bytes[i+7] == 0x05) {␊ |
1175 | for (y = i; y < 0x1000000; y++) {␊ |
1176 | // E8 XX 00 00 00 EB XX XX␊ |
1177 | if (Bytes[y+0] == 0xE8 && Bytes[y+2] == 0x00 && Bytes[y+3] == 0x00 &&␊ |
1178 | Bytes[y+4] == 0x00 && Bytes[y+5] == 0xEB) {␊ |
1179 | //(Bytes[y+7] == 0x48 || Bytes[y+7] == 0xE8)) { // 48:10.8-10.9/E8:10.10+␊ |
1180 | patchLocation = y;␊ |
1181 | break;␊ |
1182 | }␊ |
1183 | }␊ |
1184 | break;␊ |
1185 | }␊ |
1186 | } ␊ |
1187 | if (patchLocation) {␊ |
1188 | verbose("\tFound EXT pattern (10.8 - recent macOS): patched!\n");␊ |
1189 | for (i = 5; i < 7; i++) {␊ |
1190 | // E8 XX 00 00 00 EB XX␊ |
1191 | // E8 XX 00 00 00 90 90␊ |
1192 | Bytes[patchLocation + i] = 0x90;␊ |
1193 | }␊ |
1194 | count++;␊ |
1195 | PatchApplied = true;␊ |
1196 | }␊ |
1197 | ␉}␊ |
1198 | ␊ |
1199 | ␉// SIP - 10.11 - recent macOS␊ |
1200 | ␉if (kernelOSVer >= MacOSVer2Int("10.11"))␊ |
1201 | ␉{␊ |
1202 | ␉ // SIP - bypass kext check by System Integrity Protection.␊ |
1203 | for (i = 0; i < 0x1000000; ++i) {␊ |
1204 | // 45 31 FF 41 XX 01 00 00 DC 48␊ |
1205 | if (Bytes[i + 0] == 0x45 && Bytes[i + 1] == 0x31 && Bytes[i + 3] == 0x41 &&␊ |
1206 | //(Bytes[i + 4] == 0xBF || Bytes[i + 4] == 0xBE) && // BF:10.11/BE:10.12+␊ |
1207 | Bytes[i + 5] == 0x01 && Bytes[i + 6] == 0x00 && Bytes[i + 7] == 0x00 &&␊ |
1208 | Bytes[i + 8] == 0xDC && Bytes[i + 9] == 0x48) {␊ |
1209 | for (y = i; y < 0x1000000; ++y) {␊ |
1210 | // 48 85 XX 74 XX 48 XX XX 48␊ |
1211 | if (Bytes[y+0] == 0x48 && Bytes[y+1] == 0x85 && Bytes[y+3] == 0x74 &&␊ |
1212 | Bytes[y+5] == 0x48 && Bytes[y+8] == 0x48) {␊ |
1213 | patchLocation2 = y;␊ |
1214 | break;␊ |
1215 | // 00 85 C0 0F 84 XX 00 00 00 49␊ |
1216 | } else if (Bytes[y+0] == 0x00 && Bytes[y+1] == 0x85 && Bytes[y+2] == 0xC0 &&␊ |
1217 | Bytes[y+3] == 0x0F && Bytes[y+4] == 0x84 && Bytes[y+9] == 0x49) {␊ |
1218 | patchLocation2 = y;␊ |
1219 | break;␊ |
1220 | }␊ |
1221 | }␊ |
1222 | }␊ |
1223 | }␊ |
1224 | if (patchLocation2) {␊ |
1225 | if (Bytes[patchLocation2 + 0] == 0x48 && Bytes[patchLocation2 + 1] == 0x85) {␊ |
1226 | Bytes[patchLocation2 + 3] = 0xEB;␊ |
1227 | ␉␉ verbose("\tFound SIP pattern (10.11 - 10.14): patched!\n");␊ |
1228 | if (Bytes[patchLocation2 + 4] == 0x6C) {␊ |
1229 | // 48 85 XX 74 6C 48 XX XX 48␊ |
1230 | // 48 85 XX EB 15 48 XX XX 48␊ |
1231 | Bytes[patchLocation2 + 4] = 0x15; // 10.14.4-10.14.6␊ |
1232 | } else {␊ |
1233 | // 48 85 XX 74 XX 48 XX XX 48␊ |
1234 | // 48 85 XX EB 12 48 XX XX 48␊ |
1235 | Bytes[patchLocation2 + 4] = 0x12; // 10.11-10.14.3␊ |
1236 | }␊ |
1237 | count++;␊ |
1238 | PatchApplied = true;␊ |
1239 | // PMheart␊ |
1240 | } else if (Bytes[patchLocation2 + 0] == 0x00 && Bytes[patchLocation2 + 1] == 0x85) {␊ |
1241 | ␉␉ verbose("\tFound SIP pattern (10.15 - recent macOS): patched!\n");␊ |
1242 | for (i = 3; i < 9; i++) {␊ |
1243 | // 00 85 C0 0F 84 XX 00 00 00 49␊ |
1244 | // 00 85 C0 90 90 90 90 90 90 49␊ |
1245 | Bytes[patchLocation2 + i] = 0x90;␊ |
1246 | }␊ |
1247 | count++;␊ |
1248 | PatchApplied = true;␊ |
1249 | }␊ |
1250 | }␊ |
1251 | }␊ |
1252 | // Port from Clover 4979 end.␊ |
1253 | ␊ |
1254 | ␉// Lion 64␊ |
1255 | ␉if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))␊ |
1256 | ␉{␊ |
1257 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1258 | ␉␉{␊ |
1259 | ␉␉␉if (Bytes[Index] == 0xE8␊ |
1260 | ␉␉␉␉&& Bytes[Index + 1] == 0x0C␊ |
1261 | ␉␉␉␉&& Bytes[Index + 2] == 0xFD␊ |
1262 | ␉␉␉␉&& Bytes[Index + 3] == 0xFF␊ |
1263 | ␉␉␉␉&& Bytes[Index + 4] == 0xFF␊ |
1264 | ␉␉␉␉&& Bytes[Index + 5] == 0xEB␊ |
1265 | ␉␉␉␉&& Bytes[Index + 6] == 0x08␊ |
1266 | ␉␉␉␉&& Bytes[Index + 7] == 0x48␊ |
1267 | ␉␉␉␉&& Bytes[Index + 8] == 0x89␊ |
1268 | ␉␉␉␉&& Bytes[Index + 9] == 0xDF)␊ |
1269 | ␉␉␉{␊ |
1270 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1271 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1272 | ␉␉␉␉count++;␊ |
1273 | ␊ |
1274 | ␉␉␉␉verbose("\tFound Lion EXT pattern: patched!\n");␊ |
1275 | ␊ |
1276 | ␉␉␉␉if (PatchApplied)␊ |
1277 | ␉␉␉␉{␊ |
1278 | ␉␉␉␉␉break;␊ |
1279 | ␉␉␉␉}␊ |
1280 | ␊ |
1281 | ␉␉␉␉PatchApplied = true;␊ |
1282 | ␉␉␉}␊ |
1283 | ␉␉}␊ |
1284 | ␉}␊ |
1285 | ␊ |
1286 | ␉// Snow Leopard 64␊ |
1287 | ␉if (kernelOSVer >= MacOSVer2Int("10.6") && kernelOSVer < MacOSVer2Int("10.7"))␊ |
1288 | ␉{␊ |
1289 | ␉␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1290 | ␉␉{␊ |
1291 | ␉␉␉if (Bytes[Index] == 0xE8␊ |
1292 | ␉␉␉␉&& Bytes[Index + 1] == 0x5A␊ |
1293 | ␉␉␉␉&& Bytes[Index + 2] == 0xFB␊ |
1294 | ␉␉␉␉&& Bytes[Index + 3] == 0xFF␊ |
1295 | ␉␉␉␉&& Bytes[Index + 4] == 0xFF␊ |
1296 | ␉␉␉␉&& Bytes[Index + 5] == 0xEB␊ |
1297 | ␉␉␉␉&& Bytes[Index + 6] == 0x08␊ |
1298 | ␉␉␉␉&& Bytes[Index + 7] == 0x48␊ |
1299 | ␉␉␉␉&& Bytes[Index + 8] == 0x89␊ |
1300 | ␉␉␉␉&& Bytes[Index + 9] == 0xDF)␊ |
1301 | ␉␉␉{␊ |
1302 | ␉␉␉␉Bytes[Index + 5] = 0x90;␊ |
1303 | ␉␉␉␉Bytes[Index + 6] = 0x90;␊ |
1304 | ␉␉␉␉verbose("\tFound Snow Leopard EXT pattern: patched!\n");␊ |
1305 | ␉␉␉␉count++;␊ |
1306 | ␊ |
1307 | ␉␉␉␉if (PatchApplied)␊ |
1308 | ␉␉␉␉{␊ |
1309 | ␉␉␉␉␉break;␊ |
1310 | ␉␉␉␉}␊ |
1311 | ␊ |
1312 | ␉␉␉␉PatchApplied = true;␊ |
1313 | ␉␉␉}␊ |
1314 | ␉␉}␊ |
1315 | ␉}␊ |
1316 | ␊ |
1317 | ␉if (!PatchApplied)␊ |
1318 | ␉{␊ |
1319 | ␉␉verbose("\tCan't find Booter Extensions patch location.\n");␊ |
1320 | ␉}␊ |
1321 | ␉else␊ |
1322 | ␉{␊ |
1323 | ␉␉verbose("\t%d substitution(s) made.\n", count);␊ |
1324 | ␉}␊ |
1325 | }␊ |
1326 | ␊ |
1327 | // ===================================␊ |
1328 | // Patch ssse3␊ |
1329 | void patch_SSE3_6(void *kernelData)␊ |
1330 | {␊ |
1331 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1332 | ␉UInt32 patchLocation1 = 0;␊ |
1333 | ␉UInt32 patchLocation2 = 0;␊ |
1334 | ␉UInt32 patchlast = 0;␊ |
1335 | ␉UInt32 i;␊ |
1336 | ␉//UInt32 Length = sizeof(kernelData);␊ |
1337 | ␊ |
1338 | ␉verbose("\t- Start find SSE3 address\n");␊ |
1339 | ␉i = 0;␊ |
1340 | ␉//for (i = 0; i < Length; i++)␊ |
1341 | ␉while(true)␊ |
1342 | ␉{␊ |
1343 | ␉␉if (bytes[i] == 0x66␊ |
1344 | ␉␉␉&& bytes[i + 1] == 0x0F␊ |
1345 | ␉␉␉&& bytes[i + 2] == 0x6F␊ |
1346 | ␉␉␉&& bytes[i + 3] == 0x44␊ |
1347 | ␉␉␉&& bytes[i + 4] == 0x0E␊ |
1348 | ␉␉␉&& bytes[i + 5] == 0xF1␊ |
1349 | ␉␉␉&& bytes[i - 1664 - 32] == 0x55)␊ |
1350 | ␉␉{␊ |
1351 | ␉␉␉patchLocation1 = i-1664-32;␊ |
1352 | ␉␉␉verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
1353 | ␉␉}␊ |
1354 | ␊ |
1355 | ␉␉// hasSSE2+..... title␊ |
1356 | ␉␉if (bytes[i] == 0xE3␊ |
1357 | ␉␉␉&& bytes[i + 1] == 0x07␊ |
1358 | ␉␉␉&& bytes[i + 2] == 0x00␊ |
1359 | ␉␉␉&& bytes[i + 3] == 0x00␊ |
1360 | ␉␉␉&& bytes[i + 4] == 0x80␊ |
1361 | ␉␉␉&& bytes[i + 5] == 0x07␊ |
1362 | ␉␉␉&& bytes[i + 6] == 0xFF␊ |
1363 | ␉␉␉&& bytes[i + 7] == 0xFF␊ |
1364 | ␉␉␉&& bytes[i + 8] == 0x24␊ |
1365 | ␉␉␉&& bytes[i + 9] == 0x01)␊ |
1366 | ␉␉{␊ |
1367 | ␉␉␉patchLocation2 = i;␊ |
1368 | ␉␉␉verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);␊ |
1369 | ␉␉␉break;␊ |
1370 | ␉␉}␊ |
1371 | ␉␉i++;␊ |
1372 | ␉}␊ |
1373 | ␊ |
1374 | ␉if (!patchLocation1 || !patchLocation2)␊ |
1375 | ␉{␊ |
1376 | ␉␉verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);␊ |
1377 | ␉␉return;␊ |
1378 | ␉}␊ |
1379 | ␊ |
1380 | ␉verbose("\tFound SSE3 last data addres Start\n");␊ |
1381 | ␉i = patchLocation1 + 1500;␊ |
1382 | ␉//for (i=(patchLocation1+1500); i<(patchLocation1+3000); i++)␊ |
1383 | ␉while(true)␊ |
1384 | ␉{␊ |
1385 | ␉␉if (bytes[i] == 0x90␊ |
1386 | ␉␉␉&& bytes[i + 1] == 0x90␊ |
1387 | ␉␉␉&& bytes[i + 2] == 0x55 )␊ |
1388 | ␉␉{␊ |
1389 | ␉␉␉patchlast = (i+1) - patchLocation1;␊ |
1390 | ␉␉␉verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1391 | ␉␉␉break;␊ |
1392 | ␉␉}␊ |
1393 | ␉␉i++;␊ |
1394 | ␉}␊ |
1395 | ␊ |
1396 | ␉if (!patchlast)␊ |
1397 | ␉{␊ |
1398 | ␉␉verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1399 | ␉␉return;␊ |
1400 | ␉}␊ |
1401 | ␉// patch sse3_64 data␊ |
1402 | ␊ |
1403 | ␉for (i = 0; i < patchlast; i++)␊ |
1404 | ␉{␊ |
1405 | ␉␉if (i < sizeof(sse3_patcher))␊ |
1406 | ␉␉{␊ |
1407 | ␉␉␉bytes[patchLocation1 + i] = sse3_patcher[i];␊ |
1408 | ␉␉}␊ |
1409 | ␉␉else␊ |
1410 | ␉␉{␊ |
1411 | ␉␉␉bytes[patchLocation1 + i] = 0x90;␊ |
1412 | ␉␉}␊ |
1413 | ␉}␊ |
1414 | ␊ |
1415 | ␉// patch kHasSSE3 title␊ |
1416 | ␉bytes[patchLocation2 + 0] = 0xFC;␊ |
1417 | ␉bytes[patchLocation2 + 1] = 0x05;␊ |
1418 | ␉bytes[patchLocation2 + 8] = 0x2C;␊ |
1419 | ␉bytes[patchLocation2 + 9] = 0x00;␊ |
1420 | ␊ |
1421 | }␊ |
1422 | ␊ |
1423 | // ===================================␊ |
1424 | //␊ |
1425 | void patch_SSE3_5(void *kernelData)␊ |
1426 | {␊ |
1427 | ␉UInt8 *bytes = (UInt8 *)kernelData;␊ |
1428 | ␉UInt32 patchLocation1 = 0;␊ |
1429 | ␉UInt32 patchLocation2 = 0;␊ |
1430 | ␉UInt32 patchlast=0;␊ |
1431 | ␉UInt32 Length = sizeof(kernelData);␊ |
1432 | ␉UInt32 i;␊ |
1433 | ␊ |
1434 | ␉verbose("\t- Start find SSE3 address\n");␊ |
1435 | ␊ |
1436 | ␉for (i = 256; i < (Length-256); i++)␊ |
1437 | ␉{␊ |
1438 | ␉␉if (bytes[i] == 0x66␊ |
1439 | ␉␉␉&& bytes[i + 1] == 0x0F␊ |
1440 | ␉␉␉&& bytes[i + 2] == 0x6F␊ |
1441 | ␉␉␉&& bytes[i + 3] == 0x44␊ |
1442 | ␉␉␉&& bytes[i + 4] == 0x0E␊ |
1443 | ␉␉␉&& bytes[i + 5] == 0xF1␊ |
1444 | ␉␉␉&& bytes[i - 1680 - 32] == 0x55)␊ |
1445 | ␉␉{␊ |
1446 | ␉␉␉patchLocation1 = i-1680-32;␊ |
1447 | ␉␉␉verbose("\tFound SSE3 data address at 0x%08X\n", (unsigned int)patchLocation1);␊ |
1448 | ␉␉}␊ |
1449 | ␊ |
1450 | ␉␉// khasSSE2+..... title␊ |
1451 | ␉␉if (bytes[i] == 0xF3␊ |
1452 | ␉␉␉&& bytes[i + 1] == 0x07␊ |
1453 | ␉␉␉&& bytes[i + 2] == 0x00␊ |
1454 | ␉␉␉&& bytes[i + 3] == 0x00␊ |
1455 | ␉␉␉&& bytes[i + 4] == 0x80␊ |
1456 | ␉␉␉&& bytes[i + 5] == 0x07␊ |
1457 | ␉␉␉&& bytes[i + 6] == 0xFF␊ |
1458 | ␉␉␉&& bytes[i + 7] == 0xFF␊ |
1459 | ␉␉␉&& bytes[i + 8] == 0x24␊ |
1460 | ␉␉␉&& bytes[i + 9] == 0x01)␊ |
1461 | ␉␉{␊ |
1462 | ␉␉␉patchLocation2 = i;␊ |
1463 | ␉␉␉verbose("\tFound SSE3 Title address at 0x%08X\n", (unsigned int)patchLocation2);␊ |
1464 | ␉␉␉break;␊ |
1465 | ␉␉}␊ |
1466 | ␉}␊ |
1467 | ␊ |
1468 | ␉if (!patchLocation1 || !patchLocation2)␊ |
1469 | ␉{␊ |
1470 | ␉␉verbose("\tCan't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", (unsigned int)patchLocation1, (unsigned int)patchLocation2);␊ |
1471 | ␉␉return;␊ |
1472 | ␉}␊ |
1473 | ␊ |
1474 | ␉verbose("\tFound SSE3 last data addres Start\n");␊ |
1475 | ␊ |
1476 | ␉for (i = (patchLocation1+1500);i < Length;i++)␊ |
1477 | ␉{␊ |
1478 | ␉␉if (bytes[i] == 0x90␊ |
1479 | ␉␉␉&& bytes[i + 1] == 0x90␊ |
1480 | ␉␉␉&& bytes[i + 2] == 0x55)␊ |
1481 | ␉␉{␊ |
1482 | ␉␉␉patchlast = (i+1) - patchLocation1;␊ |
1483 | ␉␉␉verbose("\tFound SSE3 last data addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1484 | ␉␉␉break;␊ |
1485 | ␉␉}␊ |
1486 | ␉}␊ |
1487 | ␊ |
1488 | ␉if (!patchlast)␊ |
1489 | ␉{␊ |
1490 | ␉␉verbose("\tCan't found SSE3 data last addres at 0x%08X\n", (unsigned int)patchlast);␊ |
1491 | ␉␉return;␊ |
1492 | ␉}␊ |
1493 | ␊ |
1494 | ␉// patech sse3_64 data␊ |
1495 | ␊ |
1496 | ␉for (i = 0; i < patchlast; i++)␊ |
1497 | ␉{␊ |
1498 | ␉␉if (i < sizeof(sse3_5_patcher))␊ |
1499 | ␉␉{␊ |
1500 | ␉␉␉bytes[patchLocation1 + i] = sse3_5_patcher[i];␊ |
1501 | ␉␉}␊ |
1502 | ␉␉else␊ |
1503 | ␉␉{␊ |
1504 | ␉␉␉bytes[patchLocation1 + i] = 0x90;␊ |
1505 | ␉␉}␊ |
1506 | ␉}␊ |
1507 | ␊ |
1508 | ␉// patch kHasSSE3 title␊ |
1509 | ␉bytes[patchLocation2 + 0] = 0x0C;␊ |
1510 | ␉bytes[patchLocation2 + 1] = 0x06;␊ |
1511 | ␉bytes[patchLocation2 + 8] = 0x2C;␊ |
1512 | ␉bytes[patchLocation2 + 9] = 0x00;␊ |
1513 | ␊ |
1514 | }␊ |
1515 | ␊ |
1516 | // ===================================␊ |
1517 | //␊ |
1518 | void patch_SSE3_7(void *kernelData)␊ |
1519 | {␊ |
1520 | ␉// not support yet␊ |
1521 | ␉return;␊ |
1522 | }␊ |
1523 | ␊ |
1524 | // ===================================␊ |
1525 | // root:xnu text replacement Patch␊ |
1526 | bool patch_string_XNU_init(void *kernelData) //␊ |
1527 | {␊ |
1528 | ␊ |
1529 | ␉UInt8␉*Bytes;␊ |
1530 | ␉UInt32␉Index;␊ |
1531 | ␉bool␉PatchApplied;␊ |
1532 | ␊ |
1533 | ␉DBG("\t- Searching for \"root:xnu-\" string pattern\n");␊ |
1534 | ␊ |
1535 | ␉Bytes = (UInt8 *)kernelData;␊ |
1536 | ␉PatchApplied = false;␊ |
1537 | ␊ |
1538 | ␉for (Index = 0; Index < 0x1000000; ++Index)␊ |
1539 | ␉{␊ |
1540 | ␉␉// search for root:xnu- and replace it with ***Enoch-␊ |
1541 | ␉␉if (Bytes[Index] == ' '␊ |
1542 | ␉␉␉&& Bytes[Index + 1] == 'r'␊ |
1543 | ␉␉␉&& Bytes[Index + 2] == 'o'␊ |
1544 | ␉␉␉&& Bytes[Index + 3] == 'o'␊ |
1545 | ␉␉␉&& Bytes[Index + 4] == 't'␊ |
1546 | ␉␉␉&& Bytes[Index + 5] == ':'␊ |
1547 | ␉␉␉&& Bytes[Index + 6] == 'x'␊ |
1548 | ␉␉␉&& Bytes[Index + 7] == 'n'␊ |
1549 | ␉␉␉&& Bytes[Index + 8] == 'u'␊ |
1550 | ␉␉␉&& Bytes[Index + 9] == '-' )␊ |
1551 | ␉␉{␊ |
1552 | ␉␉␉Bytes[Index + 1] = '*';␊ |
1553 | ␉␉␉Bytes[Index + 2] = '*';␊ |
1554 | ␉␉␉Bytes[Index + 3] = '*';␊ |
1555 | ␉␉␉Bytes[Index + 4] = 'E';␊ |
1556 | ␉␉␉Bytes[Index + 5] = 'n';␊ |
1557 | ␉␉␉Bytes[Index + 6] = 'o';␊ |
1558 | ␉␉␉Bytes[Index + 7] = 'c';␊ |
1559 | ␉␉␉Bytes[Index + 8] = 'h';␊ |
1560 | ␊ |
1561 | ␉␉␉DBG("\tFound \"root:xnu-\" pattern; patched.\n");␊ |
1562 | ␊ |
1563 | ␉␉␉if (PatchApplied)␊ |
1564 | ␉␉␉{␊ |
1565 | ␉␉␉␉break;␊ |
1566 | ␉␉␉}␊ |
1567 | ␊ |
1568 | ␉␉␉PatchApplied = true;␊ |
1569 | ␉␉}␊ |
1570 | ␉}␊ |
1571 | ␊ |
1572 | ␉if (!PatchApplied)␊ |
1573 | ␉{␊ |
1574 | ␉␉DBG("\tCan't find \"root:xnu-\" string pattern: patch not applied.\n");␊ |
1575 | ␉}␊ |
1576 | ␊ |
1577 | ␉return PatchApplied;␊ |
1578 | }␊ |
1579 | ␊ |
1580 | // ===================================␊ |
1581 | // (Clover)␊ |
1582 | // Patching AppleRTC to prevent CMOS reset␊ |
1583 | unsigned int AppleRTC_Patch(void *data, UInt32 DriverSize, UInt32 StartLocation)␊ |
1584 | {␊ |
1585 | unsigned int count = 0;␊ |
1586 | // as far as I know this works from Lion to Sierra␊ |
1587 | UInt8 LionSearch_X64[] = { 0x75, 0x30, 0x44, 0x89, 0xf8 };␊ |
1588 | UInt8 LionReplace_X64[] = { 0xeb, 0x30, 0x44, 0x89, 0xf8 };␊ |
1589 | ␊ |
1590 | UInt8 LionSearch_i386[] = { 0x75, 0x3d, 0x8b, 0x75, 0x08 };␊ |
1591 | UInt8 LionReplace_i386[] = { 0xeb, 0x3d, 0x8b, 0x75, 0x08 };␊ |
1592 | ␊ |
1593 | UInt8 MLSearch[] = { 0x75, 0x30, 0x89, 0xd8 };␊ |
1594 | UInt8 MLReplace[] = { 0xeb, 0x30, 0x89, 0xd8 };␊ |
1595 | //SunKi␊ |
1596 | //752e0fb6 -> eb2e0fb6␊ |
1597 | UInt8 MavSearch[] = { 0x75, 0x2e, 0x0f, 0xb6 };␊ |
1598 | UInt8 MavReplace[] = { 0xeb, 0x2e, 0x0f, 0xb6};␊ |
1599 | ␊ |
1600 | if (kernelOSVer >= MacOSVer2Int("10.7") && kernelOSVer < MacOSVer2Int("10.8"))␊ |
1601 | {␊ |
1602 | count = FindAndReplace(data,␊ |
1603 | DriverSize,␊ |
1604 | StartLocation,␊ |
1605 | LionSearch_i386,␊ |
1606 | sizeof(LionSearch_i386),␊ |
1607 | LionReplace_i386,␊ |
1608 | 0);␊ |
1609 | ␊ |
1610 | count = count + FindAndReplace(data,␊ |
1611 | DriverSize,␊ |
1612 | StartLocation,␊ |
1613 | LionSearch_X64,␊ |
1614 | sizeof(LionSearch_X64),␊ |
1615 | LionReplace_X64,␊ |
1616 | 0);␊ |
1617 | }␊ |
1618 | else␊ |
1619 | if (kernelOSVer >= MacOSVer2Int("10.8") && kernelOSVer < MacOSVer2Int("10.9"))␊ |
1620 | {␊ |
1621 | count = FindAndReplace(data,␊ |
1622 | DriverSize,␊ |
1623 | StartLocation,␊ |
1624 | MLSearch,␊ |
1625 | sizeof(MLSearch),␊ |
1626 | MLReplace,␊ |
1627 | 0);␊ |
1628 | }␊ |
1629 | else␊ |
1630 | if (kernelOSVer >= MacOSVer2Int("10.9"))␊ |
1631 | {␊ |
1632 | count = FindAndReplace(data,␊ |
1633 | DriverSize,␊ |
1634 | StartLocation,␊ |
1635 | MavSearch,␊ |
1636 | sizeof(MavSearch),␊ |
1637 | MavReplace,␊ |
1638 | 0);␊ |
1639 | }␊ |
1640 | ␊ |
1641 | return count;␊ |
1642 | }␊ |
1643 | ␊ |
1644 | // ===================================␊ |
1645 | // (Clover)␊ |
1646 | // Patching AppleIntelCPUPowerManagement␊ |
1647 | unsigned int AsusAICPUPMPatch(void *data, UInt32 DriverSize, UInt32 StartLocation)␊ |
1648 | {␊ |
1649 | unsigned int Index1;␊ |
1650 | unsigned int Index2;␊ |
1651 | unsigned int Count = 0;␊ |
1652 | ␊ |
1653 | UInt8 MovlE2ToEcx[] = { 0xB9, 0xE2, 0x00, 0x00, 0x00 };␊ |
1654 | UInt8 MovE2ToCx[] = { 0x66, 0xB9, 0xE2, 0x00 };␊ |
1655 | UInt8 Wrmsr[] = { 0x0F, 0x30 };␊ |
1656 | ␊ |
1657 | UInt8␉*Driver = (UInt8 *)data;␊ |
1658 | ␊ |
1659 | //TODO: we should scan only __text __TEXT␊ |
1660 | for (Index1 = StartLocation; Index1 < (StartLocation+DriverSize); Index1++)␊ |
1661 | {␊ |
1662 | // search for MovlE2ToEcx␊ |
1663 | if (memcmp(Driver + Index1, MovlE2ToEcx, sizeof(MovlE2ToEcx)) == 0)␊ |
1664 | {␊ |
1665 | // search for wrmsr in next few bytes␊ |
1666 | for (Index2 = Index1 + sizeof(MovlE2ToEcx); Index2 < Index1 + sizeof(MovlE2ToEcx) + 32; Index2++)␊ |
1667 | {␊ |
1668 | if (Driver[Index2] == Wrmsr[0] && Driver[Index2 + 1] == Wrmsr[1])␊ |
1669 | {␊ |
1670 | // found it - patch it with nops␊ |
1671 | Count++;␊ |
1672 | Driver[Index2] = 0x90;␊ |
1673 | Driver[Index2 + 1] = 0x90;␊ |
1674 | verbose("\t%d wrmsr patched at 0x%X\n", Count, Index2);␊ |
1675 | break;␊ |
1676 | } else if ((Driver[Index2] == 0xC9 && Driver[Index2 + 1] == 0xC3) ||␊ |
1677 | (Driver[Index2] == 0x5D && Driver[Index2 + 1] == 0xC3) ||␊ |
1678 | (Driver[Index2] == 0xB9 && Driver[Index2 + 3] == 0 && Driver[Index2 + 4] == 0) ||␊ |
1679 | (Driver[Index2] == 0x66 && Driver[Index2 + 1] == 0xB9 && Driver[Index2 + 3] == 0))␊ |
1680 | {␊ |
1681 | // a leave/ret will cancel the search␊ |
1682 | // so will an intervening "mov[l] $xx, [e]cx"␊ |
1683 | break;␊ |
1684 | }␊ |
1685 | }␊ |
1686 | } else if (memcmp(Driver + Index1, MovE2ToCx, sizeof(MovE2ToCx)) == 0)␊ |
1687 | {␊ |
1688 | // search for wrmsr in next few bytes␊ |
1689 | for (Index2 = Index1 + sizeof(MovE2ToCx); Index2 < Index1 + sizeof(MovE2ToCx) + 32; Index2++)␊ |
1690 | {␊ |
1691 | if (Driver[Index2] == Wrmsr[0] && Driver[Index2 + 1] == Wrmsr[1])␊ |
1692 | {␊ |
1693 | // found it - patch it with nops␊ |
1694 | Count++;␊ |
1695 | Driver[Index2] = 0x90;␊ |
1696 | Driver[Index2 + 1] = 0x90;␊ |
1697 | verbose("\t%d wrmsr patched at 0x%X\n", Count, Index2);␊ |
1698 | break;␊ |
1699 | } else if ((Driver[Index2] == 0xC9 && Driver[Index2 + 1] == 0xC3) ||␊ |
1700 | (Driver[Index2] == 0x5D && Driver[Index2 + 1] == 0xC3) ||␊ |
1701 | (Driver[Index2] == 0xB9 && Driver[Index2 + 3] == 0 && Driver[Index2 + 4] == 0) ||␊ |
1702 | (Driver[Index2] == 0x66 && Driver[Index2 + 1] == 0xB9 && Driver[Index2 + 3] == 0))␊ |
1703 | {␊ |
1704 | // a leave/ret will cancel the search␊ |
1705 | // so will an intervening "mov[l] $xx, [e]cx"␊ |
1706 | break;␊ |
1707 | }␊ |
1708 | }␊ |
1709 | }␊ |
1710 | }␊ |
1711 | ␊ |
1712 | return Count;␊ |
1713 | }␊ |
1714 | ␊ |
1715 | // ===================================␊ |
1716 | // Patching IOAHCIBlockStorage to enable the trim support␊ |
1717 | unsigned int trimEnablerSata(void *data, UInt32 DriverSize, UInt32 StartLocation)␊ |
1718 | {␊ |
1719 | // as far as I know this works from Lion to Sierra␊ |
1720 | UInt8 Find[] = { 0x00, 0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x53, 0x53, 0x44, 0x00 };␊ |
1721 | ␊ |
1722 | UInt8 Replace[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };␊ |
1723 | unsigned int count = FindAndReplace(data,␊ |
1724 | DriverSize,␊ |
1725 | StartLocation,␊ |
1726 | Find,␊ |
1727 | sizeof(Find),␊ |
1728 | Replace,␊ |
1729 | 0);␊ |
1730 | ␊ |
1731 | return count;␊ |
1732 | }␊ |
1733 | ␊ |
1734 | // ===================================␊ |
1735 | // Patching AppleAHCIPort to fix orange icon (Sata only)␊ |
1736 | unsigned int patch_AppleAHCIPort_OrangeFix(void *data, UInt32 DriverSize, UInt32 StartLocation)␊ |
1737 | {␊ |
1738 | // as far as I know this works from lion onward␊ |
1739 | UInt8 Find[] = { 0x45, 0x78, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C };␊ |
1740 | UInt8 Replace[] = { 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C };␊ |
1741 | unsigned int count = FindAndReplace(data,␊ |
1742 | DriverSize,␊ |
1743 | StartLocation,␊ |
1744 | Find,␊ |
1745 | sizeof(Find),␊ |
1746 | Replace,␊ |
1747 | 0);␊ |
1748 | ␊ |
1749 | return count;␊ |
1750 | }␊ |
1751 | ␊ |
1752 | // ===================================␊ |
1753 | // (Micky1979)␊ |
1754 | // Patching NVDAStartupWeb␊ |
1755 | unsigned int patch_NVDAStartupWeb(void *data, UInt32 DriverSize, UInt32 StartLocation)␊ |
1756 | {␊ |
1757 | unsigned int count = 0;␊ |
1758 | // this patch is needed only in Sierra onward␊ |
1759 | if (MacOSVerCurrent >= MacOSVer2Int("10.12"))␊ |
1760 | {␊ |
1761 | Node *nvdadrvNode = DT__FindNode("/nvdadrv", true);␊ |
1762 | if (nvdadrvNode != 0)␊ |
1763 | {␊ |
1764 | DT__AddProperty(nvdadrvNode, "nvda_drv", strlen(NVDAVALUE), (void*)NVDAVALUE);␊ |
1765 | UInt8 Find[] = { 0x49, 0x4F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65,␊ |
1766 | 0x3A, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x00, 0x4E, 0x56,␊ |
1767 | 0x44, 0x41, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x57, 0x65, 0x62,␊ |
1768 | 0x3A };␊ |
1769 | ␊ |
1770 | UInt8 Replace[] = { 0x49, 0x4F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65,␊ |
1771 | 0x3A, 0x2F, 0x6E, 0x76, 0x64, 0x61, 0x64, 0x72, 0x76, 0x00, 0x4E, 0x56,␊ |
1772 | 0x44, 0x41, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x57, 0x65, 0x62,␊ |
1773 | 0x3A };␊ |
1774 | count = FindAndReplace(data,␊ |
1775 | DriverSize,␊ |
1776 | StartLocation,␊ |
1777 | Find,␊ |
1778 | sizeof(Find),␊ |
1779 | Replace,␊ |
1780 | 0);␊ |
1781 | }␊ |
1782 | else␊ |
1783 | {␊ |
1784 | verbose("Error: Unable to add nvdadrv node\n");␊ |
1785 | }␊ |
1786 | ␊ |
1787 | }␊ |
1788 | return count;␊ |
1789 | }␊ |
1790 | ␊ |
1791 | // ===================================␊ |
1792 | // Micky1979, 2017␊ |
1793 | // patch_prelinked_kexts␊ |
1794 | void patch_prelinked_kexts(void *kernelData,␊ |
1795 | u_int32_t uncompressed_size,␊ |
1796 | unsigned prelinkTextVmaddr,␊ |
1797 | unsigned prelinkTextFileOff)␊ |
1798 | {␊ |
1799 | TagPtr KextsPatches;␊ |
1800 | bool canPatchKexts = false;␊ |
1801 | unsigned long prelinkDictSize;␊ |
1802 | unsigned int Index;␊ |
1803 | unsigned int Count = 0;␊ |
1804 | ␊ |
1805 | UInt8 *Bytes = (UInt8 *)kernelData;␊ |
1806 | ␊ |
1807 | UInt8 *prelinkDic = NULL;␊ |
1808 | UInt32 prelinkDictStartLocation = 0;␊ |
1809 | UInt32 prelinkDictEndLocation = 0;␊ |
1810 | ␊ |
1811 | ␊ |
1812 | if (bootInfo->kextConfig.dictionary)␊ |
1813 | {␊ |
1814 | ␉KextsPatches = XMLGetProperty(bootInfo->kextConfig.dictionary, (const char*)"KextsPatches");␊ |
1815 | }␊ |
1816 | ␊ |
1817 | verbose("[ KEXTS PATCHER START ]\n");␊ |
1818 | //int lessBytes = (int)((uncompressed_size/3)*2); // speedup, the _PrelinkInfoDictionary should not be 1/3 of entire cache!␊ |
1819 | for (Index = 0/*lessBytes*/; Index < uncompressed_size; ++Index)␊ |
1820 | {␊ |
1821 | // scan for _PrelinkInfoDictionary␊ |
1822 | // <dict><key>_PrelinkInfoDictionary</key>␊ |
1823 | // 3C 64 69 63 74 3E 3C 6B 65 79 3E 5F 50 72 65 6C 69 6E 6B 49 6E 66 6F 44 69 63 74 69 6F 6E 61 72 79 3C 2F 6B 65 79 3E␊ |
1824 | if (Bytes[Index] == 0x3C␊ |
1825 | && Bytes[Index + 1] == 0x64␊ |
1826 | && Bytes[Index + 2] == 0x69␊ |
1827 | && Bytes[Index + 3] == 0x63␊ |
1828 | && Bytes[Index + 4] == 0x74␊ |
1829 | && Bytes[Index + 5] == 0x3E␊ |
1830 | && Bytes[Index + 6] == 0x3C␊ |
1831 | && Bytes[Index + 7] == 0x6B␊ |
1832 | && Bytes[Index + 8] == 0x65␊ |
1833 | && Bytes[Index + 9] == 0x79␊ |
1834 | && Bytes[Index + 10] == 0x3E␊ |
1835 | && Bytes[Index + 11] == 0x5F␊ |
1836 | && Bytes[Index + 12] == 0x50␊ |
1837 | && Bytes[Index + 13] == 0x72␊ |
1838 | && Bytes[Index + 14] == 0x65␊ |
1839 | && Bytes[Index + 15] == 0x6C␊ |
1840 | && Bytes[Index + 16] == 0x69␊ |
1841 | && Bytes[Index + 17] == 0x6E␊ |
1842 | && Bytes[Index + 18] == 0x6B␊ |
1843 | && Bytes[Index + 19] == 0x49␊ |
1844 | && Bytes[Index + 20] == 0x6E␊ |
1845 | && Bytes[Index + 21] == 0x66␊ |
1846 | && Bytes[Index + 22] == 0x6F␊ |
1847 | && Bytes[Index + 23] == 0x44␊ |
1848 | && Bytes[Index + 24] == 0x69␊ |
1849 | && Bytes[Index + 25] == 0x63␊ |
1850 | && Bytes[Index + 26] == 0x74␊ |
1851 | && Bytes[Index + 27] == 0x69␊ |
1852 | && Bytes[Index + 28] == 0x6F␊ |
1853 | && Bytes[Index + 29] == 0x6E␊ |
1854 | && Bytes[Index + 30] == 0x61␊ |
1855 | && Bytes[Index + 31] == 0x72␊ |
1856 | && Bytes[Index + 32] == 0x79␊ |
1857 | && Bytes[Index + 33] == 0x3C␊ |
1858 | && Bytes[Index + 34] == 0x2F␊ |
1859 | && Bytes[Index + 35] == 0x6B␊ |
1860 | && Bytes[Index + 36] == 0x65␊ |
1861 | && Bytes[Index + 37] == 0x79␊ |
1862 | && Bytes[Index + 38] == 0x3E)␊ |
1863 | {␊ |
1864 | Count++;␊ |
1865 | prelinkDictStartLocation = Index;␊ |
1866 | DBG("\tFound _PrelinkInfoDictionary at 0x%08X index = %d\n", (unsigned int)prelinkDictStartLocation, Index);␊ |
1867 | canPatchKexts = true;␊ |
1868 | break;␊ |
1869 | }␊ |
1870 | }␊ |
1871 | ␊ |
1872 | if (prelinkDictStartLocation)␊ |
1873 | {␊ |
1874 | for (Index = prelinkDictStartLocation; Index < uncompressed_size; ++Index)␊ |
1875 | {␊ |
1876 | // end of prelink ( <> plus some zeros) ␊ |
1877 | // </dict>␊ |
1878 | // 3C 2F 64 69 63 74 3E 00 00 00 00 00 00 00␊ |
1879 | if (Bytes[Index] == 0x3C␊ |
1880 | && Bytes[Index + 1] == 0x2F␊ |
1881 | && Bytes[Index + 2] == 0x64␊ |
1882 | && Bytes[Index + 3] == 0x69␊ |
1883 | && Bytes[Index + 4] == 0x63␊ |
1884 | && Bytes[Index + 5] == 0x74␊ |
1885 | && Bytes[Index + 6] == 0x3E␊ |
1886 | && Bytes[Index + 7] == 0x00␊ |
1887 | && Bytes[Index + 8] == 0x00␊ |
1888 | && Bytes[Index + 9] == 0x00␊ |
1889 | && Bytes[Index + 10] == 0x00␊ |
1890 | && Bytes[Index + 11] == 0x00␊ |
1891 | && Bytes[Index + 12] == 0x00␊ |
1892 | && Bytes[Index + 13] == 0x00)␊ |
1893 | {␊ |
1894 | Count++;␊ |
1895 | ␊ |
1896 | if ((Count = 2))␊ |
1897 | {␊ |
1898 | canPatchKexts = true;␊ |
1899 | prelinkDictEndLocation = Index + 7 ;␊ |
1900 | DBG("\tFound _PrelinkInfoDictionary end location at 0x%08X index = %d\n", (unsigned int)prelinkDictEndLocation, Index);␊ |
1901 | }␊ |
1902 | break;␊ |
1903 | }␊ |
1904 | }␊ |
1905 | }␊ |
1906 | ␊ |
1907 | if (canPatchKexts)␊ |
1908 | {␊ |
1909 | prelinkDictSize = uncompressed_size - prelinkDictStartLocation;␊ |
1910 | prelinkDic = malloc(prelinkDictSize);␊ |
1911 | memcpy(prelinkDic, Bytes+prelinkDictStartLocation, prelinkDictSize);␊ |
1912 | TagPtr prelinkInfoPtr = NULL;␊ |
1913 | XMLParseFile( (char *)prelinkDic, &prelinkInfoPtr );␊ |
1914 | ␊ |
1915 | if (prelinkInfoPtr)␊ |
1916 | {␊ |
1917 | TagPtr prelinkInfoDictionary = XMLGetProperty(prelinkInfoPtr, "_PrelinkInfoDictionary");␊ |
1918 | if (!prelinkInfoDictionary)␊ |
1919 | {␊ |
1920 | verbose("Unable to allocate the _PrelinkInfoDictionary, kexts patcher skipped.");␊ |
1921 | return;␊ |
1922 | }␊ |
1923 | int count = XMLTagCount(prelinkInfoDictionary);␊ |
1924 | while(count)␊ |
1925 | {␊ |
1926 | TagPtr sub = XMLGetElement( prelinkInfoDictionary, count-1);␊ |
1927 | if (sub && XMLIsDict(sub))␊ |
1928 | {␊ |
1929 | char* execPath = XMLCastString(XMLGetProperty(sub, (const char*)"CFBundleExecutable"));␊ |
1930 | ␊ |
1931 | if (execPath != NULL)␊ |
1932 | {␊ |
1933 | UInt32 kextSize = XMLCastInteger(XMLGetProperty(sub, (const char*)"_PrelinkExecutableSize"));␊ |
1934 | UInt32 kextAddr = XMLCastInteger(XMLGetProperty(sub, (const char*)"_PrelinkExecutableSourceAddr"));␊ |
1935 | ␊ |
1936 | ␊ |
1937 | if (kextAddr && kextSize)␊ |
1938 | {␊ |
1939 | // adjust binary address location␊ |
1940 | kextAddr -= prelinkTextVmaddr;␊ |
1941 | kextAddr += prelinkTextFileOff;␊ |
1942 | ␊ |
1943 | DBG("\t[%d] found exec:%s (size = %u, kextAddr = 0x%X [vmaddr = 0x%X fileoff = 0x%X])\n", count, execPath,␊ |
1944 | (unsigned int)kextSize, (unsigned int)kextAddr, (unsigned int)prelinkTextVmaddr, (unsigned int)prelinkTextFileOff);␊ |
1945 | ␊ |
1946 | if (!strcmp(execPath, "FakeSMC"))␊ |
1947 | {␊ |
1948 | FakeSMCLoaded = true;␊ |
1949 | }␊ |
1950 | ␊ |
1951 | ␉␉␉␉// chameleon patches␊ |
1952 | ␉␉␉␉patchBooterDefinedKext(execPath, kernelData, kextSize, kextAddr);␊ |
1953 | ␊ |
1954 | // user's defined␊ |
1955 | if (KextsPatches && XMLIsDict(KextsPatches))␊ |
1956 | {␊ |
1957 | pach_binaryUsingDictionary(kernelData,␊ |
1958 | kextSize,␊ |
1959 | kextAddr,␊ |
1960 | execPath,␊ |
1961 | KextsPatches);␊ |
1962 | }␊ |
1963 | ␊ |
1964 | #if DEBUG_KERNEL␊ |
1965 | getchar();␊ |
1966 | #endif␊ |
1967 | }␊ |
1968 | }␊ |
1969 | }␊ |
1970 | ␊ |
1971 | count --;␊ |
1972 | }␊ |
1973 | }␊ |
1974 | }␊ |
1975 | else␊ |
1976 | {␊ |
1977 | verbose("Unable to find the _PrelinkInfoDictionary, kexts patcher skipped.");␊ |
1978 | }␊ |
1979 | ␊ |
1980 | if (prelinkDic) free(prelinkDic);␊ |
1981 | verbose("Kexts patcher: end!\n\n");␊ |
1982 | }␊ |
1983 | ␊ |
1984 | void patchBooterDefinedKext(const char *kext, void *driverAddr, UInt32 DriverSize, UInt32 StartLocation)␊ |
1985 | {␊ |
1986 | ␉if ((!strcmp(kext, "AppleRTC")) && AppleRTCPatch)␊ |
1987 | ␉{␊ |
1988 | ␉␉verbose("\tPatching %s:", kext);␊ |
1989 | ␊ |
1990 | ␉␉unsigned int numPatches = AppleRTC_Patch(driverAddr, DriverSize, StartLocation);␊ |
1991 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
1992 | ␉}␊ |
1993 | ␊ |
1994 | ␉if ((!strcmp(kext, "AppleIntelCPUPowerManagement")) && AICPMPatch)␊ |
1995 | ␉{␊ |
1996 | ␉␉verbose("\tPatching %s (locked msr):\n", kext);␊ |
1997 | ␊ |
1998 | ␉␉unsigned int numPatches = AsusAICPUPMPatch(driverAddr, DriverSize, StartLocation);␊ |
1999 | ␉␉verbose("\t %d substitutions made!\n", numPatches);␊ |
2000 | ␉}␊ |
2001 | ␊ |
2002 | ␉if ((!strcmp(kext, "NVDAStartupWeb")) && NVIDIAWebDrv)␊ |
2003 | ␉{␊ |
2004 | ␉␉verbose("\tPatching %s (force load w/o nvram):\n", kext);␊ |
2005 | ␊ |
2006 | ␉␉unsigned int numPatches = patch_NVDAStartupWeb(driverAddr, DriverSize, StartLocation);␊ |
2007 | ␉␉verbose("\t %d substitutions made!\n", numPatches);␊ |
2008 | ␉}␊ |
2009 | ␊ |
2010 | ␉if ((!strcmp(kext, "IOAHCIBlockStorage")) && TrimEnablerSata)␊ |
2011 | ␉{␊ |
2012 | ␉␉verbose("\tPatching %s (trim enabler SATA):", kext);␊ |
2013 | ␊ |
2014 | ␉␉unsigned int numPatches = trimEnablerSata(driverAddr, DriverSize, StartLocation);␊ |
2015 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2016 | ␉}␊ |
2017 | ␊ |
2018 | ␉if ((!strcmp(kext, "AppleAHCIPort")) && OrangeIconFixSata)␊ |
2019 | ␉{␊ |
2020 | ␉␉verbose("\tPatching %s (orange icon fix):", kext);␊ |
2021 | ␊ |
2022 | ␉␉unsigned int numPatches = patch_AppleAHCIPort_OrangeFix(driverAddr, DriverSize, StartLocation);␊ |
2023 | ␉␉verbose(" %d substitutions made!\n", numPatches);␊ |
2024 | ␉}␊ |
2025 | }␊ |
2026 | ␊ |
2027 | // ===================================␊ |
2028 | // Boolean function to check the full OSX match version␊ |
2029 | bool checkFullOSVer(const char *version)␊ |
2030 | {␊ |
2031 | ␉// We are in a version with 7 char ?␊ |
2032 | ␉if ( (sizeof(version) == 7) && ('.' == version[5]) && ('\0' != version[6]) ) // 10.xx.x␊ |
2033 | ␉{␊ |
2034 | ␉␉return ( (gBootVolume->OSFullVer[0] == version[0]) // 1␊ |
2035 | ␉␉␉&& (gBootVolume->OSFullVer[1] == version[1]) // 0␊ |
2036 | ␉␉␉&& (gBootVolume->OSFullVer[2] == version[2]) // .␊ |
2037 | ␉␉␉&& (gBootVolume->OSFullVer[3] == version[3]) // x␊ |
2038 | ␉␉␉&& (gBootVolume->OSFullVer[4] == version[4]) // x␊ |
2039 | ␉␉␉&& (gBootVolume->OSFullVer[5] == version[5]) // .␊ |
2040 | ␉␉␉&& (gBootVolume->OSFullVer[6] == version[6]) // x␊ |
2041 | ␉␉);␊ |
2042 | ␉}␊ |
2043 | ␊ |
2044 | ␉// We are in a version with 7 char ?␊ |
2045 | ␉if ( (sizeof(version) == 7) && ('.' == version[4]) && ('\0' != version[6]) ) // 10.4.11␊ |
2046 | ␉{␊ |
2047 | ␉␉return ( (gBootVolume->OSFullVer[0] == version[0]) // 1␊ |
2048 | ␉␉␉&& (gBootVolume->OSFullVer[1] == version[1]) // 0␊ |
2049 | ␉␉␉&& (gBootVolume->OSFullVer[2] == version[2]) // .␊ |
2050 | ␉␉␉&& (gBootVolume->OSFullVer[3] == version[3]) // 4␊ |
2051 | ␉␉␉&& (gBootVolume->OSFullVer[4] == version[4]) // .␊ |
2052 | ␉␉␉&& (gBootVolume->OSFullVer[5] == version[5]) // x␊ |
2053 | ␉␉␉&& (gBootVolume->OSFullVer[6] == version[6]) // x␊ |
2054 | ␉␉);␊ |
2055 | ␉}␊ |
2056 | ␊ |
2057 | ␉// We are in a version with 6 char ?␊ |
2058 | ␉if ( (sizeof(version) == 6) && ('.' == version[4]) && ('\0' != version[5]) ) // 10.x.x␊ |
2059 | ␉{␊ |
2060 | ␉␉return ( (gBootVolume->OSFullVer[0] == version[0]) // 1␊ |
2061 | ␉␉␉&& (gBootVolume->OSFullVer[1] == version[1]) // 0␊ |
2062 | ␉␉␉&& (gBootVolume->OSFullVer[2] == version[2]) // .␊ |
2063 | ␉␉␉&& (gBootVolume->OSFullVer[3] == version[3]) // x␊ |
2064 | ␉␉␉&& (gBootVolume->OSFullVer[4] == version[4]) // .␊ |
2065 | ␉␉␉&& (gBootVolume->OSFullVer[5] == version[5]) // x␊ |
2066 | ␉␉);␊ |
2067 | ␉}␊ |
2068 | ␊ |
2069 | ␉// We are in a version with 5 char ?␊ |
2070 | ␉if ( (sizeof(version) == 5) && ('.' != version[4]) && ('\0' != version[4]) ) // 10.xx␊ |
2071 | ␉{␊ |
2072 | ␉␉return ( (gBootVolume->OSFullVer[0] == version[0]) // 1␊ |
2073 | ␉␉␉&& (gBootVolume->OSFullVer[1] == version[1]) // 0␊ |
2074 | ␉␉␉&& (gBootVolume->OSFullVer[2] == version[2]) // .␊ |
2075 | ␉␉␉&& (gBootVolume->OSFullVer[3] == version[3]) // x␊ |
2076 | ␉␉␉&& (gBootVolume->OSFullVer[4] == version[4]) // x␊ |
2077 | ␉␉);␊ |
2078 | ␉}␊ |
2079 | ␊ |
2080 | ␉// We are in a version with 4 char ?␊ |
2081 | ␉if ( (sizeof(version) == 4) && ('\0' != version[3]) ) // 10.x␊ |
2082 | ␉{␊ |
2083 | ␉␉return ( (gBootVolume->OSFullVer[0] == version[0]) // 1␊ |
2084 | ␉␉␉&& (gBootVolume->OSFullVer[1] == version[1]) // 0␊ |
2085 | ␉␉␉&& (gBootVolume->OSFullVer[2] == version[2]) // .␊ |
2086 | ␉␉␉&& (gBootVolume->OSFullVer[3] == version[3]) // x␊ |
2087 | ␉␉);␊ |
2088 | ␉}␊ |
2089 | ␊ |
2090 | ␉// no match found␊ |
2091 | ␉return false;␊ |
2092 | }␊ |
2093 | |