Chameleon

Chameleon Commit Details

Date:2010-05-07 08:55:39 (4 years 7 months ago)
Author:Evan Lojewski
Commit:144
Parents: 143
Message:Kernel patcher fixes. no more infinate loop...
Changes:
M/branches/meklort/i386/boot2/kernel_patcher.c
M/branches/meklort/i386/boot2/Makefile
M/branches/meklort/i386/libsaio/load.c
M/branches/meklort/i386/libsaio/hfs.c
M/branches/meklort/i386/boot2/drivers.c

File differences

branches/meklort/i386/libsaio/hfs.c
602602
603603
604604
605
605
606606
607607
608608
......
732732
733733
734734
735
735
736736
737737
738738
// Read the BTree node and get the record for index.
ReadExtent(extent, extentSize, kHFSCatalogFileID,
curNode * nodeSize, nodeSize, nodeBuf, 1);
(long long)curNode * nodeSize, nodeSize, nodeBuf, 1);
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);
GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid);
while (1) {
// Read the current node.
ReadExtent(extent, extentSize, extentFile,
curNode * nodeSize, nodeSize, nodeBuf, 1);
(long long)curNode * nodeSize, nodeSize, nodeBuf, 1);
// Find the matching key.
lowerBound = 0;
branches/meklort/i386/libsaio/load.c
3737
3838
3939
40
40
4141
4242
4343
static long DecodeSymbolTable(long cmdBase);
static unsigned long gBinaryAddress;
unsigned long gBinaryAddress;
bool gHaveKernelCache;/* XXX aserebln: uninitialized? and only set to true, never to false */
cpu_type_t archCpuType=CPU_TYPE_I386;
branches/meklort/i386/boot2/drivers.c
3838
3939
4040
41
4142
4243
4344
......
813814
814815
815816
817
818
816819
817820
818821
#include "bootstruct.h"
#include "xml.h"
#include "ramdisk.h"
#include "kernel_patcher.h"
extern char gMacOSVersion;
archCpuType=CPU_TYPE_I386;
ret = DecodeMachO(binary, rentry, raddr, rsize);
}
patch_kernel();
return ret;
}
branches/meklort/i386/boot2/kernel_patcher.c
2929
3030
3131
32
33
32
33
3434
3535
3636
......
4242
4343
4444
45
4546
4647
4748
......
5556
5657
5758
58
59
5960
6061
62
6163
6264
6365
6466
6567
6668
67
6869
6970
7071
......
7273
7374
7475
76
7577
7678
7779
......
9294
9395
9496
97
9598
9699
97100
......
135138
136139
137140
141
138142
139143
140144
......
157161
158162
159163
164
160165
161166
162167
......
189194
190195
191196
192
197
193198
194199
195200
......
207212
208213
209214
215
210216
211217
212218
213219
214220
215
221
216222
217223
224
225
226
227
228
229
230
231
232
233
234
218235
219
220236
221237
222238
......
228244
229245
230246
247
231248
232249
233250
......
237254
238255
239256
240
241
242257
243258
259
244260
245261
246262
247263
248264
249265
250
266
251267
252268
269
270
271
272
273
274
253275
254276
255277
......
260282
261283
262284
263
264285
};
UInt32 textSection;
UInt32 textAddress;
UInt32 textSection = 0;
UInt32 textAddress = 0;
extern unsigned long gBinaryAddress;
case KERNEL_32:
patch_kernel_32((void*)gBinaryAddress);
break;
case KERNEL_64:
default:
patch_kernel_64((void*)gBinaryAddress);
// At the moment, the kernel patching code fails when used
// in 64bit mode, so we don't patch it. This is due to 32bit vs 64bit
// pointers as well as changes in structure sizes
verbose("Unable to patch 64bit kernel. Please use arch=i386.\n");
printf("Unable to patch 64bit kernel. Please use arch=i386.\n");
}
/**
** patch_kernel_32
**Due to the way the _cpuid_set_info function is writtin, the first instance of _panic is called
**when an unsupported (read: non apple used cpu) is found. This routine locates that first _panic call
**and replaces the jump call (0xe8) with no ops (0x90).
**/
void patch_kernel_32(void* kernelData)
{
patch_pmCPUExitHaltToOff(kernelData);
}
/**
**This functions located the following in the mach_kernel symbol table
**_panic
if(((struct mach_header*)kernelData)->magic != MH_MAGIC) return KERNEL_64;
//printf("%d load commands beginning at 0x%X\n", (unsigned int)header->ncmds, (unsigned int)kernelIndex);
//printf("Commands take up %d bytes\n", header->sizeofcmds);
symbolIndexes[i] = symbolIndex;
numSymbolsFound++;
}
i++;
}
symbolString += strlen(symbolString) + 1;
kernelSymbolAddresses[i] = (UInt32)symbolEntry->n_value;
numSymbolsFound++;
}
i++;
}
if(strcmp("__text", sect->sectname) == 0)
{
// __TEXT,__text found, save the offset and address for when looking for the panic call.
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
break;
return KERNEL_32;
}
/**
** Locate the fisrt instance of _panic inside of _cpuid_set_info, and remove it
**/
void patch_cpuid_set_info(void* kernelData)
{
UInt8* bytes = (void*)kernelData;
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = (kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
UInt32 panidAddr = kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
if(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] == 0)
{
printf("Unable to locate _cpuid_set_info\n");
return;
}
if(kernelSymbolAddresses[SYMBOL_PANIC] == 0)
{
printf("Unable to locate _panic\n");
return;
}
//TODO: don't assume it'll always work (Look for *next* function address in symtab and fail once it's been reached)
while(
(bytes[patchLocation -1] != 0xE8) ||
// (patchLocation < maxLocation)// max location is not known... assuming there is a panic call somewhere after cpuid_set_info
)
{
//printf("Looking at 0x%X\n", patchLocation);
patchLocation++;
}
bytes[patchLocation + 1] = 0x90;
bytes[patchLocation + 2] = 0x90;
bytes[patchLocation + 3] = 0x90;
// Patching finished
}
/**
** SleepEnabler.kext replacement (for those that need it)
** Located the KERN_INVALID_ARGUMENT return and replace it with KERN_SUCCESS
**/
void patch_pmCPUExitHaltToOff(void* kernelData)
{
UInt8* bytes = (void*)kernelData;
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = (kernelSymbolAddresses[SYMBOL_PMCPUEXITHALTTOOFF] - textAddress + textSection);
if(kernelSymbolAddresses[SYMBOL_PMCPUEXITHALTTOOFF] == 0)
{
printf("Unable to locate _pmCPUExitHaltToOff\n");
return;
}
while(bytes[patchLocation - 1]!= 0xB8 ||
bytes[patchLocation]!= 0x04 ||// KERN_INVALID_ARGUMENT (0x00000004)
bytes[patchLocation + 1]!= 0x00 ||// KERN_INVALID_ARGUMENT
patchLocation++;
}
bytes[patchLocation] = 0x00;// KERN_SUCCESS;
}
branches/meklort/i386/boot2/Makefile
4242
4343
4444
45
45
4646
4747
4848
# The ordering is important;
# boot2.o must be first.
OBJS = boot2.o boot.o graphics.o drivers.o prompt.o options.o lzss.o mboot.o \
ramdisk.o picopng.o resume.o bmdecompress.o graphic_utils.o gui.o
ramdisk.o kernel_patcher.o picopng.o resume.o bmdecompress.o graphic_utils.o gui.o
# button.o browser.o scrollbar.o == NOTYET
UTILDIR = ../util

Archive Download the corresponding diff file

Revision: 144