Chameleon

Chameleon Svn Source Tree

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

Source at commit 444 created 13 years 10 months ago.
By zef, Fixed calling getBootVolumeDescription() with properly adjusted strMaxLen values. Removed broken optionKey setting. Now using strncat() for adding proper NULL termination in destination strings.
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: 444