Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c

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

Archive Download this file

Revision: 499