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

Archive Download this file

Revision: 497