long LoadThinFatFile(const char *fileSpec, void **binary) { const char *filePath; FSReadFile readFile; BVRef bvr; unsigned long length, length2; // Resolve the boot volume from the file spec. if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) return -1; *binary = (void *)kLoadAddr; // Read file into load buffer. The data in the load buffer will be // overwritten by the next LoadFile() call. gFSLoadAddress = (void *) LOAD_ADDR; readFile = bvr->fs_readfile; if (readFile != NULL) { // Read the first 4096 bytes (fat header) length = readFile(bvr, (char *)filePath, *binary, 0, 0x1000); if (length > 0) { if (ThinFatFile(binary, &length) == 0) { if (length == 0) return 0; // We found a fat binary; read only the thin part length = readFile(bvr, (char *)filePath, (void *)kLoadAddr, (unsigned long)(*binary) - kLoadAddr, length); *binary = (void *)kLoadAddr; } else { // Not a fat binary; read the rest of the file length2 = readFile(bvr, (char *)filePath, (void *)(kLoadAddr + length), length, 0); if (length2 == -1) return -1; length += length2; } } } else { length = bvr->fs_loadfile(bvr, (char *)filePath); if (length > 0) { ThinFatFile(binary, &length); } } return length; }
long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { long ret; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; u_int32_t uncompressed_size, size; void *buffer; #if 0 printf("kernel header:\n"); printf("signature: 0x%x\n", kernel_header->signature); printf("compress_type: 0x%x\n", kernel_header->compress_type); printf("adler32: 0x%x\n", kernel_header->adler32); printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size); printf("compressed_size: 0x%x\n", kernel_header->compressed_size); getc(); #endif if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) { error("kernel compression is bad\n"); return -1; } #if NOTDEF if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name)) return -1; if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path)) return -1; #endif uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size); binary = buffer = malloc(uncompressed_size); size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); if (uncompressed_size != size) { error("size mismatch from lzss: %x\n", size); return -1; } if (OSSwapBigToHostInt32(kernel_header->adler32) != Alder32(binary, uncompressed_size)) { printf("adler mismatch\n"); return -1; } } ThinFatFile(&binary, 0); ret = DecodeMachO(binary, rentry, raddr, rsize); return ret; }
static long LoadDriverMKext( char * fileSpec ) { unsigned long driversAddr, driversLength; long length; char segName[32]; DriversPackage * package = (DriversPackage *)kLoadAddr; #define GetPackageElement(e) OSSwapBigToHostInt32(package->e) // Load the MKext. length = LoadFile(fileSpec); if (length == -1) return -1; ThinFatFile((void **)&package, &length); // Verify the MKext. if (( GetPackageElement(signature1) != kDriverPackageSignature1) || ( GetPackageElement(signature2) != kDriverPackageSignature2) || ( GetPackageElement(length) > kLoadSize ) || ( GetPackageElement(alder32) != Alder32((char *)&package->version, GetPackageElement(length) - 0x10) ) ) { return -1; } // Make space for the MKext. driversLength = GetPackageElement(length); driversAddr = AllocateKernelMemory(driversLength); // Copy the MKext. memcpy((void *)driversAddr, (void *)package, driversLength); // Add the MKext to the memory map. sprintf(segName, "DriversPackage-%lx", driversAddr); AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT); return 0; }
long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { long ret = 0; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; u_int32_t uncompressed_size = 0, size = 0, adler32 = 0; void *buffer = NULL; unsigned long len = 0; /*#if 0 printf("kernel header:\n"); printf("signature: 0x%x\n", kernel_header->signature); printf("compress_type: 0x%x\n", kernel_header->compress_type); printf("adler32: 0x%x\n", kernel_header->adler32); printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size); printf("compressed_size: 0x%x\n", kernel_header->compressed_size); getchar(); #endif*/ if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { DBG("Decompressing Kernel: "); if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) && (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn'))) { error("ERROR: kernel compression is bad!\n"); return -1; } #if NOTDEF if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name)) { return -1; } if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path)) { return -1; } #endif uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size); binary = buffer = malloc(uncompressed_size); // MinusZwei size = 0; switch (kernel_header->compress_type) { case OSSwapBigToHostConstInt32('lzvn'): size = decompress_lzvn( binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); break; case OSSwapBigToHostConstInt32('lzss'): size = decompress_lzss( (u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); break; default: break; } // MinusZwei if (uncompressed_size != size) { if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn')) { error("ERROR: size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size); } if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss')) { error("ERROR: size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size); } return -1; } adler32 = Adler32(binary, uncompressed_size); if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32) { error("ERROR: adler mismatch (found: %x, expected: %x).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32)); return -1; } DBG("OK.\n"); } ret = ThinFatFile(&binary, &len); if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64) { archCpuType=CPU_TYPE_I386; ret = ThinFatFile(&binary, &len); } // Bungo: no range checking, sorry size = 0; while (memcmp((uint8_t *)binary + size, (uint8_t *)gDarwinBuildVerStr, 21)) { size++; } gDarwinBuildVerStr = (char *)binary + size; // Notify modules that the kernel has been decompressed, thinned and is about to be decoded execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL); ret = DecodeMachO(binary, rentry, raddr, rsize); if (ret < 0 && archCpuType == CPU_TYPE_X86_64) { archCpuType = CPU_TYPE_I386; ret = DecodeMachO(binary, rentry, raddr, rsize); } return ret; }
long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { long ret; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; u_int32_t uncompressed_size, size; void *buffer; unsigned long len; #if 0 printf("kernel header:\n"); printf("signature: 0x%x\n", kernel_header->signature); printf("compress_type: 0x%x\n", kernel_header->compress_type); printf("adler32: 0x%x\n", kernel_header->adler32); printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size); printf("compressed_size: 0x%x\n", kernel_header->compressed_size); getchar(); #endif if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) { error("kernel compression is bad\n"); return -1; } #if NOTDEF if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name)) return -1; if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path)) return -1; #endif uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size); binary = buffer = malloc(uncompressed_size); size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); if (uncompressed_size != size) { error("size mismatch from lzss: %x\n", size); return -1; } if (OSSwapBigToHostInt32(kernel_header->adler32) != Adler32(binary, uncompressed_size)) { printf("adler mismatch\n"); return -1; } } ret = ThinFatFile(&binary, &len); if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64) { archCpuType=CPU_TYPE_I386; ret = ThinFatFile(&binary, &len); } // Notify modules that the kernel has been decompressed, thinned and is about to be decoded execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL); ret = DecodeMachO(binary, rentry, raddr, rsize); if (ret<0 && archCpuType==CPU_TYPE_X86_64) { archCpuType=CPU_TYPE_I386; ret = DecodeMachO(binary, rentry, raddr, rsize); } return ret; }
long decodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { // return DecodeMachO(binary, rentry, raddr, rsize); void *buffer; long ret; unsigned long len; u_int32_t uncompressedSize, size; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; #if DEBUG_DRIVERS printf("Kernel header data.\n"); printf("===================\n"); printf("signature : 0x%08x\n", kernel_header->signature); printf("compressType : 0x%08x\n", kernel_header->compressType); printf("adler32 : 0x%08x\n", kernel_header->adler32); printf("uncompressedSize : 0x%08x\n", kernel_header->uncompressedSize); printf("compressedSize : 0x%08x\n", kernel_header->compressedSize); printf("platformName : %s\n", kernel_header->platformName); printf("rootPath : %s\n", kernel_header->rootPath); printf("Sleeping for 5 seconds...\n"); sleep(5); #endif if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { if (kernel_header->compressType != OSSwapBigToHostConstInt32('lzss')) { error("kernel compression is bad\n"); return -1; } #if NOTDEF if (kernel_header->platformName[0] && strcmp(gPlatform.ModelID, kernel_header->platformName)) { return -1; } if (kernel_header->rootPath[0] && strcmp(gBootFile, kernel_header->rootPath)) { return -1; } #endif uncompressedSize = OSSwapBigToHostInt32(kernel_header->uncompressedSize); binary = buffer = malloc(uncompressedSize); size = decompressLZSS((u_int8_t *) binary, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressedSize)); if (uncompressedSize != size) { error("Size mismatch from lzss: 0x08%x\n", size); return -1; } if (OSSwapBigToHostInt32(kernel_header->adler32) != localAdler32(binary, uncompressedSize)) { printf("Adler mismatch\n"); return -1; } } ret = ThinFatFile(&binary, &len); if (ret == 0 && len == 0 && gArchCPUType == CPU_TYPE_X86_64) { gArchCPUType = CPU_TYPE_I386; ret = ThinFatFile(&binary, &len); } ret = DecodeMachO(binary, rentry, raddr, rsize); if (ret < 0 && gArchCPUType == CPU_TYPE_X86_64) { gArchCPUType = CPU_TYPE_I386; ret = DecodeMachO(binary, rentry, raddr, rsize); } return ret; }
static long LoadMatchedModules( void ) { TagPtr prop; ModulePtr module; char *fileName, segName[32]; DriverInfoPtr driver; long length, driverAddr, driverLength; module = gModuleHead; while (module != 0) { if (module->willLoad) { prop = XMLGetProperty(module->dict, kPropCFBundleExecutable); if (prop != 0) { fileName = prop->string; sprintf(gFileSpec, "%s%s", module->driverPath, fileName); length = LoadFile(gFileSpec); } else length = 0; if (length != -1) { void *driverModuleAddr = (void *)kLoadAddr; if (length != 0) { ThinFatFile(&driverModuleAddr, &length); } // Make make in the image area. driverLength = sizeof(DriverInfo) + module->plistLength + length; driverAddr = AllocateKernelMemory(driverLength); // Set up the DriverInfo. driver = (DriverInfoPtr)driverAddr; driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo)); driver->plistLength = module->plistLength; if (length != 0) { driver->moduleAddr = (void *)(driverAddr + sizeof(DriverInfo) + module->plistLength); driver->moduleLength = length; } else { driver->moduleAddr = 0; driver->moduleLength = 0; } // Save the plist and module. strcpy(driver->plistAddr, module->plistAddr); if (length != 0) { memcpy(driver->moduleAddr, driverModuleAddr, length); } // Add an entry to the memory map. sprintf(segName, "Driver-%lx", (unsigned long)driver); AllocateMemoryRange(segName, driverAddr, driverLength, kBootDriverTypeKEXT); } } module = module->nextModule; } return 0; }