Chameleon

Chameleon Svn Source Tree

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

Source at commit 442 created 13 years 7 months ago.
By meklort, Kernel patcher changes, initial lapic_configure patch, as well as a test patch for lapic_interrupt.
1/*
2 * Copyright (c) 2009 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
16UInt32 textSection = 0;
17UInt32 textAddress = 0;
18
19
20void KernelPatcher_start()
21{
22//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_ATOM);// TODO: CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN
23//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_UNKNOWN);// 0, 0
24register_kernel_patch(patch_cpuid_set_info_all, KERNEL_32, CPUID_MODEL_UNKNOWN);
25
26register_kernel_patch(patch_commpage_stuff_routine, KERNEL_32, CPUID_MODEL_ANY);
27
28register_kernel_patch(patch_lapic_init, KERNEL_32, CPUID_MODEL_ANY);
29
30//register_kernel_patch(patch_lapic_configure, KERNEL_32, CPUID_MODEL_ANY);
31register_kernel_patch(patch_lapic_interrupt, KERNEL_32, CPUID_MODEL_ANY);
32
33
34register_kernel_symbol(KERNEL_32, "_panic");
35register_kernel_symbol(KERNEL_32, "_cpuid_set_info");
36register_kernel_symbol(KERNEL_32, "_pmCPUExitHaltToOff");
37register_kernel_symbol(KERNEL_32, "_lapic_init");
38register_kernel_symbol(KERNEL_32, "_commpage_stuff_routine");
39
40// LAPIC configure symbols
41register_kernel_symbol(KERNEL_32, "_lapic_configure");
42register_kernel_symbol(KERNEL_32, "_lapic_interrupt");
43
44register_kernel_symbol(KERNEL_32, "_lapic_start");
45register_kernel_symbol(KERNEL_32, "_lapic_interrupt_base");
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
178
179if(patches != NULL)
180{
181while(entry)
182{
183if(entry->validArchs == KERNEL_ANY || arch == entry->validArchs)
184{
185if(entry->patchRoutine) entry->patchRoutine(kernelData);
186}
187entry = entry->next;
188}
189
190}
191}
192
193int determineKernelArchitecture(void* kernelData)
194{
195if(((struct mach_header*)kernelData)->magic == MH_MAGIC)
196{
197return KERNEL_32;
198}
199if(((struct mach_header*)kernelData)->magic == MH_MAGIC_64)
200{
201return KERNEL_64;
202}
203else
204{
205return KERNEL_ERR;
206}
207}
208
209
210/**
211 **This functions located the requested symbols in the mach-o file.
212 **as well as determines the start of the __TEXT segment and __TEXT,__text sections
213 **/
214int locate_symbols(void* kernelData)
215{
216
217struct load_command *loadCommand;
218struct symtab_command *symtableData;
219//struct nlist *symbolEntry;
220
221char* symbolString;
222
223UInt32 kernelIndex = 0;
224kernelIndex += sizeof(struct mach_header);
225
226if(((struct mach_header*)kernelData)->magic != MH_MAGIC) return KERNEL_64;
227
228
229int cmd = 0;
230while(cmd < ((struct mach_header*)kernelData)->ncmds)// TODO: for loop instead
231{
232cmd++;
233
234loadCommand = kernelData + kernelIndex;
235
236UInt cmdSize = loadCommand->cmdsize;
237
238
239if((loadCommand->cmd & 0x7FFFFFFF) == LC_SYMTAB)// We only care about the symtab segment
240{
241//printf("Located symtable, length is 0x%X, 0x%X\n", (unsigned int)loadCommand->cmdsize, (unsigned int)sizeof(symtableData));
242
243symtableData = kernelData + kernelIndex;
244kernelIndex += sizeof(struct symtab_command);
245
246symbolString = kernelData + symtableData->stroff;
247}
248else if((loadCommand->cmd & 0x7FFFFFFF) == LC_SEGMENT)// We only care about the __TEXT segment, any other load command can be ignored
249{
250
251struct segment_command *segCommand;
252
253segCommand = kernelData + kernelIndex;
254
255//printf("Segment name is %s\n", segCommand->segname);
256
257if(strcmp("__TEXT", segCommand->segname) == 0)
258{
259UInt32 sectionIndex;
260
261sectionIndex = sizeof(struct segment_command);
262
263struct section *sect;
264
265while(sectionIndex < segCommand->cmdsize)
266{
267sect = kernelData + kernelIndex + sectionIndex;
268
269sectionIndex += sizeof(struct section);
270
271
272if(strcmp("__text", sect->sectname) == 0)
273{
274// __TEXT,__text found, save the offset and address for when looking for the calls.
275textSection = sect->offset;
276textAddress = sect->addr;
277break;
278}
279}
280}
281
282
283kernelIndex += cmdSize;
284} else {
285kernelIndex += cmdSize;
286}
287}
288
289handle_symtable((UInt32)kernelData, symtableData, &symbol_handler);
290}
291
292void* symbol_handler(char* symbolName, void* addr)
293{
294// Locate the symbol in the list, if it exists, update it's address
295kernSymbols_t *symbol = lookup_kernel_symbol(symbolName);
296
297
298if(symbol)
299{
300symbol->addr = (UInt32)addr;
301}
302return (void*)0xFFFFFFFF;
303}
304
305
306/**
307 ** Locate the fisrt instance of _panic inside of _cpuid_set_info, and either remove it
308 ** Or replace it so that the cpuid is set to a valid value.
309 **/
310void patch_cpuid_set_info_all(void* kernelData)
311{
312switch(Platform.CPU.Model)
313{
314case CPUID_MODEL_ATOM:
315patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);
316break;
317
318default:
319patch_cpuid_set_info(kernelData, 0, 0);
320break;
321}
322}
323
324void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
325{
326UInt8* bytes = (UInt8*)kernelData;
327
328kernSymbols_t *symbol = lookup_kernel_symbol("_cpuid_set_info");
329UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; //(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
330
331UInt32 jumpLocation = 0;
332
333
334if(symbol == 0 || symbol->addr == 0)
335{
336printf("Unable to locate _cpuid_set_info\n");
337return;
338
339}
340
341symbol = lookup_kernel_symbol("_panic");
342UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
343if(symbol == 0 || symbol->addr == 0)
344{
345printf("Unable to locate _panic\n");
346return;
347}
348
349patchLocation -= (UInt32)kernelData;// Remove offset
350panicAddr -= (UInt32)kernelData;
351
352
353
354
355
356//TODO: don't assume it'll always work (Look for *next* function address in symtab and fail once it's been reached)
357while(
358 (bytes[patchLocation -1] != 0xE8) ||
359 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
360bytes[patchLocation + 1] << 8 |
361bytes[patchLocation + 2] << 16 |
362bytes[patchLocation + 3] << 24)))
363 )
364{
365patchLocation++;
366}
367patchLocation--;
368
369// Remove panic call, just in case the following patch routines fail
370bytes[patchLocation + 0] = 0x90;
371bytes[patchLocation + 1] = 0x90;
372bytes[patchLocation + 2] = 0x90;
373bytes[patchLocation + 3] = 0x90;
374bytes[patchLocation + 4] = 0x90;
375
376
377// Locate the jump call, so that 10 bytes can be reclamed.
378// NOTE: This will *NOT* be located on pre 10.6.2 kernels
379jumpLocation = patchLocation - 15;
380while((bytes[jumpLocation - 1] != 0x77 ||
381 bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) &&
382 (patchLocation - jumpLocation) < 0xF0)
383{
384jumpLocation--;
385}
386
387// If found... AND we want to impersonate a specific cpumodel / family...
388if(impersonateFamily &&
389 impersonateModel &&
390 ((patchLocation - jumpLocation) < 0xF0))
391{
392
393bytes[jumpLocation] -= 10;// sizeof(movl$0x6b5a4cd2,0x00872eb4) = 10bytes
394
395/*
396 * Inpersonate the specified CPU FAMILY and CPU Model
397 */
398
399// bytes[patchLocation - 17] = 0xC7;// already here... not needed to be done
400// bytes[patchLocation - 16] = 0x05;// see above
401UInt32 cpuid_cpufamily_addr =bytes[patchLocation - 15] << 0 |
402bytes[patchLocation - 14] << 8 |
403bytes[patchLocation - 13] << 16 |
404bytes[patchLocation - 12] << 24;
405
406// NOTE: may change, determined based on cpuid_info struct
407UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 299;
408
409
410// cpufamily = CPUFAMILY_INTEL_PENRYN
411bytes[patchLocation - 11] = (impersonateFamily & 0x000000FF) >> 0;
412bytes[patchLocation - 10] = (impersonateFamily & 0x0000FF00) >> 8;
413bytes[patchLocation - 9] = (impersonateFamily & 0x00FF0000) >> 16;
414bytes[patchLocation - 8] = (impersonateFamily & 0xFF000000) >> 24;
415
416// NOPS, just in case if the jmp call wasn't patched, we'll jump to a
417// nop and continue with the rest of the patch
418// Yay two free bytes :), 10 more can be reclamed if needed, as well as a few
419// from the above code (only cpuid_model needs to be set.
420bytes[patchLocation - 7] = 0x90;
421bytes[patchLocation - 6] = 0x90;
422
423bytes[patchLocation - 5] = 0xC7;
424bytes[patchLocation - 4] = 0x05;
425bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
426bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
427bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
428bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;
429
430// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes
431// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.
432bytes[patchLocation + 1] = impersonateModel;// cpuid_model
433bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
434bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
435bytes[patchLocation + 4] = 0x02;// cpuid_stepping
436
437}
438else if(impersonateFamily && impersonateModel)
439{
440// pre 10.6.2 kernel
441// Locate the jump to directly *after* the panic call,
442jumpLocation = patchLocation - 4;
443while((bytes[jumpLocation - 1] != 0x77 ||
444 bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) &&
445 (patchLocation - jumpLocation) < 0x20)
446{
447jumpLocation--;
448}
449// NOTE above isn't needed (I was going to use it, but I'm not, so instead,
450// I'll just leave it to verify the binary stucture.
451
452// NOTE: the cpumodel_familt data is not set in _cpuid_set_info
453// so we don't need to set it here, I'll get set later based on the model
454// we set now.
455
456if((patchLocation - jumpLocation) < 0x20)
457{
458UInt32 cpuid_model_addr =(bytes[patchLocation - 14] << 0 |
459bytes[patchLocation - 13] << 8 |
460bytes[patchLocation - 12] << 16 |
461bytes[patchLocation - 11] << 24);
462// Remove jump
463bytes[patchLocation - 9] = 0x90;/// Was a jump if supported cpu
464bytes[patchLocation - 8] = 0x90;// jumped past the panic call, we want to override the panic
465
466bytes[patchLocation - 7] = 0x90;
467bytes[patchLocation - 6] = 0x90;
468
469bytes[patchLocation - 5] = 0xC7;
470bytes[patchLocation - 4] = 0x05;
471bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
472bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
473bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
474bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;
475
476// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes
477// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.
478bytes[patchLocation + 1] = impersonateModel;// cpuid_model
479bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
480bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
481bytes[patchLocation + 4] = 0x02;// cpuid_stepping
482
483
484
485patchLocation = jumpLocation;
486// We now have 14 bytes available for a patch
487
488}
489else
490{
491// Patching failed, using NOP replacement done initialy
492}
493}
494else
495{
496// Either We were unable to change the jump call due to the function's sctructure
497// changing, or the user did not request a patch. As such, resort to just
498// removing the panic call (using NOP replacement above). Note that the
499// IntelCPUPM kext may still panic due to the cpu's Model ID not being patched
500}
501}
502
503
504/**
505 ** SleepEnabler.kext replacement (for those that need it)
506 ** Located the KERN_INVALID_ARGUMENT return and replace it with KERN_SUCCESS
507 **/
508void patch_pmCPUExitHaltToOff(void* kernelData)
509{
510UInt8* bytes = (UInt8*)kernelData;
511
512kernSymbols_t *symbol = lookup_kernel_symbol("_PmCpuExitHaltToOff");
513UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0;
514
515if(symbol == 0 || symbol->addr == 0)
516{
517printf("Unable to locate _pmCPUExitHaltToOff\n");
518return;
519}
520
521patchLocation -= (UInt32)kernelData;// Remove offset
522
523
524
525while(bytes[patchLocation - 1]!= 0xB8 ||
526 bytes[patchLocation]!= 0x04 ||// KERN_INVALID_ARGUMENT (0x00000004)
527 bytes[patchLocation + 1]!= 0x00 ||// KERN_INVALID_ARGUMENT
528 bytes[patchLocation + 2]!= 0x00 ||// KERN_INVALID_ARGUMENT
529 bytes[patchLocation + 3]!= 0x00)// KERN_INVALID_ARGUMENT
530
531{
532patchLocation++;
533}
534bytes[patchLocation] = 0x00;// KERN_SUCCESS;
535}
536
537void patch_lapic_init(void* kernelData)
538{
539
540UInt8 panicIndex = 0;
541UInt8* bytes = (UInt8*)kernelData;
542
543kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_init");
544UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0;
545if(symbol == 0 || symbol->addr == 0)
546{
547printf("Unable to locate %s\n", "_lapic_init");
548return;
549
550}
551
552symbol = lookup_kernel_symbol("_panic");
553UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0;
554if(symbol == 0 || symbol->addr == 0)
555{
556printf("Unable to locate %s\n", "_panic");
557return;
558}
559
560patchLocation -= (UInt32)kernelData;// Remove offset
561panicAddr -= (UInt32)kernelData;// Remove offset
562
563
564
565
566// Locate the (panicIndex + 1) panic call
567while(panicIndex < 3)// Find the third panic call
568{
569while(
570 (bytes[patchLocation -1] != 0xE8) ||
571 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
572bytes[patchLocation + 1] << 8 |
573bytes[patchLocation + 2] << 16 |
574bytes[patchLocation + 3] << 24)))
575 )
576{
577patchLocation++;
578}
579patchLocation++;
580panicIndex++;
581}
582patchLocation--;// Remove extra increment from the < 3 while loop
583
584bytes[--patchLocation] = 0x90;
585bytes[++patchLocation] = 0x90;
586bytes[++patchLocation] = 0x90;
587bytes[++patchLocation] = 0x90;
588bytes[++patchLocation] = 0x90;
589
590
591}
592
593
594void patch_commpage_stuff_routine(void* kernelData)
595{
596UInt8* bytes = (UInt8*)kernelData;
597
598kernSymbols_t *symbol = lookup_kernel_symbol("_commpage_stuff_routine");
599if(symbol == 0 || symbol->addr == 0)
600{
601printf("Unable to locate %s\n", "_commpage_stuff_routine");
602return;
603
604}
605
606UInt32 patchLocation = symbol->addr - textAddress + textSection;
607
608
609symbol = lookup_kernel_symbol("_panic");
610if(symbol == 0 || symbol->addr == 0)
611{
612printf("Unable to locate %s\n", "_panic");
613return;
614}
615UInt32 panicAddr = symbol->addr - textAddress;
616
617patchLocation -= (UInt32)kernelData;
618panicAddr -= (UInt32)kernelData;
619
620while(
621 (bytes[patchLocation -1] != 0xE8) ||
622 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
623bytes[patchLocation + 1] << 8 |
624bytes[patchLocation + 2] << 16 |
625bytes[patchLocation + 3] << 24)))
626 )
627{
628patchLocation++;
629}
630patchLocation--;
631
632// Replace panic with nops
633bytes[patchLocation + 0] = 0x90;
634bytes[patchLocation + 1] = 0x90;
635bytes[patchLocation + 2] = 0x90;
636bytes[patchLocation + 3] = 0x90;
637bytes[patchLocation + 4] = 0x90;
638
639
640}
641
642void patch_lapic_interrupt(void* kernelData)
643{
644UInt8* bytes = (UInt8*)kernelData;
645
646kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_interrupt");
647if(symbol == 0 || symbol->addr == 0)
648{
649printf("Unable to locate %s\n", "_lapic_interrupt");
650return;
651
652}
653
654UInt32 patchLocation = symbol->addr - textAddress + textSection;
655
656
657symbol = lookup_kernel_symbol("_panic");
658if(symbol == 0 || symbol->addr == 0)
659{
660printf("Unable to locate %s\n", "_panic");
661return;
662}
663UInt32 panicAddr = symbol->addr - textAddress;
664
665patchLocation -= (UInt32)kernelData;
666panicAddr -= (UInt32)kernelData;
667
668while(
669 (bytes[patchLocation -1] != 0xE8) ||
670 ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
671bytes[patchLocation + 1] << 8 |
672bytes[patchLocation + 2] << 16 |
673bytes[patchLocation + 3] << 24)))
674 )
675{
676patchLocation++;
677}
678patchLocation--;
679
680// Replace panic with nops
681bytes[patchLocation + 0] = 0x90;
682bytes[patchLocation + 1] = 0x90;
683bytes[patchLocation + 2] = 0x90;
684bytes[patchLocation + 3] = 0x90;
685bytes[patchLocation + 4] = 0x90;
686
687
688}
689
690
691void patch_lapic_configure(void* kernelData)
692{
693UInt8* bytes = (UInt8*)kernelData;
694
695UInt32 patchLocation;
696UInt32 lapicStart;
697UInt32 lapicInterruptBase;
698
699kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_configure");
700if(symbol == 0 || symbol->addr == 0)
701{
702printf("Unable to locate %s\n", "_lapic_configure");
703return;
704}
705patchLocation = symbol->addr - textAddress + textSection;
706
707symbol = lookup_kernel_symbol("_lapic_start");
708if(symbol == 0 || symbol->addr == 0)
709{
710printf("Unable to locate %s\n", "_lapic_start");
711return;
712}
713lapicStart = symbol->addr;
714
715
716symbol = lookup_kernel_symbol("_lapic_interrupt_base");
717if(symbol == 0 || symbol->addr == 0)
718{
719printf("Unable to locate %s\n", "_lapic_interrupt_base");
720return;
721}
722lapicInterruptBase = symbol->addr - textAddress;
723
724patchLocation -= (UInt32)kernelData;
725lapicStart -= (UInt32)kernelData;
726lapicInterruptBase -= (UInt32)kernelData;
727
728
729printf("\n\n\n\n\n\n\n"); // new lines so I can see things...
730// Looking for the following:
731//movl _lapic_start,%e_x
732//addl $0x00000360,%e_x
733// 8b 15 __ __ __ __ 81 c2 d0 00 00 00 65
734while(
735 (bytes[patchLocation - 2] != 0x8b) ||
736 //bytes[patchLocation -1] != 0x8b) ||// Register, we don't care what it is
737 ( lapicStart != (UInt32)(
738(bytes[patchLocation + 0] << 0 |
739 bytes[patchLocation + 1] << 8 |
740 bytes[patchLocation + 2] << 16 |
741 bytes[patchLocation + 3] << 24
742)
743 )
744 ) ||
745 (bytes[patchLocation + 7 ] != 0x00) ||
746 (bytes[patchLocation + 8 ] != 0x00) ||
747 (bytes[patchLocation + 9 ] != 0x00) ||
748 (bytes[patchLocation + 10] != 0x65)
749
750 )
751{
752
753printf("0x%X 0x%X 0x%X 0x%X 0x%X, 0x%X\n", bytes[patchLocation - 1], bytes[patchLocation + 0], bytes[patchLocation + 1], bytes[patchLocation + 2], bytes[patchLocation + 3], lapicStart);
754//getc();
755patchLocation++;
756}
757patchLocation-=2;
758printf("Patch location located at 0x%X\n", patchLocation);
759
760printf("0x%X 0x%X 0x%X 0x%X 0x%X, 0x%X\n", bytes[patchLocation - 0], bytes[patchLocation + 1], bytes[patchLocation + 2], bytes[patchLocation + 3], bytes[patchLocation + 4], lapicStart);
761getc();
762
763// TODO: Patch location has been located, verify that the function hasen't changed to and unpachable state
764
765
766// backup movl _lapic_interrupt_base,%e_x, so we know what the register is
767
768
769
770}
771

Archive Download this file

Revision: 442