Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c

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"
10extern PlatformInfo_t Platform;
11
12patchRoutine_t* patches = NULL;
13kernSymbols_t* kernelSymbols = NULL;
14
15
16void 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
20register_kernel_patch(patch_cpuid_set_info_all, KERNEL_ANY, CPUID_MODEL_UNKNOWN);
21
22register_kernel_patch(patch_commpage_stuff_routine, KERNEL_ANY, CPUID_MODEL_ANY);
23
24register_kernel_patch(patch_lapic_init, KERNEL_ANY, CPUID_MODEL_ANY);
25
26// NOTE: following is currently 32bit only
27register_kernel_patch(patch_lapic_configure, KERNEL_32, CPUID_MODEL_ANY);
28
29
30register_kernel_symbol(KERNEL_ANY, "_panic");
31register_kernel_symbol(KERNEL_ANY, "_cpuid_set_info");
32register_kernel_symbol(KERNEL_ANY, "_pmCPUExitHaltToOff");
33register_kernel_symbol(KERNEL_ANY, "_lapic_init");
34register_kernel_symbol(KERNEL_ANY, "_commpage_stuff_routine");
35
36// LAPIC configure symbols
37register_kernel_symbol(KERNEL_ANY, "_lapic_configure");
38
39register_kernel_symbol(KERNEL_ANY, "_lapic_start");
40register_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
51register_hook_callback("ExecKernel", &patch_kernel);
52}
53
54/*
55 * Register a kerenl patch
56 */
57void 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
61patchRoutine_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
66if(cpus != Platform.CPU.Model)
67{
68if(cpus != CPUID_MODEL_ANY)
69{
70if(cpus == CPUID_MODEL_UNKNOWN)
71{
72switch(Platform.CPU.Model)
73{
74case 13:
75case CPUID_MODEL_YONAH:
76case CPUID_MODEL_MEROM:
77case CPUID_MODEL_PENRYN:
78case CPUID_MODEL_NEHALEM:
79case CPUID_MODEL_FIELDS:
80case CPUID_MODEL_DALES:
81case CPUID_MODEL_NEHALEM_EX:
82// Known cpu's we don't want to add the patch
83return;
84break;
85
86default:
87// CPU not in supported list, so we are going to add
88// The patch will be applied
89break;
90
91}
92}
93else
94{
95// Invalid cpuid for current cpu. Ignoring patch
96return;
97}
98
99}
100}
101
102if(patches == NULL)
103{
104patches = entry = malloc(sizeof(patchRoutine_t));
105}
106else
107{
108entry = patches;
109while(entry->next)
110{
111entry = entry->next;
112}
113
114entry->next = malloc(sizeof(patchRoutine_t));
115entry = entry->next;
116}
117
118entry->next = NULL;
119entry->patchRoutine = patch;
120entry->validArchs = arch;
121entry->validCpu = cpus;
122}
123
124void register_kernel_symbol(int kernelType, const char* name)
125{
126if(kernelSymbols == NULL)
127{
128kernelSymbols = malloc(sizeof(kernSymbols_t));
129kernelSymbols->next = NULL;
130kernelSymbols->symbol = (char*)name;
131kernelSymbols->addr = 0;
132}
133else {
134kernSymbols_t *symbol = kernelSymbols;
135while(symbol->next != NULL)
136{
137symbol = symbol->next;
138}
139
140symbol->next = malloc(sizeof(kernSymbols_t));
141symbol = symbol->next;
142
143symbol->next = NULL;
144symbol->symbol = (char*)name;
145symbol->addr = 0;
146}
147}
148
149kernSymbols_t* lookup_kernel_symbol(const char* name)
150{
151kernSymbols_t *symbol = kernelSymbols;
152
153while(symbol && strcmp(symbol->symbol, name) !=0)
154{
155symbol = symbol->next;
156}
157
158if(!symbol)
159{
160return NULL;
161}
162else
163{
164return symbol;
165}
166
167}
168
169void patch_kernel(void* kernelData, void* arg2, void* arg3, void *arg4)
170{
171patchRoutine_t* entry = patches;
172
173
174int arch = determineKernelArchitecture(kernelData);
175
176locate_symbols(kernelData);
177
178if(patches != NULL)
179{
180while(entry)
181{
182if(entry->validArchs == KERNEL_ANY || arch == entry->validArchs)
183{
184if(entry->patchRoutine) entry->patchRoutine(kernelData);
185}
186entry = entry->next;
187}
188
189}
190}
191
192int determineKernelArchitecture(void* kernelData)
193{
194if(((struct mach_header*)kernelData)->magic == MH_MAGIC)
195{
196return KERNEL_32;
197}
198if(((struct mach_header*)kernelData)->magic == MH_MAGIC_64)
199{
200return KERNEL_64;
201}
202else
203{
204return 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 **/
213int locate_symbols(void* kernelData)
214{
215char is64 = 1;
216parse_mach(kernelData, NULL, symbol_handler);
217//handle_symtable((UInt32)kernelData, symtableData, &symbol_handler, determineKernelArchitecture(kernelData) == KERNEL_64);
218return 1 << is64;
219}
220
221long 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
224kernSymbols_t *symbol = lookup_kernel_symbol(symbolName);
225
226
227
228if(symbol)
229{
230
231//printf("Located %sbit symbol %s at 0x%lX\n", is64 ? "64" : "32", symbolName, addr);
232//getc();
233
234symbol->addr = addr;
235}
236return 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 **/
244void patch_cpuid_set_info_all(void* kernelData)
245{
246switch(Platform.CPU.Model)
247{
248case CPUID_MODEL_ATOM:
249patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);
250break;
251
252default:
253patch_cpuid_set_info(kernelData, 0, 0);
254break;
255}
256}
257
258void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
259{
260UInt8* bytes = (UInt8*)kernelData;
261
262kernSymbols_t *symbol = lookup_kernel_symbol("_cpuid_set_info");
263
264UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; //(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
265patchLocation -= (UInt32)kernelData;// Remove offset
266
267
268
269UInt32 jumpLocation = 0;
270
271
272if(symbol == 0 || symbol->addr == 0)
273{
274printf("Unable to locate _cpuid_set_info\n");
275return;
276
277}
278
279symbol = lookup_kernel_symbol("_panic");
280UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
281if(symbol == 0 || symbol->addr == 0)
282{
283printf("Unable to locate _panic\n");
284return;
285}
286panicAddr -= (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)
291while(
292 (bytes[patchLocation -1] != 0xE8) ||
293 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
294bytes[patchLocation + 1] << 8 |
295bytes[patchLocation + 2] << 16 |
296bytes[patchLocation + 3] << 24)))
297 )
298{
299patchLocation++;
300}
301patchLocation--;
302
303printf("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
306bytes[patchLocation + 0] = 0x90;
307bytes[patchLocation + 1] = 0x90;
308bytes[patchLocation + 2] = 0x90;
309bytes[patchLocation + 3] = 0x90;
310bytes[patchLocation + 4] = 0x90;
311printf("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
313getc();
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
318jumpLocation = patchLocation - 15;
319while((bytes[jumpLocation - 1] != 0x77 ||
320 bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) &&
321 (patchLocation - jumpLocation) < 0xF0)
322{
323jumpLocation--;
324}
325
326// If found... AND we want to impersonate a specific cpumodel / family...
327if(impersonateFamily &&
328 impersonateModel &&
329 ((patchLocation - jumpLocation) < 0xF0))
330{
331
332bytes[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
340UInt32 cpuid_cpufamily_addr =bytes[patchLocation - 15] << 0 |
341bytes[patchLocation - 14] << 8 |
342bytes[patchLocation - 13] << 16 |
343bytes[patchLocation - 12] << 24;
344
345// NOTE: may change, determined based on cpuid_info struct
346UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 299;
347
348
349// cpufamily = CPUFAMILY_INTEL_PENRYN
350bytes[patchLocation - 11] = (impersonateFamily & 0x000000FF) >> 0;
351bytes[patchLocation - 10] = (impersonateFamily & 0x0000FF00) >> 8;
352bytes[patchLocation - 9] = (impersonateFamily & 0x00FF0000) >> 16;
353bytes[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.
359bytes[patchLocation - 7] = 0x90;
360bytes[patchLocation - 6] = 0x90;
361
362bytes[patchLocation - 5] = 0xC7;
363bytes[patchLocation - 4] = 0x05;
364bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
365bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
366bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
367bytes[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.
371bytes[patchLocation + 1] = impersonateModel;// cpuid_model
372bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
373bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
374bytes[patchLocation + 4] = 0x02;// cpuid_stepping
375
376}
377else if(impersonateFamily && impersonateModel)
378{
379// Eitehr a 64bit kernel *or* a pre 10.6.2 kernel
380// Look for
381jumpLocation = patchLocation - 15;
382while((bytes[jumpLocation - 2] != 0x0F ||
383 bytes[jumpLocation - 1] != 0x87 ||
384 bytes[jumpLocation] != (patchLocation - jumpLocation - -31)) &&
385 (patchLocation - jumpLocation) < 0x200)
386{
387jumpLocation--;
388}
389
390
391if((patchLocation - jumpLocation) < 0x200)
392{
393// 64 bit kernel, 10.6.2+
394}
395else
396{// 32 bit kernel
397
398// pre 10.6.2 kernel
399// Locate the jump to directly *after* the panic call,
400jumpLocation = patchLocation - 4;
401while((bytes[jumpLocation - 1] != 0x77 ||
402 bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) &&
403 (patchLocation - jumpLocation) < 0x20)
404{
405jumpLocation--;
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
414if((patchLocation - jumpLocation) < 0x20)
415{
416UInt32 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
421bytes[patchLocation - 9] = 0x90;/// Was a jump if supported cpu
422bytes[patchLocation - 8] = 0x90;// jumped past the panic call, we want to override the panic
423
424bytes[patchLocation - 7] = 0x90;
425bytes[patchLocation - 6] = 0x90;
426
427bytes[patchLocation - 5] = 0xC7;
428bytes[patchLocation - 4] = 0x05;
429bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
430bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
431bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
432bytes[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.
436bytes[patchLocation + 1] = impersonateModel;// cpuid_model
437bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
438bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
439bytes[patchLocation + 4] = 0x02;// cpuid_stepping
440
441
442
443patchLocation = 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}
455else
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 **/
469void patch_pmCPUExitHaltToOff(void* kernelData)
470{
471UInt8* bytes = (UInt8*)kernelData;
472
473kernSymbols_t *symbol = lookup_kernel_symbol("_PmCpuExitHaltToOff");
474UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0;
475
476if(symbol == 0 || symbol->addr == 0)
477{
478printf("Unable to locate _pmCPUExitHaltToOff\n");
479return;
480}
481
482patchLocation -= (UInt32)kernelData;// Remove offset
483
484
485
486while(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{
493patchLocation++;
494}
495bytes[patchLocation] = 0x00;// KERN_SUCCESS;
496}
497
498void patch_lapic_init(void* kernelData)
499{
500
501UInt8 panicIndex = 0;
502UInt8* bytes = (UInt8*)kernelData;
503
504kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_init");
505UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0;
506if(symbol == 0 || symbol->addr == 0)
507{
508printf("Unable to locate %s\n", "_lapic_init");
509return;
510
511}
512
513symbol = lookup_kernel_symbol("_panic");
514UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0;
515if(symbol == 0 || symbol->addr == 0)
516{
517printf("Unable to locate %s\n", "_panic");
518return;
519}
520
521patchLocation -= (UInt32)kernelData;// Remove offset
522panicAddr -= (UInt32)kernelData;// Remove offset
523
524
525
526
527// Locate the (panicIndex + 1) panic call
528while(panicIndex < 3)// Find the third panic call
529{
530while(
531 (bytes[patchLocation -1] != 0xE8) ||
532 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
533bytes[patchLocation + 1] << 8 |
534bytes[patchLocation + 2] << 16 |
535bytes[patchLocation + 3] << 24)))
536 )
537{
538patchLocation++;
539}
540patchLocation++;
541panicIndex++;
542}
543patchLocation--;// Remove extra increment from the < 3 while loop
544
545bytes[--patchLocation] = 0x90;
546bytes[++patchLocation] = 0x90;
547bytes[++patchLocation] = 0x90;
548bytes[++patchLocation] = 0x90;
549bytes[++patchLocation] = 0x90;
550
551
552}
553
554
555void patch_commpage_stuff_routine(void* kernelData)
556{
557UInt8* bytes = (UInt8*)kernelData;
558
559kernSymbols_t *symbol = lookup_kernel_symbol("_commpage_stuff_routine");
560if(symbol == 0 || symbol->addr == 0)
561{
562printf("Unable to locate %s\n", "_commpage_stuff_routine");
563return;
564
565}
566
567UInt32 patchLocation = symbol->addr - textAddress + textSection;
568
569
570symbol = lookup_kernel_symbol("_panic");
571if(symbol == 0 || symbol->addr == 0)
572{
573printf("Unable to locate %s\n", "_panic");
574return;
575}
576UInt32 panicAddr = symbol->addr - textAddress;
577
578patchLocation -= (UInt32)kernelData;
579panicAddr -= (UInt32)kernelData;
580
581while(
582 (bytes[patchLocation -1] != 0xE8) ||
583 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
584bytes[patchLocation + 1] << 8 |
585bytes[patchLocation + 2] << 16 |
586bytes[patchLocation + 3] << 24)))
587 )
588{
589patchLocation++;
590}
591patchLocation--;
592
593// Replace panic with nops
594bytes[patchLocation + 0] = 0x90;
595bytes[patchLocation + 1] = 0x90;
596bytes[patchLocation + 2] = 0x90;
597bytes[patchLocation + 3] = 0x90;
598bytes[patchLocation + 4] = 0x90;
599
600
601}
602
603void patch_lapic_interrupt(void* kernelData)
604{
605// NOTE: this is a hack untill I finish patch_lapic_configure
606UInt8* bytes = (UInt8*)kernelData;
607
608kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_interrupt");
609if(symbol == 0 || symbol->addr == 0)
610{
611printf("Unable to locate %s\n", "_lapic_interrupt");
612return;
613
614}
615
616UInt32 patchLocation = symbol->addr - textAddress + textSection;
617
618
619symbol = lookup_kernel_symbol("_panic");
620if(symbol == 0 || symbol->addr == 0)
621{
622printf("Unable to locate %s\n", "_panic");
623return;
624}
625UInt32 panicAddr = symbol->addr - textAddress;
626
627patchLocation -= (UInt32)kernelData;
628panicAddr -= (UInt32)kernelData;
629
630while(
631 (bytes[patchLocation -1] != 0xE8) ||
632 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
633bytes[patchLocation + 1] << 8 |
634bytes[patchLocation + 2] << 16 |
635bytes[patchLocation + 3] << 24)))
636 )
637{
638patchLocation++;
639}
640patchLocation--;
641
642// Replace panic with nops
643bytes[patchLocation + 0] = 0x90;
644bytes[patchLocation + 1] = 0x90;
645bytes[patchLocation + 2] = 0x90;
646bytes[patchLocation + 3] = 0x90;
647bytes[patchLocation + 4] = 0x90;
648
649
650}
651
652
653void patch_lapic_configure(void* kernelData)
654{
655UInt8* bytes = (UInt8*)kernelData;
656
657UInt32 patchLocation;
658UInt32 lapicStart;
659UInt32 lapicInterruptBase;
660
661kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_configure");
662if(symbol == 0 || symbol->addr == 0)
663{
664printf("Unable to locate %s\n", "_lapic_configure");
665return;
666}
667patchLocation = symbol->addr - textAddress + textSection;
668
669symbol = lookup_kernel_symbol("_lapic_start");
670if(symbol == 0 || symbol->addr == 0)
671{
672printf("Unable to locate %s\n", "_lapic_start");
673return;
674}
675lapicStart = symbol->addr;
676
677
678symbol = lookup_kernel_symbol("_lapic_interrupt_base");
679if(symbol == 0 || symbol->addr == 0)
680{
681printf("Unable to locate %s\n", "_lapic_interrupt_base");
682return;
683}
684lapicInterruptBase = symbol->addr;
685patchLocation -= (UInt32)kernelData;
686lapicStart -= (UInt32)kernelData;
687lapicInterruptBase -= (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
694while(
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{
714patchLocation++;
715}
716patchLocation-=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/*
723bytes[patchLocation++] = 0x8B;
724bytes[patchLocation++] = 0x15;
725bytes[patchLocation++] = (lapicStart & 0x000000FF) >> 0;
726bytes[patchLocation++] = (lapicStart & 0x0000FF00) >> 8;
727bytes[patchLocation++] = (lapicStart & 0x00FF0000) >> 16;
728bytes[patchLocation++] = (lapicStart & 0xFF000000) >> 24;
729*/
730patchLocation += 6;
731
732// 81 c2 60 03 00 00 -> addl $0x00000320,%edx
733/*
734bytes[patchLocation++] = 0x81;
735bytes[patchLocation++] = 0xC2;
736*/
737patchLocation += 2;
738bytes[patchLocation++] = 0x60;
739/*
740bytes[patchLocation++];// = 0x03;
741bytes[patchLocation++];// = 0x00;
742bytes[patchLocation++];// = 0x00;
743*/
744 patchLocation += 3;
745
746// c7 02 00 04 00 00 -> movl $0x00000400,(%edx)
747bytes[patchLocation++] = 0xC7;
748bytes[patchLocation++] = 0x02;
749bytes[patchLocation++] = 0x00;
750bytes[patchLocation++] = 0x04;
751bytes[patchLocation++] = 0x00;
752bytes[patchLocation++] = 0x00;
753
754// 83 ea 40 -> subl $0x40,edx
755bytes[patchLocation++] = 0x83;
756bytes[patchLocation++] = 0xEA;
757bytes[patchLocation++] = 0x40;
758
759// a1 __ __ __ __ -> movl _lapic_interrupt_base,%eax
760bytes[patchLocation++] = 0xA1;
761bytes[patchLocation++] = (lapicInterruptBase & 0x000000FF) >> 0;
762bytes[patchLocation++] = (lapicInterruptBase & 0x0000FF00) >> 8;
763bytes[patchLocation++] = (lapicInterruptBase & 0x00FF0000) >> 16;
764bytes[patchLocation++] = (lapicInterruptBase & 0xFF000000) >> 24;
765
766// 83 c0 0e -> addl $0x0e,%eax
767bytes[patchLocation++] = 0x83;
768bytes[patchLocation++] = 0xC0;
769bytes[patchLocation++] = 0x0E;
770
771// 89 02 -> movl %eax,(%edx)
772bytes[patchLocation++] = 0x89;
773bytes[patchLocation++] = 0x02;
774
775// 81c230030000 addl $0x00000330,%edx
776bytes[patchLocation++] = 0x81;
777bytes[patchLocation++] = 0xC2;
778bytes[patchLocation++] = 0x30;
779bytes[patchLocation++] = 0x03;
780bytes[patchLocation++] = 0x00;
781bytes[patchLocation++] = 0x00;
782
783// a1 __ __ __ __ -> movl _lapic_interrupt_base,%eax
784bytes[patchLocation++] = 0xA1;
785bytes[patchLocation++] = (lapicInterruptBase & 0x000000FF) >> 0;
786bytes[patchLocation++] = (lapicInterruptBase & 0x0000FF00) >> 8;
787bytes[patchLocation++] = (lapicInterruptBase & 0x00FF0000) >> 16;
788bytes[patchLocation++] = (lapicInterruptBase & 0xFF000000) >> 24;
789
790// 83 c0 0f -> addl $0x0f,%eax
791bytes[patchLocation++] = 0x83;
792bytes[patchLocation++] = 0xC0;
793bytes[patchLocation++] = 0x0F;
794
795// 89 02 -> movl %eax,(%edx)
796bytes[patchLocation++] = 0x89;
797bytes[patchLocation++] = 0x02;
798
799// 83 ea 10 -> subl $0x10,edx
800bytes[patchLocation++] = 0x83;
801bytes[patchLocation++] = 0xEA;
802bytes[patchLocation++] = 0x10;
803
804// a1 __ __ __ __ -> movl _lapic_interrupt_base,%eax
805bytes[patchLocation++] = 0xA1;
806bytes[patchLocation++] = (lapicInterruptBase & 0x000000FF) >> 0;
807bytes[patchLocation++] = (lapicInterruptBase & 0x0000FF00) >> 8;
808bytes[patchLocation++] = (lapicInterruptBase & 0x00FF0000) >> 16;
809bytes[patchLocation++] = (lapicInterruptBase & 0xFF000000) >> 24;
810
811// 83 c0 0c -> addl $0x0c,%eax
812bytes[patchLocation++] = 0x83;
813bytes[patchLocation++] = 0xC0;
814bytes[patchLocation++] = 0x0C;
815
816// 89 02 -> movl %eax,(%edx)
817bytes[patchLocation++] = 0x89;
818bytes[patchLocation++] = 0x02;
819
820// Replace remaining with nops
821
822
823bytes[patchLocation++] = 0x90;
824bytes[patchLocation++] = 0x90;
825bytes[patchLocation++] = 0x90;
826bytes[patchLocation++] = 0x90;
827//bytes[patchLocation++] = 0x90; // double check the lenght of the patch...
828//bytes[patchLocation++] = 0x90;
829}
830

Archive Download this file

Revision: 496