Root/
Source at commit 496 created 13 years 7 months ago. By meklort, Updated Symbols makefile so that it will compile if not in an svn dir. Added a missing paren form last commit. | |
---|---|
1 | ␉/*␊ |
2 | * Copyright (c) 2009-2010 Evan Lojewski. All rights reserved.␊ |
3 | *␊ |
4 | */␊ |
5 | ␊ |
6 | #include "libsaio.h"␊ |
7 | #include "kernel_patcher.h"␊ |
8 | #include "platform.h"␊ |
9 | #include "modules.h"␊ |
10 | extern PlatformInfo_t Platform;␊ |
11 | ␊ |
12 | patchRoutine_t* patches = NULL;␊ |
13 | kernSymbols_t* kernelSymbols = NULL;␊ |
14 | ␊ |
15 | ␊ |
16 | void KernelPatcher_start()␊ |
17 | {␊ |
18 | ␉//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_ATOM);␉␉// TODO: CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN␊ |
19 | ␉//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_UNKNOWN);␉// 0, 0 ␊ |
20 | ␉register_kernel_patch(patch_cpuid_set_info_all, KERNEL_ANY, CPUID_MODEL_UNKNOWN); ␊ |
21 | ␊ |
22 | ␉register_kernel_patch(patch_commpage_stuff_routine, KERNEL_ANY, CPUID_MODEL_ANY);␊ |
23 | ␉␊ |
24 | ␉register_kernel_patch(patch_lapic_init, KERNEL_ANY, CPUID_MODEL_ANY);␊ |
25 | ␊ |
26 | ␉// NOTE: following is currently 32bit only␊ |
27 | ␉register_kernel_patch(patch_lapic_configure, KERNEL_32, CPUID_MODEL_ANY);␊ |
28 | ␊ |
29 | ␉␊ |
30 | ␉register_kernel_symbol(KERNEL_ANY, "_panic");␊ |
31 | ␉register_kernel_symbol(KERNEL_ANY, "_cpuid_set_info");␊ |
32 | ␉register_kernel_symbol(KERNEL_ANY, "_pmCPUExitHaltToOff");␊ |
33 | ␉register_kernel_symbol(KERNEL_ANY, "_lapic_init");␊ |
34 | ␉register_kernel_symbol(KERNEL_ANY, "_commpage_stuff_routine");␊ |
35 | ␊ |
36 | ␉// LAPIC configure symbols␊ |
37 | ␉register_kernel_symbol(KERNEL_ANY, "_lapic_configure");␊ |
38 | ␊ |
39 | ␉register_kernel_symbol(KERNEL_ANY, "_lapic_start");␊ |
40 | ␉register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt_base");␊ |
41 | ␉␊ |
42 | ␉␊ |
43 | ␉//register_kernel_patch(patch_lapic_interrupt, KERNEL_ANY, CPUID_MODEL_ANY);␊ |
44 | ␉//register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt");␊ |
45 | ␊ |
46 | ␊ |
47 | ␉␊ |
48 | ␉// TODO: register needed symbols␊ |
49 | ␉␊ |
50 | ␉␊ |
51 | ␉register_hook_callback("ExecKernel", &patch_kernel); ␊ |
52 | }␊ |
53 | ␊ |
54 | /*␊ |
55 | * Register a kerenl patch␊ |
56 | */␊ |
57 | void register_kernel_patch(void* patch, int arch, int cpus)␊ |
58 | {␊ |
59 | ␉// TODO: only insert valid patches based on current cpuid and architecture␊ |
60 | ␉// AKA, don't at 64bit patches if it's a 32bit only machine␊ |
61 | ␉patchRoutine_t* entry;␊ |
62 | ␉␊ |
63 | ␉// TODO: verify Platform.CPU.Model is populated this early in bootup␊ |
64 | ␉// Check to ensure that the patch is valid on this machine␊ |
65 | ␉// If it is not, exit early form this function␊ |
66 | ␉if(cpus != Platform.CPU.Model)␊ |
67 | ␉{␊ |
68 | ␉␉if(cpus != CPUID_MODEL_ANY)␊ |
69 | ␉␉{␊ |
70 | ␉␉␉if(cpus == CPUID_MODEL_UNKNOWN)␊ |
71 | ␉␉␉{␊ |
72 | ␉␉␉␉switch(Platform.CPU.Model)␊ |
73 | ␉␉␉␉{␊ |
74 | ␉␉␉␉␉case 13:␊ |
75 | ␉␉␉␉␉case CPUID_MODEL_YONAH:␊ |
76 | ␉␉␉␉␉case CPUID_MODEL_MEROM:␊ |
77 | ␉␉␉␉␉case CPUID_MODEL_PENRYN:␊ |
78 | ␉␉␉␉␉case CPUID_MODEL_NEHALEM:␊ |
79 | ␉␉␉␉␉case CPUID_MODEL_FIELDS:␊ |
80 | ␉␉␉␉␉case CPUID_MODEL_DALES:␊ |
81 | ␉␉␉␉␉case CPUID_MODEL_NEHALEM_EX:␊ |
82 | ␉␉␉␉␉␉// Known cpu's we don't want to add the patch␊ |
83 | ␉␉␉␉␉␉return;␊ |
84 | ␉␉␉␉␉␉break;␊ |
85 | ␊ |
86 | ␉␉␉␉␉default:␊ |
87 | ␉␉␉␉␉␉// CPU not in supported list, so we are going to add␊ |
88 | ␉␉␉␉␉␉// The patch will be applied␊ |
89 | ␉␉␉␉␉␉break;␊ |
90 | ␉␉␉␉␉␉␊ |
91 | ␉␉␉␉}␊ |
92 | ␉␉␉}␊ |
93 | ␉␉␉else␊ |
94 | ␉␉␉{␊ |
95 | ␉␉␉␉// Invalid cpuid for current cpu. Ignoring patch␊ |
96 | ␉␉␉␉return;␊ |
97 | ␉␉␉}␊ |
98 | ␊ |
99 | ␉␉}␊ |
100 | ␉}␊ |
101 | ␉␉␊ |
102 | ␉if(patches == NULL)␊ |
103 | ␉{␊ |
104 | ␉␉patches = entry = malloc(sizeof(patchRoutine_t));␊ |
105 | ␉}␊ |
106 | ␉else␊ |
107 | ␉{␊ |
108 | ␉␉entry = patches;␊ |
109 | ␉␉while(entry->next)␊ |
110 | ␉␉{␊ |
111 | ␉␉␉entry = entry->next;␊ |
112 | ␉␉}␊ |
113 | ␉␉␊ |
114 | ␉␉entry->next = malloc(sizeof(patchRoutine_t));␊ |
115 | ␉␉entry = entry->next;␊ |
116 | ␉}␊ |
117 | ␉␊ |
118 | ␉entry->next = NULL;␊ |
119 | ␉entry->patchRoutine = patch;␊ |
120 | ␉entry->validArchs = arch;␊ |
121 | ␉entry->validCpu = cpus;␊ |
122 | }␊ |
123 | ␊ |
124 | void register_kernel_symbol(int kernelType, const char* name)␊ |
125 | {␊ |
126 | ␉if(kernelSymbols == NULL)␊ |
127 | ␉{␊ |
128 | ␉␉kernelSymbols = malloc(sizeof(kernSymbols_t));␊ |
129 | ␉␉kernelSymbols->next = NULL;␊ |
130 | ␉␉kernelSymbols->symbol = (char*)name;␊ |
131 | ␉␉kernelSymbols->addr = 0;␊ |
132 | ␉}␊ |
133 | ␉else {␊ |
134 | ␉␉kernSymbols_t *symbol = kernelSymbols;␊ |
135 | ␉␉while(symbol->next != NULL)␊ |
136 | ␉␉{␊ |
137 | ␉␉␉symbol = symbol->next;␊ |
138 | ␉␉}␊ |
139 | ␉␉␊ |
140 | ␉␉symbol->next = malloc(sizeof(kernSymbols_t));␊ |
141 | ␉␉symbol = symbol->next;␊ |
142 | ␊ |
143 | ␉␉symbol->next = NULL;␊ |
144 | ␉␉symbol->symbol = (char*)name;␊ |
145 | ␉␉symbol->addr = 0;␊ |
146 | ␉}␊ |
147 | }␊ |
148 | ␊ |
149 | kernSymbols_t* lookup_kernel_symbol(const char* name)␊ |
150 | {␊ |
151 | ␉kernSymbols_t *symbol = kernelSymbols;␊ |
152 | ␊ |
153 | ␉while(symbol && strcmp(symbol->symbol, name) !=0)␊ |
154 | ␉{␊ |
155 | ␉␉symbol = symbol->next;␊ |
156 | ␉}␊ |
157 | ␉␊ |
158 | ␉if(!symbol)␊ |
159 | ␉{␊ |
160 | ␉␉return NULL;␊ |
161 | ␉}␊ |
162 | ␉else␊ |
163 | ␉{␊ |
164 | ␉␉return symbol;␊ |
165 | ␉}␊ |
166 | ␊ |
167 | }␊ |
168 | ␊ |
169 | void patch_kernel(void* kernelData, void* arg2, void* arg3, void *arg4)␊ |
170 | {␊ |
171 | ␉patchRoutine_t* entry = patches;␊ |
172 | ␊ |
173 | ␉␊ |
174 | ␉int arch = determineKernelArchitecture(kernelData);␊ |
175 | ␊ |
176 | ␉locate_symbols(kernelData);␊ |
177 | ␉␊ |
178 | ␉if(patches != NULL)␊ |
179 | ␉{␊ |
180 | ␉␉while(entry)␊ |
181 | ␉␉{␊ |
182 | ␉␉␉if(entry->validArchs == KERNEL_ANY || arch == entry->validArchs)␊ |
183 | ␉␉␉{␊ |
184 | ␉␉␉␉if(entry->patchRoutine) entry->patchRoutine(kernelData);␊ |
185 | ␉␉␉}␊ |
186 | ␉␉␉entry = entry->next;␊ |
187 | ␉␉}␊ |
188 | ␉␉␊ |
189 | ␉}␊ |
190 | }␊ |
191 | ␊ |
192 | int determineKernelArchitecture(void* kernelData)␊ |
193 | {␉␊ |
194 | ␉if(((struct mach_header*)kernelData)->magic == MH_MAGIC)␊ |
195 | ␉{␊ |
196 | ␉␉return KERNEL_32;␊ |
197 | ␉}␊ |
198 | ␉if(((struct mach_header*)kernelData)->magic == MH_MAGIC_64)␊ |
199 | ␉{␊ |
200 | ␉␉return KERNEL_64;␊ |
201 | ␉}␊ |
202 | ␉else␊ |
203 | ␉{␊ |
204 | ␉␉return KERNEL_ERR;␊ |
205 | ␉}␊ |
206 | }␊ |
207 | ␊ |
208 | ␊ |
209 | /**␊ |
210 | **␉␉This functions located the requested symbols in the mach-o file.␊ |
211 | **␉␉␉as well as determines the start of the __TEXT segment and __TEXT,__text sections␊ |
212 | **/␊ |
213 | int locate_symbols(void* kernelData)␊ |
214 | {␊ |
215 | ␉char is64 = 1;␊ |
216 | ␉parse_mach(kernelData, NULL, symbol_handler);␊ |
217 | ␉//handle_symtable((UInt32)kernelData, symtableData, &symbol_handler, determineKernelArchitecture(kernelData) == KERNEL_64);␊ |
218 | ␉return 1 << is64;␊ |
219 | }␊ |
220 | ␊ |
221 | long long symbol_handler(char* symbolName, long long addr, char is64)␊ |
222 | {␊ |
223 | ␉// Locate the symbol in the list, if it exists, update it's address␊ |
224 | ␉kernSymbols_t *symbol = lookup_kernel_symbol(symbolName);␊ |
225 | ␉␊ |
226 | ␉␊ |
227 | ␉␊ |
228 | ␉if(symbol)␊ |
229 | ␉{␊ |
230 | ␊ |
231 | ␉␉//printf("Located %sbit symbol %s at 0x%lX\n", is64 ? "64" : "32", symbolName, addr);␊ |
232 | ␉␉//getc();␊ |
233 | ␉␉␊ |
234 | ␉␉symbol->addr = addr;␊ |
235 | ␉}␊ |
236 | ␉return 0xFFFFFFFF; // fixme␊ |
237 | }␊ |
238 | ␊ |
239 | ␊ |
240 | /**␊ |
241 | ** Locate the fisrt instance of _panic inside of _cpuid_set_info, and either remove it␊ |
242 | ** Or replace it so that the cpuid is set to a valid value.␊ |
243 | **/␊ |
244 | void patch_cpuid_set_info_all(void* kernelData)␊ |
245 | {␊ |
246 | ␉switch(Platform.CPU.Model)␊ |
247 | ␉{␊ |
248 | ␉␉case CPUID_MODEL_ATOM:␊ |
249 | ␉␉␉patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN); ␊ |
250 | ␉␉␉break;␊ |
251 | ␉␉␉␊ |
252 | ␉␉default:␊ |
253 | ␉␉␉patch_cpuid_set_info(kernelData, 0, 0);␊ |
254 | ␉␉␉break;␊ |
255 | ␉}␊ |
256 | }␊ |
257 | ␊ |
258 | void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)␊ |
259 | {␉␊ |
260 | ␉UInt8* bytes = (UInt8*)kernelData;␊ |
261 | ␉␊ |
262 | ␉kernSymbols_t *symbol = lookup_kernel_symbol("_cpuid_set_info");␊ |
263 | ␊ |
264 | ␉UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; //␉(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);␊ |
265 | ␉patchLocation -= (UInt32)kernelData;␉// Remove offset␊ |
266 | ␉␊ |
267 | ␉␊ |
268 | ␊ |
269 | ␉UInt32 jumpLocation = 0;␊ |
270 | ␉␊ |
271 | ␉␊ |
272 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
273 | ␉{␊ |
274 | ␉␉printf("Unable to locate _cpuid_set_info\n");␊ |
275 | ␉␉return;␊ |
276 | ␉␉␊ |
277 | ␉}␊ |
278 | ␊ |
279 | ␉symbol = lookup_kernel_symbol("_panic");␊ |
280 | ␉UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;␊ |
281 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
282 | ␉{␊ |
283 | ␉␉printf("Unable to locate _panic\n");␊ |
284 | ␉␉return;␊ |
285 | ␉}␊ |
286 | ␉panicAddr -= (UInt32)kernelData;␊ |
287 | ␊ |
288 | ␉␊ |
289 | ␉␊ |
290 | ␉//TODO: don't assume it'll always work (Look for *next* function address in symtab and fail once it's been reached)␊ |
291 | ␉while( ␊ |
292 | ␉␉ (bytes[patchLocation -1] != 0xE8) ||␊ |
293 | ␉␉ ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 | ␊ |
294 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 1] << 8 | ␊ |
295 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 2] << 16 |␊ |
296 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 3] << 24)))␊ |
297 | ␉␉ )␊ |
298 | ␉{␊ |
299 | ␉␉patchLocation++;␊ |
300 | ␉}␊ |
301 | ␉patchLocation--;␊ |
302 | ␉␊ |
303 | ␉printf("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]);␊ |
304 | ␉␊ |
305 | ␉// Remove panic call, just in case the following patch routines fail␊ |
306 | ␉bytes[patchLocation + 0] = 0x90;␊ |
307 | ␉bytes[patchLocation + 1] = 0x90;␊ |
308 | ␉bytes[patchLocation + 2] = 0x90;␊ |
309 | ␉bytes[patchLocation + 3] = 0x90;␊ |
310 | ␉bytes[patchLocation + 4] = 0x90;␊ |
311 | ␉printf("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]);␊ |
312 | ␊ |
313 | ␉getc();␊ |
314 | ␉␊ |
315 | ␉// Locate the jump call, so that 10 bytes can be reclamed.␊ |
316 | ␉// NOTE: This will *NOT* be located on pre 10.6.2 kernels␊ |
317 | ␉// NOTE: This will work on a *32* bit kernel and *not* on a 64 bit ont␊ |
318 | ␉jumpLocation = patchLocation - 15;␊ |
319 | ␉while((bytes[jumpLocation - 1] != 0x77 ||␊ |
320 | ␉␉ bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) &&␊ |
321 | ␉␉ (patchLocation - jumpLocation) < 0xF0)␊ |
322 | ␉{␊ |
323 | ␉␉jumpLocation--;␊ |
324 | ␉}␊ |
325 | ␉␊ |
326 | ␉// If found... AND we want to impersonate a specific cpumodel / family...␊ |
327 | ␉if(impersonateFamily &&␊ |
328 | ␉ impersonateModel &&␊ |
329 | ␉ ((patchLocation - jumpLocation) < 0xF0))␊ |
330 | ␉{␊ |
331 | ␉␉␊ |
332 | ␉␉bytes[jumpLocation] -= 10;␉␉// sizeof(movl␉$0x6b5a4cd2,0x00872eb4) = 10bytes␊ |
333 | ␉␉␊ |
334 | ␉␉/* ␊ |
335 | ␉␉ * Inpersonate the specified CPU FAMILY and CPU Model␊ |
336 | ␉␉ */␊ |
337 | ␊ |
338 | ␉␉// bytes[patchLocation - 17] = 0xC7;␉// already here... not needed to be done␊ |
339 | ␉␉// bytes[patchLocation - 16] = 0x05;␉// see above␊ |
340 | ␉␉UInt32 cpuid_cpufamily_addr =␉bytes[patchLocation - 15] << 0 |␊ |
341 | ␉␉␉␉␉␉␉␉␉␉bytes[patchLocation - 14] << 8 |␊ |
342 | ␉␉␉␉␉␉␉␉␉␉bytes[patchLocation - 13] << 16 |␊ |
343 | ␉␉␉␉␉␉␉␉␉␉bytes[patchLocation - 12] << 24;␊ |
344 | ␉␉␊ |
345 | ␉␉// NOTE: may change, determined based on cpuid_info struct␊ |
346 | ␉␉UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 299; ␊ |
347 | ␉␉␊ |
348 | ␉␉␊ |
349 | ␉␉// cpufamily = CPUFAMILY_INTEL_PENRYN␊ |
350 | ␉␉bytes[patchLocation - 11] = (impersonateFamily & 0x000000FF) >> 0;␊ |
351 | ␉␉bytes[patchLocation - 10] = (impersonateFamily & 0x0000FF00) >> 8;␊ |
352 | ␉␉bytes[patchLocation - 9] = (impersonateFamily & 0x00FF0000) >> 16;␉␊ |
353 | ␉␉bytes[patchLocation - 8] = (impersonateFamily & 0xFF000000) >> 24;␊ |
354 | ␉␉␊ |
355 | ␉␉// NOPS, just in case if the jmp call wasn't patched, we'll jump to a␊ |
356 | ␉␉// nop and continue with the rest of the patch␊ |
357 | ␉␉// Yay two free bytes :), 10 more can be reclamed if needed, as well as a few␊ |
358 | ␉␉// from the above code (only cpuid_model needs to be set.␊ |
359 | ␉␉bytes[patchLocation - 7] = 0x90;␊ |
360 | ␉␉bytes[patchLocation - 6] = 0x90;␊ |
361 | ␉␉␊ |
362 | ␉␉bytes[patchLocation - 5] = 0xC7;␊ |
363 | ␉␉bytes[patchLocation - 4] = 0x05;␊ |
364 | ␉␉bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;␊ |
365 | ␉␉bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;␉␊ |
366 | ␉␉bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;␊ |
367 | ␉␉bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;␊ |
368 | ␉␉␊ |
369 | ␉␉// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes␊ |
370 | ␉␉// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.␊ |
371 | ␉␉bytes[patchLocation + 1] = impersonateModel;␉// cpuid_model␊ |
372 | ␉␉bytes[patchLocation + 2] = 0x01;␉// cpuid_extmodel␊ |
373 | ␉␉bytes[patchLocation + 3] = 0x00;␉// cpuid_extfamily␊ |
374 | ␉␉bytes[patchLocation + 4] = 0x02;␉// cpuid_stepping␊ |
375 | ␉␉␊ |
376 | ␉}␊ |
377 | ␉else if(impersonateFamily && impersonateModel)␊ |
378 | ␉{␊ |
379 | ␉␉// Eitehr a 64bit kernel *or* a pre 10.6.2 kernel␊ |
380 | ␉␉// Look for ␊ |
381 | ␉␉jumpLocation = patchLocation - 15;␊ |
382 | ␉␉while((bytes[jumpLocation - 2] != 0x0F ||␊ |
383 | ␉␉␉ bytes[jumpLocation - 1] != 0x87 ||␊ |
384 | ␉␉␉ bytes[jumpLocation] != (patchLocation - jumpLocation - -31)) &&␊ |
385 | ␉␉␉ (patchLocation - jumpLocation) < 0x200)␊ |
386 | ␉␉{␊ |
387 | ␉␉␉jumpLocation--;␊ |
388 | ␉␉}␊ |
389 | ␉␉␊ |
390 | ␉␉␊ |
391 | ␉␉if((patchLocation - jumpLocation) < 0x200)␊ |
392 | ␉␉{␊ |
393 | ␉␉␉// 64 bit kernel, 10.6.2+␊ |
394 | ␉␉}␊ |
395 | ␉␉else␊ |
396 | ␉␉{␉// 32 bit kernel␊ |
397 | ␉␉␊ |
398 | ␉␉␉// pre 10.6.2 kernel␊ |
399 | ␉␉␉// Locate the jump to directly *after* the panic call,␊ |
400 | ␉␉␉jumpLocation = patchLocation - 4;␊ |
401 | ␉␉␉while((bytes[jumpLocation - 1] != 0x77 ||␊ |
402 | ␉␉␉␉ bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) &&␊ |
403 | ␉␉␉␉ (patchLocation - jumpLocation) < 0x20)␊ |
404 | ␉␉␉{␊ |
405 | ␉␉␉␉jumpLocation--;␊ |
406 | ␉␉␉}␊ |
407 | ␉␉␉// NOTE above isn't needed (I was going to use it, but I'm not, so instead,␊ |
408 | ␉␉␉// I'll just leave it to verify the binary stucture.␊ |
409 | ␉␉␉␊ |
410 | ␉␉␉// NOTE: the cpumodel_family data is not set in _cpuid_set_info␊ |
411 | ␉␉␉// so we don't need to set it here, I'll get set later based on the model␊ |
412 | ␉␉␉// we set now.␊ |
413 | ␉␉␉␊ |
414 | ␉␉␉if((patchLocation - jumpLocation) < 0x20)␊ |
415 | ␉␉␉{␊ |
416 | ␉␉␉␉UInt32 cpuid_model_addr =␉(bytes[patchLocation - 14] << 0 |␊ |
417 | ␉␉␉␉␉␉␉␉␉␉␉ bytes[patchLocation - 13] << 8 |␊ |
418 | ␉␉␉␉␉␉␉␉␉␉␉ bytes[patchLocation - 12] << 16 |␊ |
419 | ␉␉␉␉␉␉␉␉␉␉␉ bytes[patchLocation - 11] << 24);␊ |
420 | ␉␉␉␉// Remove jump␊ |
421 | ␉␉␉␉bytes[patchLocation - 9] = 0x90;␉␉/// Was a jump if supported cpu␊ |
422 | ␉␉␉␉bytes[patchLocation - 8] = 0x90;␉␉// jumped past the panic call, we want to override the panic␊ |
423 | ␉␉␉␉␊ |
424 | ␉␉␉␉bytes[patchLocation - 7] = 0x90;␊ |
425 | ␉␉␉␉bytes[patchLocation - 6] = 0x90;␊ |
426 | ␉␉␉␉␊ |
427 | ␉␉␉␉bytes[patchLocation - 5] = 0xC7;␊ |
428 | ␉␉␉␉bytes[patchLocation - 4] = 0x05;␊ |
429 | ␉␉␉␉bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;␊ |
430 | ␉␉␉␉bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;␉␊ |
431 | ␉␉␉␉bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;␊ |
432 | ␉␉␉␉bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;␊ |
433 | ␉␉␉␉␊ |
434 | ␉␉␉␉// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes␊ |
435 | ␉␉␉␉// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.␊ |
436 | ␉␉␉␉bytes[patchLocation + 1] = impersonateModel;␉// cpuid_model␊ |
437 | ␉␉␉␉bytes[patchLocation + 2] = 0x01;␉// cpuid_extmodel␊ |
438 | ␉␉␉␉bytes[patchLocation + 3] = 0x00;␉// cpuid_extfamily␊ |
439 | ␉␉␉␉bytes[patchLocation + 4] = 0x02;␉// cpuid_stepping␊ |
440 | ␉␉␉␉␊ |
441 | ␉␉␉␉␊ |
442 | ␉␉␉␉␊ |
443 | ␉␉␉␉patchLocation = jumpLocation;␊ |
444 | ␉␉␉␉// We now have 14 bytes available for a patch␊ |
445 | ␉␉␉␉␊ |
446 | ␉␉␉}␊ |
447 | ␉␉}␊ |
448 | ␉␉/*else ␊ |
449 | ␉␉{␊ |
450 | ␉␉␉// Check for 64bit kernel.␊ |
451 | ␉␉␉␊ |
452 | ␉␉␉// Patching failed, using NOP replacement done initialy␊ |
453 | ␉␉}*/␊ |
454 | ␉}␊ |
455 | ␉else ␊ |
456 | ␉{␊ |
457 | ␉␉// Either We were unable to change the jump call due to the function's sctructure␊ |
458 | ␉␉// changing, or the user did not request a patch. As such, resort to just ␊ |
459 | ␉␉// removing the panic call (using NOP replacement above). Note that the␊ |
460 | ␉␉// IntelCPUPM kext may still panic due to the cpu's Model ID not being patched␊ |
461 | ␉}␊ |
462 | }␊ |
463 | ␊ |
464 | ␊ |
465 | /**␊ |
466 | ** SleepEnabler.kext replacement (for those that need it)␊ |
467 | ** Located the KERN_INVALID_ARGUMENT return and replace it with KERN_SUCCESS␊ |
468 | **/␊ |
469 | void patch_pmCPUExitHaltToOff(void* kernelData)␊ |
470 | {␊ |
471 | ␉UInt8* bytes = (UInt8*)kernelData;␊ |
472 | ␊ |
473 | ␉kernSymbols_t *symbol = lookup_kernel_symbol("_PmCpuExitHaltToOff");␊ |
474 | ␉UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0;␊ |
475 | ␉␊ |
476 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
477 | ␉{␊ |
478 | ␉␉printf("Unable to locate _pmCPUExitHaltToOff\n");␊ |
479 | ␉␉return;␊ |
480 | ␉}␊ |
481 | ␉␊ |
482 | ␉patchLocation -= (UInt32)kernelData;␉// Remove offset␊ |
483 | ␉␊ |
484 | ␉␊ |
485 | ␉␊ |
486 | ␉while(bytes[patchLocation - 1]␉!= 0xB8 ||␊ |
487 | ␉␉ bytes[patchLocation]␉␉!= 0x04 ||␉// KERN_INVALID_ARGUMENT (0x00000004)␊ |
488 | ␉␉ bytes[patchLocation + 1]␉!= 0x00 ||␉// KERN_INVALID_ARGUMENT␊ |
489 | ␉␉ bytes[patchLocation + 2]␉!= 0x00 ||␉// KERN_INVALID_ARGUMENT␊ |
490 | ␉␉ bytes[patchLocation + 3]␉!= 0x00)␉// KERN_INVALID_ARGUMENT␊ |
491 | ␊ |
492 | ␉{␊ |
493 | ␉␉patchLocation++;␊ |
494 | ␉}␊ |
495 | ␉bytes[patchLocation] = 0x00;␉// KERN_SUCCESS;␊ |
496 | }␊ |
497 | ␊ |
498 | void patch_lapic_init(void* kernelData)␊ |
499 | {␊ |
500 | ␊ |
501 | ␉UInt8 panicIndex = 0;␊ |
502 | ␉UInt8* bytes = (UInt8*)kernelData;␊ |
503 | ␉␊ |
504 | ␉kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_init");␊ |
505 | ␉UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; ␊ |
506 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
507 | ␉{␊ |
508 | ␉␉printf("Unable to locate %s\n", "_lapic_init");␊ |
509 | ␉␉return;␊ |
510 | ␉␉␊ |
511 | ␉}␊ |
512 | ␉␊ |
513 | ␉symbol = lookup_kernel_symbol("_panic");␊ |
514 | ␉UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; ␊ |
515 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
516 | ␉{␊ |
517 | ␉␉printf("Unable to locate %s\n", "_panic");␊ |
518 | ␉␉return;␊ |
519 | ␉}␊ |
520 | ␉␊ |
521 | ␉patchLocation -= (UInt32)kernelData;␉// Remove offset␊ |
522 | ␉panicAddr -= (UInt32)kernelData;␉// Remove offset␊ |
523 | ␊ |
524 | ␉␊ |
525 | ␉␊ |
526 | ␉␊ |
527 | ␉// Locate the (panicIndex + 1) panic call␊ |
528 | ␉while(panicIndex < 3)␉// Find the third panic call␊ |
529 | ␉{␊ |
530 | ␉␉while( ␊ |
531 | ␉␉␉ (bytes[patchLocation -1] != 0xE8) ||␊ |
532 | ␉␉␉ ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 | ␊ |
533 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 1] << 8 | ␊ |
534 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 2] << 16 |␊ |
535 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 3] << 24)))␊ |
536 | ␉␉␉ )␊ |
537 | ␉␉{␊ |
538 | ␉␉␉patchLocation++;␊ |
539 | ␉␉}␊ |
540 | ␉␉patchLocation++;␊ |
541 | ␉␉panicIndex++;␊ |
542 | ␉}␊ |
543 | ␉patchLocation--;␉// Remove extra increment from the < 3 while loop␊ |
544 | ␉␊ |
545 | ␉bytes[--patchLocation] = 0x90;␉␊ |
546 | ␉bytes[++patchLocation] = 0x90;␊ |
547 | ␉bytes[++patchLocation] = 0x90;␊ |
548 | ␉bytes[++patchLocation] = 0x90;␊ |
549 | ␉bytes[++patchLocation] = 0x90;␊ |
550 | ␉␊ |
551 | ␉␊ |
552 | }␊ |
553 | ␊ |
554 | ␊ |
555 | void patch_commpage_stuff_routine(void* kernelData)␊ |
556 | {␊ |
557 | ␉UInt8* bytes = (UInt8*)kernelData;␊ |
558 | ␊ |
559 | ␉kernSymbols_t *symbol = lookup_kernel_symbol("_commpage_stuff_routine");␊ |
560 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
561 | ␉{␊ |
562 | ␉␉printf("Unable to locate %s\n", "_commpage_stuff_routine");␊ |
563 | ␉␉return;␊ |
564 | ␉␉␊ |
565 | ␉}␊ |
566 | ␉␊ |
567 | ␉UInt32 patchLocation = symbol->addr - textAddress + textSection; ␊ |
568 | ␊ |
569 | ␉␊ |
570 | ␉symbol = lookup_kernel_symbol("_panic");␊ |
571 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
572 | ␉{␊ |
573 | ␉␉printf("Unable to locate %s\n", "_panic");␊ |
574 | ␉␉return;␊ |
575 | ␉}␊ |
576 | ␉UInt32 panicAddr = symbol->addr - textAddress; ␊ |
577 | ␊ |
578 | ␉patchLocation -= (UInt32)kernelData;␊ |
579 | ␉panicAddr -= (UInt32)kernelData;␊ |
580 | ␉␊ |
581 | ␉while( ␊ |
582 | ␉␉ (bytes[patchLocation -1] != 0xE8) ||␊ |
583 | ␉␉ ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 | ␊ |
584 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 1] << 8 | ␊ |
585 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 2] << 16 |␊ |
586 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 3] << 24)))␊ |
587 | ␉␉ )␊ |
588 | ␉{␊ |
589 | ␉␉patchLocation++;␊ |
590 | ␉}␊ |
591 | ␉patchLocation--;␊ |
592 | ␉␊ |
593 | ␉// Replace panic with nops␊ |
594 | ␉bytes[patchLocation + 0] = 0x90;␊ |
595 | ␉bytes[patchLocation + 1] = 0x90;␊ |
596 | ␉bytes[patchLocation + 2] = 0x90;␊ |
597 | ␉bytes[patchLocation + 3] = 0x90;␊ |
598 | ␉bytes[patchLocation + 4] = 0x90;␊ |
599 | ␉␊ |
600 | ␉␊ |
601 | }␊ |
602 | ␊ |
603 | void patch_lapic_interrupt(void* kernelData)␊ |
604 | {␊ |
605 | ␉// NOTE: this is a hack untill I finish patch_lapic_configure␊ |
606 | ␉UInt8* bytes = (UInt8*)kernelData;␊ |
607 | ␉␊ |
608 | ␉kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_interrupt");␊ |
609 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
610 | ␉{␊ |
611 | ␉␉printf("Unable to locate %s\n", "_lapic_interrupt");␊ |
612 | ␉␉return;␊ |
613 | ␉␉␊ |
614 | ␉}␊ |
615 | ␉␊ |
616 | ␉UInt32 patchLocation = symbol->addr - textAddress + textSection; ␊ |
617 | ␉␊ |
618 | ␉␊ |
619 | ␉symbol = lookup_kernel_symbol("_panic");␊ |
620 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
621 | ␉{␊ |
622 | ␉␉printf("Unable to locate %s\n", "_panic");␊ |
623 | ␉␉return;␊ |
624 | ␉}␊ |
625 | ␉UInt32 panicAddr = symbol->addr - textAddress; ␊ |
626 | ␉␊ |
627 | ␉patchLocation -= (UInt32)kernelData;␊ |
628 | ␉panicAddr -= (UInt32)kernelData;␊ |
629 | ␉␊ |
630 | ␉while( ␊ |
631 | ␉␉ (bytes[patchLocation -1] != 0xE8) ||␊ |
632 | ␉␉ ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 | ␊ |
633 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 1] << 8 | ␊ |
634 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 2] << 16 |␊ |
635 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 3] << 24)))␊ |
636 | ␉␉ )␊ |
637 | ␉{␊ |
638 | ␉␉patchLocation++;␊ |
639 | ␉}␊ |
640 | ␉patchLocation--;␊ |
641 | ␉␊ |
642 | ␉// Replace panic with nops␊ |
643 | ␉bytes[patchLocation + 0] = 0x90;␊ |
644 | ␉bytes[patchLocation + 1] = 0x90;␊ |
645 | ␉bytes[patchLocation + 2] = 0x90;␊ |
646 | ␉bytes[patchLocation + 3] = 0x90;␊ |
647 | ␉bytes[patchLocation + 4] = 0x90;␊ |
648 | ␉␊ |
649 | ␉␊ |
650 | }␊ |
651 | ␊ |
652 | ␊ |
653 | void patch_lapic_configure(void* kernelData)␊ |
654 | {␊ |
655 | ␉UInt8* bytes = (UInt8*)kernelData;␊ |
656 | ␉␊ |
657 | ␉UInt32 patchLocation;␊ |
658 | ␉UInt32 lapicStart;␊ |
659 | ␉UInt32 lapicInterruptBase;␊ |
660 | ␉␊ |
661 | ␉kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_configure");␊ |
662 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
663 | ␉{␊ |
664 | ␉␉printf("Unable to locate %s\n", "_lapic_configure");␊ |
665 | ␉␉return;␊ |
666 | ␉}␊ |
667 | ␉patchLocation = symbol->addr - textAddress + textSection; ␊ |
668 | ␉␊ |
669 | ␉symbol = lookup_kernel_symbol("_lapic_start");␊ |
670 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
671 | ␉{␊ |
672 | ␉␉printf("Unable to locate %s\n", "_lapic_start");␊ |
673 | ␉␉return;␊ |
674 | ␉}␊ |
675 | ␉lapicStart = symbol->addr; ␊ |
676 | ␊ |
677 | ␊ |
678 | ␉symbol = lookup_kernel_symbol("_lapic_interrupt_base");␊ |
679 | ␉if(symbol == 0 || symbol->addr == 0)␊ |
680 | ␉{␊ |
681 | ␉␉printf("Unable to locate %s\n", "_lapic_interrupt_base");␊ |
682 | ␉␉return;␊ |
683 | ␉}␊ |
684 | ␉lapicInterruptBase = symbol->addr;␊ |
685 | ␉patchLocation -= (UInt32)kernelData;␊ |
686 | ␉lapicStart -= (UInt32)kernelData;␊ |
687 | ␉lapicInterruptBase -= (UInt32)kernelData;␊ |
688 | ␉␊ |
689 | ␉␊ |
690 | ␉// Looking for the following:␊ |
691 | ␉//movl _lapic_start,%e_x␊ |
692 | ␉//addl $0x00000320,%e_x␊ |
693 | ␉// 8b 15 __ __ __ __ 81 c2 20 03 00 00␊ |
694 | ␉while( ␊ |
695 | ␉␉ (bytes[patchLocation - 2] != 0x8b) ||␊ |
696 | ␉␉ //bytes[patchLocation -1] != 0x15) ||␉// Register, we don't care what it is␊ |
697 | ␉␉ ( lapicStart != (UInt32)(␊ |
698 | ␉␉␉␉␉␉␉␉␉(bytes[patchLocation + 0] << 0 | ␊ |
699 | ␉␉␉␉␉␉␉␉␉ bytes[patchLocation + 1] << 8 | ␊ |
700 | ␉␉␉␉␉␉␉␉␉ bytes[patchLocation + 2] << 16 |␊ |
701 | ␉␉␉␉␉␉␉␉␉ bytes[patchLocation + 3] << 24␊ |
702 | ␉␉␉␉␉␉␉␉␉)␊ |
703 | ␉␉␉␉␉␉␉␉ )␊ |
704 | ␉␉ ) || ␊ |
705 | ␉␉ (bytes[patchLocation + 4 ] != 0x81) ||␊ |
706 | ␉␉ //(bytes[patchLocation + 5 ] != 0Cx2) ||␉// register␊ |
707 | ␉␉ (bytes[patchLocation + 6 ] != 0x20) ||␊ |
708 | ␉␉ (bytes[patchLocation + 7 ] != 0x03) ||␊ |
709 | ␉␉ (bytes[patchLocation + 8 ] != 0x00) ||␊ |
710 | ␉␉ (bytes[patchLocation + 9] != 0x00)␊ |
711 | ␊ |
712 | ␉␉ )␊ |
713 | ␉{␊ |
714 | ␉␉patchLocation++;␊ |
715 | ␉}␊ |
716 | ␉patchLocation-=2;␊ |
717 | ␊ |
718 | ␉// NOTE: this is currently hardcoded, change it to be more resilient to changes␊ |
719 | ␉// At a minimum, I should have this do a cheksup first and if not matching, remove the panic instead.␊ |
720 | ␉␊ |
721 | ␉// 8b 15 __ __ __ __ -> movl␉␉ _lapic_start,%edx (NOTE: this should already be here)␊ |
722 | ␉/*␊ |
723 | ␉bytes[patchLocation++] = 0x8B;␊ |
724 | ␉bytes[patchLocation++] = 0x15;␊ |
725 | ␉bytes[patchLocation++] = (lapicStart & 0x000000FF) >> 0;␊ |
726 | ␉bytes[patchLocation++] = (lapicStart & 0x0000FF00) >> 8;␊ |
727 | ␉bytes[patchLocation++] = (lapicStart & 0x00FF0000) >> 16;␊ |
728 | ␉bytes[patchLocation++] = (lapicStart & 0xFF000000) >> 24;␊ |
729 | ␉*/␊ |
730 | ␉patchLocation += 6;␊ |
731 | ␉␊ |
732 | ␉// 81 c2 60 03 00 00 -> addl␉␉ $0x00000320,%edx␊ |
733 | ␉/*␊ |
734 | ␉bytes[patchLocation++] = 0x81;␊ |
735 | ␉bytes[patchLocation++] = 0xC2;␊ |
736 | ␉*/␊ |
737 | ␉patchLocation += 2;␊ |
738 | ␉bytes[patchLocation++] = 0x60;␊ |
739 | ␉/*␊ |
740 | ␉bytes[patchLocation++];// = 0x03;␊ |
741 | ␉bytes[patchLocation++];// = 0x00;␊ |
742 | ␉bytes[patchLocation++];// = 0x00;␊ |
743 | ␉*/␊ |
744 | ␉ patchLocation += 3;␊ |
745 | ␊ |
746 | ␉// c7 02 00 04 00 00 -> movl␉␉ $0x00000400,(%edx)␊ |
747 | ␉bytes[patchLocation++] = 0xC7;␊ |
748 | ␉bytes[patchLocation++] = 0x02;␊ |
749 | ␉bytes[patchLocation++] = 0x00;␊ |
750 | ␉bytes[patchLocation++] = 0x04;␊ |
751 | ␉bytes[patchLocation++] = 0x00;␊ |
752 | ␉bytes[patchLocation++] = 0x00;␊ |
753 | ␉␊ |
754 | ␉// 83 ea 40 -> subl␉␉ $0x40,edx␊ |
755 | ␉bytes[patchLocation++] = 0x83;␊ |
756 | ␉bytes[patchLocation++] = 0xEA;␊ |
757 | ␉bytes[patchLocation++] = 0x40;␊ |
758 | ␊ |
759 | ␉// a1 __ __ __ __ -> movl␉␉ _lapic_interrupt_base,%eax␊ |
760 | ␉bytes[patchLocation++] = 0xA1;␊ |
761 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x000000FF) >> 0;␊ |
762 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x0000FF00) >> 8;␊ |
763 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x00FF0000) >> 16;␊ |
764 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0xFF000000) >> 24;␊ |
765 | ␊ |
766 | ␉// 83 c0 0e -> addl␉␉ $0x0e,%eax␊ |
767 | ␉bytes[patchLocation++] = 0x83;␊ |
768 | ␉bytes[patchLocation++] = 0xC0;␊ |
769 | ␉bytes[patchLocation++] = 0x0E;␊ |
770 | ␊ |
771 | ␉// 89 02 -> movl␉␉ %eax,(%edx)␊ |
772 | ␉bytes[patchLocation++] = 0x89;␊ |
773 | ␉bytes[patchLocation++] = 0x02;␊ |
774 | ␉␊ |
775 | ␉// 81c230030000␉␉ addl␉␉ $0x00000330,%edx␊ |
776 | ␉bytes[patchLocation++] = 0x81;␊ |
777 | ␉bytes[patchLocation++] = 0xC2;␊ |
778 | ␉bytes[patchLocation++] = 0x30;␊ |
779 | ␉bytes[patchLocation++] = 0x03;␊ |
780 | ␉bytes[patchLocation++] = 0x00;␊ |
781 | ␉bytes[patchLocation++] = 0x00;␊ |
782 | ␉␊ |
783 | ␉// a1 __ __ __ __ -> movl␉␉ _lapic_interrupt_base,%eax␊ |
784 | ␉bytes[patchLocation++] = 0xA1;␊ |
785 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x000000FF) >> 0;␊ |
786 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x0000FF00) >> 8;␊ |
787 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x00FF0000) >> 16;␊ |
788 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0xFF000000) >> 24;␊ |
789 | ␉␊ |
790 | ␉// 83 c0 0f -> addl␉␉ $0x0f,%eax␊ |
791 | ␉bytes[patchLocation++] = 0x83;␊ |
792 | ␉bytes[patchLocation++] = 0xC0;␊ |
793 | ␉bytes[patchLocation++] = 0x0F;␊ |
794 | ␉␊ |
795 | ␉// 89 02 -> movl␉␉ %eax,(%edx)␊ |
796 | ␉bytes[patchLocation++] = 0x89;␊ |
797 | ␉bytes[patchLocation++] = 0x02;␊ |
798 | ␉␊ |
799 | ␉// 83 ea 10 -> subl␉␉ $0x10,edx␊ |
800 | ␉bytes[patchLocation++] = 0x83;␊ |
801 | ␉bytes[patchLocation++] = 0xEA;␊ |
802 | ␉bytes[patchLocation++] = 0x10;␊ |
803 | ␊ |
804 | ␉// a1 __ __ __ __ -> movl␉␉ _lapic_interrupt_base,%eax␊ |
805 | ␉bytes[patchLocation++] = 0xA1;␊ |
806 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x000000FF) >> 0;␊ |
807 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x0000FF00) >> 8;␊ |
808 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0x00FF0000) >> 16;␊ |
809 | ␉bytes[patchLocation++] = (lapicInterruptBase & 0xFF000000) >> 24;␊ |
810 | ␉␊ |
811 | ␉// 83 c0 0c -> addl␉␉ $0x0c,%eax␊ |
812 | ␉bytes[patchLocation++] = 0x83;␊ |
813 | ␉bytes[patchLocation++] = 0xC0;␊ |
814 | ␉bytes[patchLocation++] = 0x0C;␊ |
815 | ␊ |
816 | ␉// 89 02 -> movl␉␉ %eax,(%edx)␊ |
817 | ␉bytes[patchLocation++] = 0x89;␊ |
818 | ␉bytes[patchLocation++] = 0x02;␊ |
819 | ␊ |
820 | ␉// Replace remaining with nops␊ |
821 | ␊ |
822 | ␊ |
823 | ␉bytes[patchLocation++] = 0x90;␊ |
824 | ␉bytes[patchLocation++] = 0x90;␊ |
825 | ␉bytes[patchLocation++] = 0x90;␊ |
826 | ␉bytes[patchLocation++] = 0x90;␊ |
827 | ␉//␉bytes[patchLocation++] = 0x90; // double check the lenght of the patch...␊ |
828 | ␉//␉bytes[patchLocation++] = 0x90;␊ |
829 | }␊ |
830 |