Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch/i386/boot2/drivers.c

1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * drivers.c - Driver Loading Functions.
26 *
27 * Copyright (c) 2000 Apple Computer, Inc.
28 *
29 * DRI: Josh de Cesare
30 */
31
32#include <mach-o/fat.h>
33#include <libkern/OSByteOrder.h>
34#include <mach/machine.h>
35
36#include "config.h"
37#include "sl.h"
38#include "boot.h"
39#include "bootstruct.h"
40#include "xml.h"
41#include "ramdisk.h"
42#include "kernel_patcher_internal.h"
43#include "modules.h"
44
45#if FAKESMC_SUPPORT
46#include "FakeSMC.h"
47#include "FakeSMCInfo.plist.h"
48#endif
49
50#if DEBUG
51#define DBG(x...)printf(x)
52#else
53#define DBG(x...)msglog(x)
54#endif
55
56bool gUseCommonAndOSdir = true;
57
58struct Module {
59struct Module *nextModule;
60long willLoad;
61TagPtr dict;
62char *plistAddr;
63long plistLength;
64char *executablePath;
65char *bundlePath;
66long bundlePathLength;
67};
68typedef struct Module Module, *ModulePtr;
69
70struct DriverInfo {
71char *plistAddr;
72long plistLength;
73void *executableAddr;
74long executableLength;
75void *bundlePathAddr;
76long bundlePathLength;
77};
78typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
79
80#define kDriverPackageSignature1 'MKXT'
81#define kDriverPackageSignature2 'MOSX'
82
83struct DriversPackage {
84unsigned long signature1;
85unsigned long signature2;
86unsigned long length;
87unsigned long adler32;
88unsigned long version;
89unsigned long numDrivers;
90unsigned long reserved1;
91unsigned long reserved2;
92};
93typedef struct DriversPackage DriversPackage;
94
95enum {
96kCFBundleType2,
97kCFBundleType3
98};
99
100long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);
101
102static inline unsigned long Adler32( unsigned char * buffer, long length );
103
104long FileLoadDrivers(char *dirSpec, long plugin);
105long NetLoadDrivers(char *dirSpec);
106long LoadDriverMKext(char *fileSpec);
107long LoadDriverPList(char *dirSpec, char *name, long bundleType);
108
109#if FAKESMC_SUPPORT
110void loadEmbeddedFakeSMC(void);
111#endif
112
113long LoadEmbeddedKext( char *InjectorPlist, size_t length, char *name );
114long LoadMatchedModules(void);
115void buildAndLoadInjectorPList(void);
116static long MatchPersonalities(void);
117static long MatchLibraries(void);
118
119#ifdef NOTDEF
120static ModulePtr FindModule(char *name);
121static void ThinFatFile(void **loadAddrP, unsigned long *lengthP);
122#endif
123
124bool isKextForcedToLoad(char *kext);
125static long ParseXML(char *buffer, ModulePtr *module, TagPtr *personalities, bool forceKextToLoad);
126static long InitDriverSupport(void);
127
128ModulePtr gModuleHead, gModuleTail;
129static TagPtrgPersonalityHead, gPersonalityTail;
130static char*gExtensionsSpec;
131static char*gDriverSpec;
132static char*gFileSpec;
133static char*gTempSpec;
134static char*gFileName;
135// Bungo:
136char gDarwinBuildVerStr[256] = "Darwin Kernel Version";
137
138static inline unsigned long Adler32( unsigned char *buffer, long length )
139{
140long cnt;
141unsigned long result, lowHalf, highHalf;
142
143lowHalf = 1;
144highHalf = 0;
145
146for (cnt = 0; cnt < length; cnt++)
147{
148if ((cnt % 5000) == 0)
149{
150lowHalf %= 65521L;
151highHalf %= 65521L;
152}
153
154lowHalf += buffer[cnt];
155highHalf += lowHalf;
156}
157
158lowHalf %= 65521L;
159highHalf %= 65521L;
160
161result = (highHalf << 16) | lowHalf;
162
163return result;
164}
165
166//==========================================================================
167// InitDriverSupport
168static long InitDriverSupport( void )
169{
170gExtensionsSpec = malloc( 4096 );
171gDriverSpec = malloc( 4096 );
172gFileSpec = malloc( 4096 );
173gTempSpec = malloc( 4096 );
174gFileName = malloc( 4096 );
175
176if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )
177{
178stop("InitDriverSupport error");
179}
180
181return 0;
182}
183
184//==========================================================================
185// LoadDrivers
186long LoadDrivers( char *dirSpec )
187{
188char dirSpecExtra[1024];
189long flags, ret=-1;
190u_int32_t time;
191
192if ( InitDriverSupport() != 0 )
193{
194return 0;
195}
196
197// ========================================
198gUseCommonAndOSdir = false; // old behavior
199
200ret = GetFileInfo("bt(0,0)/Extra/Extensions/", "Common", &flags, &time);
201
202// if the boot partition contains /Extra/Extensions/Common there is no need
203// to look else where because users will have also /Extra/Extensions/10.x
204if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory))
205{
206gUseCommonAndOSdir = true;
207verbose("/Extra/Extensions/Common and /Extra/Extensions/%s in use.\n", gBootVolume->OSVersion);
208//getchar();
209}
210// ========================================
211
212// Load extra drivers if a hook has been installed.
213if (LoadExtraDrivers_p != NULL)
214{
215(*LoadExtraDrivers_p)(&FileLoadDrivers);
216}
217
218if ( gBootFileType == kNetworkDeviceType )
219{
220if (NetLoadDrivers(dirSpec) != 0)
221{
222error("LoadDrivers: Could not load drivers from the network\n");
223return -1;
224}
225}
226else if ( gBootFileType == kBlockDeviceType )
227{
228// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
229if (gRAMDiskVolume && !gRAMDiskBTAliased)
230{
231strcpy(dirSpecExtra, "rd(0,0)/Extra/");
232FileLoadDrivers(dirSpecExtra, 0);
233}
234// =====================================================================
235// Secondly try to load drivers from Common folder if in use
236if (gUseCommonAndOSdir)
237{
238sprintf(dirSpecExtra, "bt(0,0)/Extra/Extensions/Common");
239FileLoadDrivers(dirSpecExtra, 0);
240}
241// =====================================================================
242
243// Next try to load Extra extensions from the selected root partition.
244if (gUseCommonAndOSdir)
245{
246sprintf(dirSpecExtra, "bt(0,0)/Extra/Extensions/%s", gBootVolume->OSVersion);
247FileLoadDrivers(dirSpecExtra, 0);
248//verbose("gUseCommonAndOSdir = %s\n", dirSpecExtra);
249//getchar();
250}
251else
252{
253strlcpy(dirSpecExtra, "/Extra/", sizeof(dirSpecExtra));
254if (FileLoadDrivers(dirSpecExtra, 0) != 0)
255{
256// If failed, then try to load Extra extensions from the boot partition
257// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.
258if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)
259|| (gRAMDiskVolume && gRAMDiskBTAliased) )
260{
261// Next try a specfic OS version folder ie 10.12
262sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion[0]);
263if (FileLoadDrivers(dirSpecExtra, 0) != 0)
264{
265// Next we'll try the base
266strlcpy(dirSpecExtra, "bt(0,0)/Extra/", sizeof(dirSpecExtra));
267FileLoadDrivers(dirSpecExtra, 0);
268}
269}
270}
271}
272
273if(!gHaveKernelCache)
274{
275// Don't load main driver (from /System/Library/Extentions) if gHaveKernelCache is set.
276// since these drivers will already be in the kernel cache.
277// NOTE: when gHaveKernelCache, xnu cannot (by default) load *any* extra kexts from the bootloader.
278// The /Extra code is not disabled in this case due to a kernel patch that allows for this to happen.
279
280// Also try to load Extensions from boot helper partitions.
281if (gBootVolume->flags & kBVFlagBooter)
282{
283strlcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/", sizeof(dirSpecExtra));
284if (FileLoadDrivers(dirSpecExtra, 0) != 0)
285{
286strlcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/", sizeof(dirSpecExtra));
287if (FileLoadDrivers(dirSpecExtra, 0) != 0)
288{
289strlcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/", sizeof(dirSpecExtra));
290FileLoadDrivers(dirSpecExtra, 0);
291}
292}
293}
294
295if (gMKextName[0] != '\0')
296{
297verbose("LoadDrivers: Loading from '%s'\n", gMKextName);
298if ( LoadDriverMKext(gMKextName) != 0 )
299{
300error("Could not load %s\n", gMKextName);
301return -1;
302}
303}
304else
305{
306verbose("Attempting to load drivers from standard repositories:\n");
307
308if ( (gMacOSVersion[3] == '9') || ((gMacOSVersion[3] == '1') && ((gMacOSVersion[4] == '0') || (gMacOSVersion[4] == '1') || (gMacOSVersion[4] == '2') ) )) // issue 352
309{
310verbose("\t- Third party extensions search path: /Library/Extensions\n");
311strlcpy(gExtensionsSpec, dirSpec, 4087); /* 4096 - sizeof("Library/") mean 4096 - 9 = 4087 */
312strcat(gExtensionsSpec, gUseCommonAndOSdir ? "Library/Extensions" : "Library/");
313FileLoadDrivers(gExtensionsSpec, 0);
314}
315
316verbose("\t- Apple extensions search path: /System/Library/Extensions\n");
317strlcpy(gExtensionsSpec, dirSpec, 4080); /* 4096 - sizeof("System/Library/") mean 4096 -16 = 4080 */
318strcat(gExtensionsSpec, gUseCommonAndOSdir ? "System/Library/Extensions" : "System/Library/");
319FileLoadDrivers(gExtensionsSpec, 0);
320}
321
322}
323}
324else
325{
326return 0;
327}
328
329#if FAKESMC_SUPPORT
330if (!FakeSMCLoaded && archCpuType != CPU_TYPE_I386)
331{
332loadEmbeddedFakeSMC();
333}
334#endif
335
336buildAndLoadInjectorPList();
337
338MatchPersonalities();
339
340MatchLibraries();
341
342LoadMatchedModules();
343
344return 0;
345}
346
347//==========================================================================
348// FileLoadMKext
349static long FileLoadMKext( const char *dirSpec, const char *extDirSpec )
350{
351longret, flags;
352u_int32_ttime, time2;
353charaltDirSpec[512];
354
355snprintf(altDirSpec, sizeof(altDirSpec), "%s%s", dirSpec, extDirSpec);
356ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);
357
358if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
359{
360ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
361
362if ((ret != 0)
363|| ((flags & kFileTypeMask) != kFileTypeDirectory)
364|| (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
365{
366snprintf(gDriverSpec, sizeof(altDirSpec) + 18, "%sExtensions.mkext", altDirSpec);
367verbose("LoadDrivers: Loading from '%s'\n", gDriverSpec);
368
369if (LoadDriverMKext(gDriverSpec) == 0)
370{
371return 0;
372}
373}
374}
375return -1;
376}
377
378//==========================================================================
379// FileLoadDrivers
380long FileLoadDrivers( char *dirSpec, long plugin )
381{
382long longindex;
383longret, length, flags, bundleType;
384longresult = -1;
385u_int32_ttime;
386const char* name;
387
388if ( !plugin )
389{
390// First try 10.6's path for loading Extensions.mkext.
391if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0) {
392return 0;
393}
394
395// Next try the legacy path.
396else if (FileLoadMKext(dirSpec, "") == 0)
397{
398return 0;
399}
400
401if (!gUseCommonAndOSdir)
402{
403// means that we already provide a full path to the Extensions directory
404strcat(dirSpec, "Extensions");
405}
406}
407
408index = 0;
409while (1)
410{
411ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
412if (ret == -1) {
413break;
414}
415
416// Make sure this is a directory.
417if ((flags & kFileTypeMask) != kFileTypeDirectory)
418{
419continue;
420}
421
422// Make sure this is a kext.
423length = strlen(name);
424if (strncmp(name + length - 5, ".kext", sizeof(".kext") ))
425{
426continue;
427}
428
429// Save the file name.
430strlcpy(gFileName, name, 4096);
431
432// Determine the bundle type.
433snprintf(gTempSpec, 4096, "%s/%s", dirSpec, gFileName);
434ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
435if (ret == 0)
436{
437bundleType = kCFBundleType2;
438}
439else
440{
441bundleType = kCFBundleType3;
442}
443
444if (!plugin)
445{
446snprintf(gDriverSpec, 4096, "%s/%s/%sPlugIns", dirSpec, gFileName, (bundleType == kCFBundleType2) ? "Contents/" : "");
447}
448
449ret = LoadDriverPList(dirSpec, gFileName, bundleType);
450
451if (result != 0)
452{
453result = ret;
454}
455
456if (!plugin)
457{
458FileLoadDrivers(gDriverSpec, 1);
459}
460}
461
462return result;
463}
464
465//==========================================================================
466//
467long NetLoadDrivers( char *dirSpec )
468{
469long tries;
470
471#if NODEF
472long cnt;
473
474// Get the name of the kernel
475cnt = strlen(gBootFile);
476while (cnt--) {
477if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ','))
478{
479cnt++;
480break;
481}
482}
483#endif
484
485// INTEL modification
486snprintf(gDriverSpec, 4096, "%s%s.mkext", dirSpec, bootInfo->bootFile);
487
488verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);
489
490tries = 3;
491while (tries--)
492{
493if (LoadDriverMKext(gDriverSpec) == 0)
494{
495break;
496}
497}
498if (tries == -1)
499{
500return -1;
501}
502
503return 0;
504}
505
506//==========================================================================
507// loadDriverMKext
508long LoadDriverMKext( char *fileSpec )
509{
510unsigned longdriversAddr, driversLength;
511longlength;
512charsegName[32];
513DriversPackage*package;
514
515#define GetPackageElement(e) OSSwapBigToHostInt32(package->e)
516
517// Load the MKext.
518length = LoadThinFatFile(fileSpec, (void **)&package);
519if (length < sizeof (DriversPackage))
520{
521return -1;
522}
523
524// call hook to notify modules that the mkext has been loaded
525execute_hook("LoadDriverMKext", (void *)fileSpec, (void *)package, (void *) &length, NULL);
526
527
528// Verify the MKext.
529if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
530( GetPackageElement(signature2) != kDriverPackageSignature2) ||
531( GetPackageElement(length) > kLoadSize ) ||
532( GetPackageElement(adler32) !=
533Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
534{
535return -1;
536}
537
538// Make space for the MKext.
539driversLength = GetPackageElement(length);
540driversAddr = AllocateKernelMemory(driversLength);
541
542// Copy the MKext.
543memcpy((void *)driversAddr, (void *)package, driversLength);
544
545// Add the MKext to the memory map.
546snprintf(segName, sizeof(segName), "DriversPackage-%lx", driversAddr);
547AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);
548
549return 0;
550}
551
552//==========================================================================
553// buildAndLoadInjectorPList
554void buildAndLoadInjectorPList(void)
555{
556TagPtr PersTag = NULL;
557if ((PersTag = XMLCastDict(XMLGetProperty(bootInfo->kextConfig.dictionary, (const char *)"PersonalitiesInjector"))))
558{
559unsigned long count = XMLTagCount(PersTag);
560if (count)
561{
562verbose("Attempting to generate and load custom injectors kexts:\n");
563}
564
565while(count)
566{
567bool canLoad = false;
568//int length = 0;
569char *kextName = strdup(XMLCastString(XMLGetKey(PersTag, count)));
570
571TagPtr sub = XMLGetProperty(PersTag, kextName);
572
573if (sub && XMLIsDict(sub))
574{
575TagPtr IOKPTag = NULL;
576char *MatchOS = NULL;
577char *Comment = NULL;
578char *OSBundleRequired = NULL;
579IOKPTag = XMLGetProperty(sub, (const char*)"IOKitPersonalities");
580Comment = XMLCastString(XMLGetProperty(sub, (const char*)"Comment"));
581MatchOS = XMLCastString(XMLGetProperty(sub, (const char*)"MatchOS"));
582OSBundleRequired = XMLCastString(XMLGetProperty(sub, (const char*)"OSBundleRequired"));
583
584Comment = (Comment != NULL && strlen(Comment) >0) ? Comment : "untitled";
585MatchOS = (MatchOS != NULL && strlen(MatchOS) >0) ? MatchOS : "";
586OSBundleRequired = (OSBundleRequired != NULL && strlen(OSBundleRequired) >0) ? OSBundleRequired : "";
587canLoad = true;
588
589if (strlen(MatchOS))
590{
591// check MatchOS and disable this patch if does not match
592canLoad = IsPatchEnabled(MatchOS, (char *)gMacOSVersion);
593}
594else
595{
596MatchOS = "not set";
597}
598
599if (canLoad)
600{
601if (XMLIsDict(IOKPTag))
602{
603char *inj= XMLGenerateKextInjectorFromTag(IOKPTag, kextName, OSBundleRequired);
604
605if (inj != NULL && strlen(inj))
606{
607verbose("\t- Loading %s.kext (%s) MatchOS[ %s ]: ", kextName, Comment, MatchOS);
608verbose("%s!\n", (LoadEmbeddedKext( inj, strlen(inj)+1, kextName ) == 0) ? "success" : "failed");
609}
610else
611{
612verbose("\t- Error building %s personality, skipped\n", kextName);
613}
614}
615else
616{
617verbose("\t- skipping %s personality (%s) MatchOS[ %s ]: not a dictionary\n", kextName, Comment, MatchOS);
618}
619}
620else
621{
622verbose("\t- skipping %s personality (%s) MatchOS[ %s ]\n", kextName, Comment, MatchOS);
623}
624}
625count--;
626}
627}
628}
629//==========================================================================
630// loadEmbeddedFakeSMC
631#if FAKESMC_SUPPORT
632void loadEmbeddedFakeSMC(void)
633{
634void *embedded = NULL;
635
636embedded = malloc(FakeSMCInfo_plist_un_len); // don't free, will be done in LoadEmbeddedKext
637if (embedded == NULL) {
638return;
639}
640
641
642size_t size = lzvn_decode(embedded,
643 FakeSMCInfo_plist_un_len,
644 FakeSMCInfo_plist,
645 FakeSMCInfo_plist_lzvn_len);
646
647if (FakeSMCInfo_plist_un_len != size)
648{
649verbose("\n\t ERROR! FakeSMC size mismatch from lzvn (found: %zx, expected: %zx), failed!\n", size, FakeSMCInfo_plist_un_len);
650free(embedded);
651}
652else
653{
654LoadEmbeddedKext((char *)embedded, size, "EmbeddedFakeSMC" );
655}
656}
657#endif
658
659//==========================================================================
660// LoadEmbeddedKext
661long LoadEmbeddedKext( char *InjectorPlist, size_t length, char *name )
662{
663longexecutablePathLength, bundlePathLength;
664ModulePtrmodule;
665TagPtrpersonalities;
666char*tmpExecutablePath = 0;
667char*tmpBundlePath = 0;
668char*realAddr = NULL;
669longret = -1;
670
671do {
672snprintf(gFileSpec, 4096, "%s/%s.kext/%s", "/System/Library/Extensions", name, "Contents/MacOS/");
673executablePathLength = strlen(gFileSpec) + 1;
674
675tmpExecutablePath = malloc(executablePathLength);
676
677if (tmpExecutablePath == 0)
678{
679break;
680}
681
682strlcpy(tmpExecutablePath, gFileSpec, executablePathLength);
683snprintf(gFileSpec, 4096, "%s/%s.kext", "/System/Library/Extensions", name);
684bundlePathLength = strlen(gFileSpec) + 1;
685
686tmpBundlePath = malloc(bundlePathLength);
687
688if (tmpBundlePath == 0)
689{
690break;
691}
692
693strlcpy(tmpBundlePath, gFileSpec, bundlePathLength);
694
695// Construct the file spec to the plist, then load it.
696snprintf(gFileSpec, 4096, "%s/%s.kext/Contents/Info.plist", "/System/Library/Extensions", name);
697
698// bug, after ParseXML something weired happened to InjectorPlist. Making a copy
699realAddr = malloc(length);
700strlcpy(realAddr, InjectorPlist, length);
701ret = ParseXML((char *)InjectorPlist, &module, &personalities, true);
702
703if (ret != 0)
704{
705break;
706}
707
708if (!module) // cparm
709{
710ret = -1;
711break;
712} // Should never happen but it will make the compiler happy
713
714// Allocate memory for the driver path and the plist.
715module->executablePath = tmpExecutablePath;
716module->bundlePath = tmpBundlePath;
717module->bundlePathLength = bundlePathLength;
718
719module->plistAddr = malloc(length);
720
721if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
722{
723verbose("(executablePath or bundlePath or plistAddr are 0) ");
724ret = -1;
725break;
726}
727
728tmpExecutablePath = 0;
729tmpBundlePath = 0;
730
731strlcpy(module->plistAddr, realAddr, length);
732module->plistLength = length;
733// Add the module to the end of the module list.
734
735if (gModuleHead == 0)
736{
737gModuleHead = module;
738}
739else
740{
741gModuleTail->nextModule = module;
742}
743gModuleTail = module;
744
745// Add the persionalities to the personality list.
746if (personalities)
747{
748personalities = personalities->tag;
749}
750while (personalities != 0)
751{
752if (gPersonalityHead == 0)
753{
754gPersonalityHead = personalities->tag;
755}
756else
757{
758gPersonalityTail->tagNext = personalities->tag;
759}
760
761gPersonalityTail = personalities->tag;
762personalities = personalities->tagNext;
763}
764ret = 0;
765
766}while (0);
767
768if (realAddr)
769{
770free(realAddr);
771}
772
773if ( strlen(InjectorPlist) )
774{
775free( InjectorPlist );
776}
777
778if ( tmpExecutablePath )
779{
780free( tmpExecutablePath );
781}
782
783if ( tmpBundlePath )
784{
785free( tmpBundlePath );
786}
787return ret;
788}
789
790//==========================================================================
791// LoadDriverPList
792long LoadDriverPList( char *dirSpec, char *name, long bundleType )
793{
794longlength, executablePathLength, bundlePathLength;
795ModulePtrmodule;
796TagPtrpersonalities;
797char*buffer = 0;
798char*tmpExecutablePath = 0;
799char*tmpBundlePath = 0;
800longret = -1;
801
802do {
803// Save the driver path.
804
805if(name)
806{
807if (!strcmp(name, "FakeSMC.kext")) {
808FakeSMCLoaded = true;
809}
810snprintf(gFileSpec, 4096, "%s/%s/%s", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
811}
812else
813{
814snprintf(gFileSpec, 4096, "%s/%s", dirSpec, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
815}
816executablePathLength = strlen(gFileSpec) + 1;
817
818tmpExecutablePath = malloc(executablePathLength);
819if (tmpExecutablePath == 0) {
820break;
821}
822strlcpy(tmpExecutablePath, gFileSpec, executablePathLength);
823
824if(name)
825{
826snprintf(gFileSpec, 4096, "%s/%s", dirSpec, name);
827}
828else
829{
830strncpy(gFileSpec, dirSpec, 4096);
831}
832bundlePathLength = strlen(gFileSpec) + 1;
833
834tmpBundlePath = malloc(bundlePathLength);
835if (tmpBundlePath == 0)
836{
837break;
838}
839
840strlcpy(tmpBundlePath, gFileSpec, bundlePathLength);
841
842// Construct the file spec to the plist, then load it.
843
844if(name)
845{
846snprintf(gFileSpec, 4096, "%s/%s/%sInfo.plist", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/" : "");
847}
848else
849{
850snprintf(gFileSpec, 4096, "%s/%sInfo.plist", dirSpec, (bundleType == kCFBundleType2) ? "Contents/" : "");
851}
852
853length = LoadFile(gFileSpec);
854
855if (length == -1)
856{
857break;
858}
859
860length = length + 1;
861buffer = malloc(length);
862
863if (buffer == 0)
864{
865break;
866}
867
868strlcpy(buffer, (char *)kLoadAddr, length);
869
870// Parse the plist.
871
872ret = ParseXML(buffer, &module, &personalities, isKextForcedToLoad(name));
873
874if (ret != 0) {
875break;
876}
877
878if (!module) // cparm
879{
880ret = -1;
881break;
882} // Should never happen but it will make the compiler happy
883
884// Allocate memory for the driver path and the plist.
885
886module->executablePath = tmpExecutablePath;
887module->bundlePath = tmpBundlePath;
888module->bundlePathLength = bundlePathLength;
889module->plistAddr = malloc(length);
890
891if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
892{
893verbose("%s: executablePath or bundlePath or plistAddr are 0\n", name);
894break;
895}
896
897// Save the driver path in the module.
898//strcpy(module->driverPath, tmpDriverPath);
899tmpExecutablePath = 0;
900tmpBundlePath = 0;
901
902// Add the plist to the module.
903
904strlcpy(module->plistAddr, (char *)kLoadAddr, length);
905module->plistLength = length;
906
907// Add the module to the end of the module list.
908
909if (gModuleHead == 0) {
910gModuleHead = module;
911} else {
912gModuleTail->nextModule = module;
913}
914gModuleTail = module;
915
916// Add the persionalities to the personality list.
917
918if (personalities) {
919personalities = personalities->tag;
920}
921while (personalities != 0)
922{
923if (gPersonalityHead == 0) {
924gPersonalityHead = personalities->tag;
925} else {
926gPersonalityTail->tagNext = personalities->tag;
927}
928
929gPersonalityTail = personalities->tag;
930personalities = personalities->tagNext;
931}
932
933ret = 0;
934}
935while (0);
936
937if ( buffer ) {
938free( buffer );
939}
940if ( tmpExecutablePath ) {
941free( tmpExecutablePath );
942}
943if ( tmpBundlePath ) {
944free( tmpBundlePath );
945}
946return ret;
947}
948
949//==========================================================================
950// LoadMatchedModules
951long LoadMatchedModules( void )
952{
953TagPtrprop;
954ModulePtrmodule;
955char*fileName, segName[32];
956DriverInfoPtrdriver;
957longlength, driverAddr, driverLength;
958void*executableAddr = 0;
959void*embedded = 0;
960
961module = gModuleHead;
962
963TagPtr KextsPatches = XMLGetProperty(bootInfo->kextConfig.dictionary, (const char*)"KextsPatches");
964
965while (module != 0)
966{
967if (module->willLoad)
968{
969prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);
970
971if (prop != 0)
972{
973fileName = prop->string;
974snprintf(gFileSpec, 4096, "%s%s", module->executablePath, fileName);
975
976#if FAKESMC_SUPPORT
977if (!strcmp(fileName, "EmbeddedFakeSMC"))
978{
979verbose("\t Loading embedded FakeSMC: ");
980embedded = malloc(FakeSMC_un_len);
981size_t size = lzvn_decode(embedded, FakeSMC_un_len, FakeSMC, FakeSMC_lzvn_len );
982
983if (FakeSMC_un_len != size)
984{
985verbose("\n\t ERROR! FakeSMC size mismatch from lzvn (found: %zx, expected: %zx), failed!\n", size, FakeSMC_un_len);
986length = -1;
987}
988else
989{
990length = size;
991// no need to Thin this kext
992//memcpy((void *)kLoadAddr, embedded, length);
993//ThinFatFile(embedded, &length);
994executableAddr = (void *)embedded;
995verbose("%s!\n", ((length != -1) && executableAddr) ? "success" : "failed");
996}
997}
998else
999{
1000#endif
1001length = LoadThinFatFile(gFileSpec, &executableAddr);
1002if (length == 0)
1003{
1004length = LoadFile(gFileSpec);
1005executableAddr = (void *)kLoadAddr;
1006}
1007#if FAKESMC_SUPPORT
1008}
1009#endif
1010//printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getchar();
1011}
1012else
1013{
1014length = 0;
1015}
1016
1017if ((length != -1) && executableAddr)
1018{
1019// patching kexts executable
1020if (!skipKextsPatcher)
1021{
1022// chameleon patches
1023patchBooterDefinedKext(fileName, executableAddr, (UInt32)length, 0);
1024// user's patches
1025if (KextsPatches && XMLIsDict(KextsPatches))
1026{
1027pach_binaryUsingDictionary(executableAddr, (UInt32)length, 0, fileName, KextsPatches);
1028}
1029}
1030
1031// Make make in the image area.
1032
1033execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
1034
1035driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
1036driverAddr = AllocateKernelMemory(driverLength);
1037
1038// Set up the DriverInfo.
1039driver = (DriverInfoPtr)driverAddr;
1040driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
1041driver->plistLength = module->plistLength;
1042
1043if (length != 0)
1044{
1045driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
1046 module->plistLength);
1047driver->executableLength = length;
1048}
1049else
1050{
1051driver->executableAddr = 0;
1052driver->executableLength = 0;
1053}
1054
1055driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
1056 module->plistLength + driver->executableLength);
1057driver->bundlePathLength = module->bundlePathLength;
1058
1059// Save the plist, module and bundle.
1060strlcpy(driver->plistAddr, module->plistAddr, driver->plistLength);
1061
1062if (length != 0)
1063{
1064memcpy(driver->executableAddr, executableAddr, length);
1065}
1066
1067strlcpy(driver->bundlePathAddr, module->bundlePath, module->bundlePathLength);
1068
1069// Add an entry to the memory map.
1070snprintf(segName, sizeof(segName), "Driver-%lx", (unsigned long)driver);
1071AllocateMemoryRange(segName, driverAddr, driverLength,
1072kBootDriverTypeKEXT);
1073}
1074}
1075module = module->nextModule;
1076}
1077
1078if(embedded)
1079{
1080free(embedded);
1081}
1082return 0;
1083}
1084
1085//==========================================================================
1086// MatchPersonalities
1087static long MatchPersonalities( void )
1088{
1089/* IONameMatch support not implemented */
1090return 0;
1091}
1092
1093//==========================================================================
1094// MatchLibraries
1095static long MatchLibraries( void )
1096{
1097TagPtr prop;
1098TagPtr prop2;
1099ModulePtr module;
1100ModulePtr module2;
1101long done;
1102
1103do {
1104done = 1;
1105module = gModuleHead;
1106
1107while (module != 0)
1108{
1109if (module->willLoad == 1)
1110{
1111prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
1112
1113if (prop != 0)
1114{
1115prop = prop->tag;
1116
1117while (prop != 0)
1118{
1119module2 = gModuleHead;
1120
1121while (module2 != 0)
1122{
1123prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
1124
1125if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
1126{
1127if (module2->willLoad == 0)
1128{
1129module2->willLoad = 1;
1130}
1131break;
1132}
1133module2 = module2->nextModule;
1134}
1135prop = prop->tagNext;
1136}
1137}
1138module->willLoad = 2;
1139done = 0;
1140}
1141module = module->nextModule;
1142}
1143}
1144while (!done);
1145
1146return 0;
1147}
1148
1149//==========================================================================
1150// FindModule
1151
1152#if NOTDEF
1153static ModulePtr FindModule( char *name )
1154{
1155ModulePtr module;
1156TagPtr prop;
1157
1158module = gModuleHead;
1159
1160while (module != 0)
1161{
1162prop = GetProperty(module->dict, kPropCFBundleIdentifier);
1163
1164if ((prop != 0) && !strcmp(name, prop->string))
1165{
1166break;
1167}
1168
1169module = module->nextModule;
1170}
1171
1172return module;
1173}
1174#endif /* NOTDEF */
1175
1176//==========================================================================
1177// try to force loading kext.
1178// this not assure the kext will be loaded by the kernel for sure,
1179// but at least is forced loaded by the bootloader
1180bool isKextForcedToLoad(char *kext)
1181{
1182TagPtr ForceTag = NULL;
1183
1184if ((ForceTag = XMLCastArray(XMLGetProperty(bootInfo->kextConfig.dictionary, (const char *)"ForceToLoad"))))
1185{
1186unsigned long count = XMLTagCount(ForceTag);
1187if (count) {
1188for (unsigned i = count ; i-- > 0 ;) /* reversed iteration since xml.c add it reversed */
1189{
1190TagPtr index = XMLGetElement( ForceTag, i );
1191if(XMLIsString(index))
1192{
1193char *forced = XMLCastString(index);
1194char buffer[strlen(forced) + strlen(".kext") +1];
1195//snprintf(buffer, strlen(forced) + strlen(".kext") +1, "%s%s", forced, ".kext");
1196
1197sprintf(buffer, "%s%s", forced, ".kext");
1198
1199if (!strcmp(buffer, kext))
1200{
1201verbose("- %s forced loaded\n", kext);
1202return true;
1203}
1204}
1205}
1206}
1207}
1208return false;
1209}
1210
1211//==========================================================================
1212// ParseXML
1213static long ParseXML( char *buffer, ModulePtr *module, TagPtr *personalities, bool forceKextToLoad )
1214{
1215longlength;
1216longpos = 0;
1217TagPtrmoduleDict;
1218TagPtrrequired;
1219TagPtridentifier;
1220ModulePtrtmpModule;
1221
1222while (1)
1223{
1224length = XMLParseNextTag(buffer + pos, &moduleDict);
1225if (length == -1)
1226{
1227break;
1228}
1229
1230pos += length;
1231
1232if (moduleDict == 0)
1233{
1234continue;
1235}
1236if (moduleDict->type == kTagTypeDict)
1237{
1238break;
1239}
1240XMLFreeTag(moduleDict);
1241}
1242
1243if (length == -1)
1244{
1245return -1;
1246}
1247
1248required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
1249
1250// if forceKextToLoad is true, the kext will be force to load even if OSBundleRequired has value set to "Safe Boot" instead of "Root"
1251if (!forceKextToLoad)
1252{
1253if ( (required == 0) || (required->type != kTagTypeString) || !strncmp(required->string, "Safe Boot", sizeof("Safe Boot")))
1254{
1255identifier = XMLGetProperty(moduleDict, "CFBundleIdentifier");
1256
1257if (strcmp(identifier->string, "com.apple.driver.AppleSMC") == 0)
1258{
1259//verbose("\tForced load of: AppleSMC.kext");
1260}
1261else
1262{
1263XMLFreeTag(moduleDict);
1264return -2;
1265}
1266}
1267}
1268
1269tmpModule = malloc(sizeof(Module));
1270if (tmpModule == 0)
1271{
1272XMLFreeTag(moduleDict);
1273return -1;
1274}
1275tmpModule->dict = moduleDict;
1276
1277// For now, load any module that has OSBundleRequired != "Safe Boot".
1278
1279tmpModule->willLoad = 1;
1280
1281*module = tmpModule;
1282
1283// Get the personalities.
1284
1285*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
1286
1287return 0;
1288}
1289
1290#if NOTDEF
1291static char gPlatformName[64];
1292#endif
1293
1294long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
1295{
1296long ret = 0;
1297compressed_kernel_header *kernel_header = (compressed_kernel_header *)binary;
1298u_int32_t uncompressed_size = 0, size = 0, adler32 = 0;
1299void *buffer = NULL;
1300unsigned long len = 0;
1301
1302/*#if 0
1303printf("kernel header:\n");
1304printf("signature: 0x%x\n", kernel_header->signature);
1305printf("compress_type: 0x%x\n", kernel_header->compress_type);
1306printf("adler32: 0x%x\n", kernel_header->adler32);
1307printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
1308printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
1309getchar();
1310#endif*/
1311
1312if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
1313{
1314DBG("Decompressing Kernel Cache:\n");
1315
1316if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) &&
1317(kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn')))
1318{
1319error("\tERROR: kernel compression is bad!\n");
1320return -1;
1321}
1322
1323if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
1324{
1325verbose ("\t- Decompressing Kernel Using lzss\n");
1326}
1327
1328if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
1329{
1330verbose ("\t- Decompressing Kernel Using lzvn\n");
1331}
1332
1333#if NOTDEF
1334if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
1335{
1336return -1;
1337}
1338
1339if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
1340{
1341return -1;
1342}
1343#endif
1344uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
1345binary = buffer = malloc(uncompressed_size);
1346
1347// MinusZwei
1348size = 0;
1349switch (kernel_header->compress_type)
1350{
1351case OSSwapBigToHostConstInt32('lzvn'):
1352size = lzvn_decode(binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
1353break;
1354
1355case OSSwapBigToHostConstInt32('lzss'):
1356size = decompress_lzss((u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
1357break;
1358
1359default:
1360break;
1361}
1362// MinusZwei
1363
1364if (uncompressed_size != size)
1365{
1366if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
1367{
1368error("ERROR! Size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size);
1369}
1370
1371if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
1372{
1373error("ERROR! size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size);
1374}
1375
1376return -1;
1377}
1378
1379adler32 = Adler32(binary, uncompressed_size);
1380if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32)
1381{
1382error("ERROR! Adler mismatch (found: %X, expected: %X).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32));
1383return -1;
1384}
1385
1386DBG("\n");
1387}
1388
1389ret = ThinFatFile(&binary, &len);
1390if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
1391{
1392archCpuType=CPU_TYPE_I386;
1393ret = ThinFatFile(&binary, &len);
1394}
1395
1396// Bungo: scan binary for Darwin Kernel Version string
1397useDarwinVersion = true;
1398uint32_t offset = 0;
1399strncpy(gDarwinBuildVerStr, "Darwin Kernel Version", sizeof(gDarwinBuildVerStr));
1400
1401while ((offset < 0xFFFFFFFF - (uint32_t)binary - 256) && memcmp(binary + offset, gDarwinBuildVerStr, 21))
1402{
1403offset++;
1404}
1405if (offset < 0xFFFFFFFF - (uint32_t)binary - 256)
1406{
1407strncpy(gDarwinBuildVerStr, (char *)(binary + offset), sizeof(gDarwinBuildVerStr));
1408}
1409else
1410{
1411strcat(gDarwinBuildVerStr, ": Unknown");
1412useDarwinVersion = false;
1413}
1414// Micky1979 use Bungo gDarwinBuildVerStr and split into gDarwinMajor, gDarwinMinor and gDarwinRev
1415if (useDarwinVersion)
1416{
1417useDarwinVersion = false;
1418const char *pattern = strstr(gDarwinBuildVerStr, "Darwin Kernel Version ")+22;
1419const char *until = strstr(pattern, ":");
1420size_t vlen = until - pattern;
1421char *ver = (char *)malloc(sizeof(char)*(len+1));
1422strncpy(ver, pattern, vlen);
1423ver[vlen] = '\0';
1424char *delim;
1425char *temp;
1426gDarwinMajor = -1; gDarwinMinor = -1; gDarwinRev = -1;
1427if (ver != NULL)
1428{
1429temp = ver;
1430int count = 1;
1431while ((delim = strsep_c(&ver, ".")) != NULL)
1432{
1433switch (count)
1434{
1435case 1: gDarwinMajor = atoi(delim); break;
1436case 2: gDarwinMinor = atoi(delim); break;
1437case 3: gDarwinRev = atoi(delim); break;
1438default: break;
1439}
1440count ++;
1441}
1442free(temp);
1443}
1444
1445if (gDarwinMajor >= 0 && gDarwinMinor >= 0 && gDarwinRev >= 0)
1446{
1447useDarwinVersion = true;
1448}
1449
1450switch (gDarwinMajor)
1451{
1452case 10:
1453switch (gDarwinMinor)
1454{
1455case 0: kernelOSVer = 0xA060000; break;
1456case 1: kernelOSVer = 0xA060100; break;
1457case 2: kernelOSVer = 0xA060200; break;
1458case 3: kernelOSVer = 0xA060300; break;
1459case 4: kernelOSVer = 0xA060400; break;
1460case 5: kernelOSVer = 0xA060500; break;
1461case 6: kernelOSVer = 0xA060600; break;
1462case 7: kernelOSVer = 0xA060700; break;
1463case 8: kernelOSVer = 0xA060800; break;
1464default:kernelOSVer = 0xA060800; break; //Last known kernel
1465}
1466break;
1467case 11:
1468switch (gDarwinMinor)
1469{
1470case 0: kernelOSVer = 0xA070000; break;
1471case 1: kernelOSVer = 0xA070100; break;
1472case 2: kernelOSVer = 0xA070200; break;
1473case 3: kernelOSVer = 0xA070300; break;
1474case 4:
1475switch (gDarwinRev)
1476{
1477case 0: kernelOSVer = 0xA070400; break;
1478case 1: kernelOSVer = 0xA070400; break;
1479case 2: kernelOSVer = 0xA070500; break;
1480default:kernelOSVer = 0xA070500; break; //Last known kernel
1481}
1482default:kernelOSVer = 0xA070500; break; //Last known kernel
1483}
1484break;
1485case 12:
1486switch (gDarwinMinor)
1487{
1488case 0: kernelOSVer = 0xA080000; break;
1489case 1: kernelOSVer = 0xA080100; break;
1490case 2: kernelOSVer = 0xA080200; break;
1491case 3: kernelOSVer = 0xA080300; break;
1492case 4: kernelOSVer = 0xA080400; break;
1493case 5: kernelOSVer = 0xA080500; break; // 10.8.5
1494case 6: kernelOSVer = 0xA080500; break; // 10.8.5 update
1495default:kernelOSVer = 0xA080500; break; //Last known kernel
1496}
1497break;
1498case 13:
1499switch (gDarwinMinor)
1500{
1501case 0: kernelOSVer = 0xA090000;
1502switch (gDarwinRev)
1503{
1504case 0: kernelOSVer = 0xA090000; break;
1505case 1: kernelOSVer = 0xA090000; break; // never exist (or released)
1506case 2: kernelOSVer = 0xA090100; break;
1507default:kernelOSVer = 0xA090100; break; //Last known kernel
1508}
1509break;
1510case 1: kernelOSVer = 0xA090100; break; // never exist (or released)
1511case 2: kernelOSVer = 0xA090200; break;
1512case 3: kernelOSVer = 0xA090300; break;
1513case 4: kernelOSVer = 0xA090400; break;
1514case 5: kernelOSVer = 0xA090500; break;
1515default:kernelOSVer = 0xA090500; break; //Last known kernel
1516}
1517break;
1518case 14:
1519switch (gDarwinMinor)
1520{
1521case 0: kernelOSVer = 0xA0A0000; break; // same kernel of 10.10.1
1522case 1: kernelOSVer = 0xA0A0100; break; // same kernel of 10.10
1523case 2: kernelOSVer = 0xA0A0200; break;
1524case 3: kernelOSVer = 0xA0A0300; break;
1525case 4: kernelOSVer = 0xA0A0400; break;
1526case 5: kernelOSVer = 0xA0A0500; break;
1527default:kernelOSVer = 0xA0A0500; break; //Last known kernel
1528}
1529break;
1530case 15: /* El Capitan */
1531switch (gDarwinMinor)
1532{
1533case 0: kernelOSVer = 0xA0B0000; break;
1534case 1: kernelOSVer = 0xA0B0100; break;
1535case 2: kernelOSVer = 0xA0B0200; break;
1536case 3: kernelOSVer = 0xA0B0300; break;
1537case 4: kernelOSVer = 0xA0B0400; break;
1538case 5: kernelOSVer = 0xA0B0500; break;
1539case 6: kernelOSVer = 0xA0B0600; break;
1540default:kernelOSVer = 0xA0B0600; break; //Last known kernel (add here updates)
1541}
1542break;
1543case 16: /* Sierra */
1544switch (gDarwinMinor)
1545{
1546case 0: kernelOSVer = 0xA0C0000; break;
1547case 1: kernelOSVer = 0xA0C0100; break;
1548case 2: kernelOSVer = 0xA0C0200; break;
1549case 3: kernelOSVer = 0xA0C0200; break;
1550case 4: kernelOSVer = 0xA0C0300; break;
1551case 5: kernelOSVer = 0xA0C0400; break;
1552case 6: kernelOSVer = 0xA0C0500; break;
1553case 7: kernelOSVer = 0xA0C0600; break;
1554default:kernelOSVer = 0xA0C0600; break; //Last known kernel (add here updates)
1555}
1556break;
1557case 17: /* High Sierra */
1558switch (gDarwinMinor)
1559{
1560case 0: kernelOSVer = 0xA0D0000; break;
1561case 1: kernelOSVer = 0xA0D0100; break; // 17.2.0
1562case 2: kernelOSVer = 0xA0D0200; break;
1563case 3: kernelOSVer = 0xA0D0300; break;
1564case 4: kernelOSVer = 0xA0D0400; break;
1565case 5: kernelOSVer = 0xA0D0500; break;
1566case 6: kernelOSVer = 0xA0D0600; break;
1567case 7: kernelOSVer = 0xA0D0700; break;
1568default:kernelOSVer = 0xA0D0700; break; //Last known kernel (add here updates)
1569}
1570break;
1571case 18: /* Mojave */
1572switch (gDarwinMinor)
1573{
1574case 0: kernelOSVer = 0xA0E0000; break;
1575case 1: kernelOSVer = 0xA0E0100; break;
1576case 2: kernelOSVer = 0xA0E0200; break;
1577case 3: kernelOSVer = 0xA0E0300; break;
1578case 4: kernelOSVer = 0xA0E0400; break;
1579case 5: kernelOSVer = 0xA0E0500; break;
1580case 6: kernelOSVer = 0xA0E0600; break;
1581case 7: kernelOSVer = 0xA0E0700; break;
1582default:kernelOSVer = 0xA0E0700; break; //Last known kernel (add here updates)
1583}
1584break;
1585case 19: /* Catalina */
1586switch (gDarwinMinor)
1587{
1588case 0: kernelOSVer = 0xA0F0000; break;
1589//case 1: kernelOSVer = 0xA0F0100; break;
1590//case 2: kernelOSVer = 0xA0F0200; break;
1591//case 3: kernelOSVer = 0xA0F0300; break;
1592//case 4: kernelOSVer = 0xA0F0400; break;
1593//case 5: kernelOSVer = 0xA0F0500; break;
1594//case 6: kernelOSVer = 0xA0F0600; break;
1595//case 7: kernelOSVer = 0xA0F0700; break;
1596default:kernelOSVer = 0xA0F0000; break; //Last known kernel (add here updates)
1597}
1598break;
1599default:
1600kernelOSVer = 0xA0F0000;
1601break; //Last known kernel is Sierra 10.15
1602}
1603}
1604else
1605{
1606switch (MacOSVerCurrent)
1607{
1608// Snow
1609case 0xA060000: gDarwinMajor = 10; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.6
1610case 0xA060100: gDarwinMajor = 10; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.6.1
1611case 0xA060200: gDarwinMajor = 10; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.6.2
1612case 0xA060300: gDarwinMajor = 10; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.6.3
1613case 0xA060400: gDarwinMajor = 10; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.6.4
1614case 0xA060500: gDarwinMajor = 10; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.6.5
1615case 0xA060600: gDarwinMajor = 10; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.6.6
1616case 0xA060700: gDarwinMajor = 10; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.6.7
1617case 0xA060800: gDarwinMajor = 10; gDarwinMinor = 8; gDarwinRev = 0; break; // 10.6.8
1618// Lion
1619case 0xA070000: gDarwinMajor = 11; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.7
1620case 0xA070100: gDarwinMajor = 11; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.7.1
1621case 0xA070200: gDarwinMajor = 11; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.7.2
1622case 0xA070300: gDarwinMajor = 11; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.7.3
1623case 0xA070400: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.7.4
1624case 0xA070500: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 2; break; // 10.7.5
1625// ML
1626case 0xA080000: gDarwinMajor = 12; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.8
1627case 0xA080100: gDarwinMajor = 12; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.8.1
1628case 0xA080200: gDarwinMajor = 12; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.8.2
1629case 0xA080300: gDarwinMajor = 12; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.8.3
1630case 0xA080400: gDarwinMajor = 12; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.8.4
1631case 0xA080500: gDarwinMajor = 12; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.8.5
1632// Mavericks
1633case 0xA090000: gDarwinMajor = 13; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.9
1634case 0xA090100: gDarwinMajor = 13; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.9.1
1635case 0xA090200: gDarwinMajor = 13; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.9.2
1636case 0xA090300: gDarwinMajor = 13; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.9.3
1637case 0xA090400: gDarwinMajor = 13; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.9.4
1638case 0xA090500: gDarwinMajor = 13; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.9.5
1639// Yosemite
1640case 0xA0A0000: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10
1641case 0xA0A0100: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10.1
1642case 0xA0A0200: gDarwinMajor = 14; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.10.2
1643case 0xA0A0300: gDarwinMajor = 14; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.10.3
1644case 0xA0A0400: gDarwinMajor = 14; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.10.4
1645case 0xA0A0500: gDarwinMajor = 14; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.10.5
1646// El Capitan
1647case 0xA0B0000: gDarwinMajor = 15; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.11
1648case 0xA0B0100: gDarwinMajor = 15; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.11.1
1649case 0xA0B0200: gDarwinMajor = 15; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.11.2
1650case 0xA0B0300: gDarwinMajor = 15; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.11.3
1651case 0xA0B0400: gDarwinMajor = 15; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.11.4
1652case 0xA0B0500: gDarwinMajor = 15; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.11.5
1653case 0xA0B0600: gDarwinMajor = 15; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.11.6
1654// Sierra
1655case 0xA0C0000: gDarwinMajor = 16; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.12
1656case 0xA0C0100: gDarwinMajor = 16; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.12.1
1657case 0xA0C0200: gDarwinMajor = 16; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.12.2
1658case 0xA0C0300: gDarwinMajor = 16; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.12.3
1659case 0xA0C0400: gDarwinMajor = 16; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.12.4
1660case 0xA0C0500: gDarwinMajor = 16; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.12.5
1661case 0xA0C0600: gDarwinMajor = 16; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.12.6
1662// High Sierra
1663case 0xA0D0000: gDarwinMajor = 17; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.13
1664case 0xA0D0100: gDarwinMajor = 17; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.13.1
1665case 0xA0D0200: gDarwinMajor = 17; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.13.2
1666case 0xA0D0300: gDarwinMajor = 17; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.13.3
1667case 0xA0D0400: gDarwinMajor = 17; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.13.4
1668case 0xA0D0500: gDarwinMajor = 17; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.13.5
1669case 0xA0D0600: gDarwinMajor = 17; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.13.6
1670// Mojave
1671case 0xA0E0000: gDarwinMajor = 18; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.14
1672case 0xA0E0100: gDarwinMajor = 18; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.14.1
1673case 0xA0E0200: gDarwinMajor = 18; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.14.2
1674case 0xA0E0300: gDarwinMajor = 18; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.14.3
1675case 0xA0E0400: gDarwinMajor = 18; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.14.4
1676case 0xA0E0500: gDarwinMajor = 18; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.14.5
1677case 0xA0E0600: gDarwinMajor = 18; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.14.6
1678// Catalina
1679case 0xA0F0000: gDarwinMajor = 19; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.15
1680//case 0xA0F0100: gDarwinMajor = 19; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.15.1
1681
1682// default = last known kernel
1683default: gDarwinMajor = 19; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.15
1684}
1685}
1686
1687// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
1688execute_hook("DecodeKernel", (void *)binary, NULL, NULL, NULL);
1689
1690/* ================================================================ */
1691
1692ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1693if (ret < 0 && archCpuType == CPU_TYPE_X86_64)
1694{
1695archCpuType = CPU_TYPE_I386;
1696ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1697}
1698
1699return ret;
1700}
1701

Archive Download this file

Revision: 2922