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;
635embedded = malloc(FakeSMCInfo_plist_un_len); // don't free, will be done in LoadEmbeddedKext
636size_t size = lzvn_decode(embedded,
637 FakeSMCInfo_plist_un_len,
638 FakeSMCInfo_plist,
639 FakeSMCInfo_plist_lzvn_len);
640
641if (FakeSMCInfo_plist_un_len != size)
642{
643verbose("\n\t ERROR! FakeSMC size mismatch from lzvn (found: %zx, expected: %zx), failed!\n", size, FakeSMCInfo_plist_un_len);
644}
645else
646{
647LoadEmbeddedKext((char *)embedded, size, "EmbeddedFakeSMC" );
648}
649}
650#endif
651
652//==========================================================================
653// LoadEmbeddedKext
654long LoadEmbeddedKext( char *InjectorPlist, size_t length, char *name )
655{
656longexecutablePathLength, bundlePathLength;
657ModulePtrmodule;
658TagPtrpersonalities;
659char*tmpExecutablePath = 0;
660char*tmpBundlePath = 0;
661char*realAddr = NULL;
662longret = -1;
663
664do {
665snprintf(gFileSpec, 4096, "%s/%s.kext/%s", "/System/Library/Extensions", name, "Contents/MacOS/");
666executablePathLength = strlen(gFileSpec) + 1;
667
668tmpExecutablePath = malloc(executablePathLength);
669
670if (tmpExecutablePath == 0)
671{
672break;
673}
674
675strlcpy(tmpExecutablePath, gFileSpec, executablePathLength);
676snprintf(gFileSpec, 4096, "%s/%s.kext", "/System/Library/Extensions", name);
677bundlePathLength = strlen(gFileSpec) + 1;
678
679tmpBundlePath = malloc(bundlePathLength);
680
681if (tmpBundlePath == 0)
682{
683break;
684}
685
686strlcpy(tmpBundlePath, gFileSpec, bundlePathLength);
687
688// Construct the file spec to the plist, then load it.
689snprintf(gFileSpec, 4096, "%s/%s.kext/Contents/Info.plist", "/System/Library/Extensions", name);
690
691// bug, after ParseXML something weired happened to InjectorPlist. Making a copy
692realAddr = malloc(length);
693strlcpy(realAddr, InjectorPlist, length);
694ret = ParseXML((char *)InjectorPlist, &module, &personalities, true);
695
696if (ret != 0)
697{
698break;
699}
700
701if (!module) // cparm
702{
703ret = -1;
704break;
705} // Should never happen but it will make the compiler happy
706
707// Allocate memory for the driver path and the plist.
708module->executablePath = tmpExecutablePath;
709module->bundlePath = tmpBundlePath;
710module->bundlePathLength = bundlePathLength;
711
712module->plistAddr = malloc(length);
713
714if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
715{
716verbose("(executablePath or bundlePath or plistAddr are 0) ");
717ret = -1;
718break;
719}
720
721tmpExecutablePath = 0;
722tmpBundlePath = 0;
723
724strlcpy(module->plistAddr, realAddr, length);
725module->plistLength = length;
726// Add the module to the end of the module list.
727
728if (gModuleHead == 0)
729{
730gModuleHead = module;
731}
732else
733{
734gModuleTail->nextModule = module;
735}
736gModuleTail = module;
737
738// Add the persionalities to the personality list.
739if (personalities)
740{
741personalities = personalities->tag;
742}
743while (personalities != 0)
744{
745if (gPersonalityHead == 0)
746{
747gPersonalityHead = personalities->tag;
748}
749else
750{
751gPersonalityTail->tagNext = personalities->tag;
752}
753
754gPersonalityTail = personalities->tag;
755personalities = personalities->tagNext;
756}
757ret = 0;
758
759}while (0);
760
761if (realAddr)
762{
763free(realAddr);
764}
765
766if ( strlen(InjectorPlist) )
767{
768free( InjectorPlist );
769}
770
771if ( tmpExecutablePath )
772{
773free( tmpExecutablePath );
774}
775
776if ( tmpBundlePath )
777{
778free( tmpBundlePath );
779}
780return ret;
781}
782
783//==========================================================================
784// LoadDriverPList
785long LoadDriverPList( char *dirSpec, char *name, long bundleType )
786{
787longlength, executablePathLength, bundlePathLength;
788ModulePtrmodule;
789TagPtrpersonalities;
790char*buffer = 0;
791char*tmpExecutablePath = 0;
792char*tmpBundlePath = 0;
793longret = -1;
794
795do {
796// Save the driver path.
797
798if(name)
799{
800if (!strcmp(name, "FakeSMC.kext")) {
801FakeSMCLoaded = true;
802}
803snprintf(gFileSpec, 4096, "%s/%s/%s", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
804}
805else
806{
807snprintf(gFileSpec, 4096, "%s/%s", dirSpec, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
808}
809executablePathLength = strlen(gFileSpec) + 1;
810
811tmpExecutablePath = malloc(executablePathLength);
812if (tmpExecutablePath == 0) {
813break;
814}
815strlcpy(tmpExecutablePath, gFileSpec, executablePathLength);
816
817if(name)
818{
819snprintf(gFileSpec, 4096, "%s/%s", dirSpec, name);
820}
821else
822{
823strncpy(gFileSpec, dirSpec, 4096);
824}
825bundlePathLength = strlen(gFileSpec) + 1;
826
827tmpBundlePath = malloc(bundlePathLength);
828if (tmpBundlePath == 0)
829{
830break;
831}
832
833strlcpy(tmpBundlePath, gFileSpec, bundlePathLength);
834
835// Construct the file spec to the plist, then load it.
836
837if(name)
838{
839snprintf(gFileSpec, 4096, "%s/%s/%sInfo.plist", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/" : "");
840}
841else
842{
843snprintf(gFileSpec, 4096, "%s/%sInfo.plist", dirSpec, (bundleType == kCFBundleType2) ? "Contents/" : "");
844}
845
846length = LoadFile(gFileSpec);
847
848if (length == -1)
849{
850break;
851}
852
853length = length + 1;
854buffer = malloc(length);
855
856if (buffer == 0)
857{
858break;
859}
860
861strlcpy(buffer, (char *)kLoadAddr, length);
862
863// Parse the plist.
864
865ret = ParseXML(buffer, &module, &personalities, isKextForcedToLoad(name));
866
867if (ret != 0) {
868break;
869}
870
871if (!module) // cparm
872{
873ret = -1;
874break;
875} // Should never happen but it will make the compiler happy
876
877// Allocate memory for the driver path and the plist.
878
879module->executablePath = tmpExecutablePath;
880module->bundlePath = tmpBundlePath;
881module->bundlePathLength = bundlePathLength;
882module->plistAddr = malloc(length);
883
884if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
885{
886verbose("%s: executablePath or bundlePath or plistAddr are 0\n", name);
887break;
888}
889
890// Save the driver path in the module.
891//strcpy(module->driverPath, tmpDriverPath);
892tmpExecutablePath = 0;
893tmpBundlePath = 0;
894
895// Add the plist to the module.
896
897strlcpy(module->plistAddr, (char *)kLoadAddr, length);
898module->plistLength = length;
899
900// Add the module to the end of the module list.
901
902if (gModuleHead == 0) {
903gModuleHead = module;
904} else {
905gModuleTail->nextModule = module;
906}
907gModuleTail = module;
908
909// Add the persionalities to the personality list.
910
911if (personalities) {
912personalities = personalities->tag;
913}
914while (personalities != 0)
915{
916if (gPersonalityHead == 0) {
917gPersonalityHead = personalities->tag;
918} else {
919gPersonalityTail->tagNext = personalities->tag;
920}
921
922gPersonalityTail = personalities->tag;
923personalities = personalities->tagNext;
924}
925
926ret = 0;
927}
928while (0);
929
930if ( buffer ) {
931free( buffer );
932}
933if ( tmpExecutablePath ) {
934free( tmpExecutablePath );
935}
936if ( tmpBundlePath ) {
937free( tmpBundlePath );
938}
939return ret;
940}
941
942//==========================================================================
943// LoadMatchedModules
944long LoadMatchedModules( void )
945{
946TagPtrprop;
947ModulePtrmodule;
948char*fileName, segName[32];
949DriverInfoPtrdriver;
950longlength, driverAddr, driverLength;
951void*executableAddr = 0;
952void*embedded = 0;
953
954module = gModuleHead;
955
956TagPtr KextsPatches = XMLGetProperty(bootInfo->kextConfig.dictionary, (const char*)"KextsPatches");
957
958while (module != 0)
959{
960if (module->willLoad)
961{
962prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);
963
964if (prop != 0)
965{
966fileName = prop->string;
967snprintf(gFileSpec, 4096, "%s%s", module->executablePath, fileName);
968
969#if FAKESMC_SUPPORT
970if (!strcmp(fileName, "EmbeddedFakeSMC"))
971{
972verbose("\t Loading embedded FakeSMC: ");
973embedded = malloc(FakeSMC_un_len);
974size_t size = lzvn_decode(embedded, FakeSMC_un_len, FakeSMC, FakeSMC_lzvn_len );
975
976if (FakeSMC_un_len != size)
977{
978verbose("\n\t ERROR! FakeSMC size mismatch from lzvn (found: %zx, expected: %zx), failed!\n", size, FakeSMC_un_len);
979length = -1;
980}
981else
982{
983length = size;
984// no need to Thin this kext
985//memcpy((void *)kLoadAddr, embedded, length);
986//ThinFatFile(embedded, &length);
987executableAddr = (void *)embedded;
988verbose("%s!\n", ((length != -1) && executableAddr) ? "success" : "failed");
989}
990}
991else
992{
993#endif
994length = LoadThinFatFile(gFileSpec, &executableAddr);
995if (length == 0)
996{
997length = LoadFile(gFileSpec);
998executableAddr = (void *)kLoadAddr;
999}
1000#if FAKESMC_SUPPORT
1001}
1002#endif
1003//printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getchar();
1004}
1005else
1006{
1007length = 0;
1008}
1009
1010if ((length != -1) && executableAddr)
1011{
1012// patching kexts executable
1013if (!skipKextsPatcher)
1014{
1015// chameleon patches
1016patchBooterDefinedKext(fileName, executableAddr, (UInt32)length, 0);
1017// user's patches
1018if (KextsPatches && XMLIsDict(KextsPatches))
1019{
1020pach_binaryUsingDictionary(executableAddr, (UInt32)length, 0, fileName, KextsPatches);
1021}
1022}
1023
1024// Make make in the image area.
1025
1026execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
1027
1028driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
1029driverAddr = AllocateKernelMemory(driverLength);
1030
1031// Set up the DriverInfo.
1032driver = (DriverInfoPtr)driverAddr;
1033driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
1034driver->plistLength = module->plistLength;
1035
1036if (length != 0)
1037{
1038driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
1039 module->plistLength);
1040driver->executableLength = length;
1041}
1042else
1043{
1044driver->executableAddr = 0;
1045driver->executableLength = 0;
1046}
1047
1048driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
1049 module->plistLength + driver->executableLength);
1050driver->bundlePathLength = module->bundlePathLength;
1051
1052// Save the plist, module and bundle.
1053strlcpy(driver->plistAddr, module->plistAddr, driver->plistLength);
1054
1055if (length != 0)
1056{
1057memcpy(driver->executableAddr, executableAddr, length);
1058}
1059
1060strlcpy(driver->bundlePathAddr, module->bundlePath, module->bundlePathLength);
1061
1062// Add an entry to the memory map.
1063snprintf(segName, sizeof(segName), "Driver-%lx", (unsigned long)driver);
1064AllocateMemoryRange(segName, driverAddr, driverLength,
1065kBootDriverTypeKEXT);
1066}
1067}
1068module = module->nextModule;
1069}
1070
1071if(embedded)
1072{
1073free(embedded);
1074}
1075return 0;
1076}
1077
1078//==========================================================================
1079// MatchPersonalities
1080static long MatchPersonalities( void )
1081{
1082/* IONameMatch support not implemented */
1083return 0;
1084}
1085
1086//==========================================================================
1087// MatchLibraries
1088static long MatchLibraries( void )
1089{
1090TagPtr prop;
1091TagPtr prop2;
1092ModulePtr module;
1093ModulePtr module2;
1094long done;
1095
1096do {
1097done = 1;
1098module = gModuleHead;
1099
1100while (module != 0)
1101{
1102if (module->willLoad == 1)
1103{
1104prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
1105
1106if (prop != 0)
1107{
1108prop = prop->tag;
1109
1110while (prop != 0)
1111{
1112module2 = gModuleHead;
1113
1114while (module2 != 0)
1115{
1116prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
1117
1118if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
1119{
1120if (module2->willLoad == 0)
1121{
1122module2->willLoad = 1;
1123}
1124break;
1125}
1126module2 = module2->nextModule;
1127}
1128prop = prop->tagNext;
1129}
1130}
1131module->willLoad = 2;
1132done = 0;
1133}
1134module = module->nextModule;
1135}
1136}
1137while (!done);
1138
1139return 0;
1140}
1141
1142//==========================================================================
1143// FindModule
1144
1145#if NOTDEF
1146static ModulePtr FindModule( char *name )
1147{
1148ModulePtr module;
1149TagPtr prop;
1150
1151module = gModuleHead;
1152
1153while (module != 0)
1154{
1155prop = GetProperty(module->dict, kPropCFBundleIdentifier);
1156
1157if ((prop != 0) && !strcmp(name, prop->string))
1158{
1159break;
1160}
1161
1162module = module->nextModule;
1163}
1164
1165return module;
1166}
1167#endif /* NOTDEF */
1168
1169//==========================================================================
1170// try to force loading kext.
1171// this not assure the kext will be loaded by the kernel for sure,
1172// but at least is forced loaded by the bootloader
1173bool isKextForcedToLoad(char *kext)
1174{
1175TagPtr ForceTag = NULL;
1176
1177if ((ForceTag = XMLCastArray(XMLGetProperty(bootInfo->kextConfig.dictionary, (const char *)"ForceToLoad"))))
1178{
1179unsigned long count = XMLTagCount(ForceTag);
1180if (count) {
1181for (unsigned i = count ; i-- > 0 ;) /* reversed iteration since xml.c add it reversed */
1182{
1183TagPtr index = XMLGetElement( ForceTag, i );
1184if(XMLIsString(index))
1185{
1186char *forced = XMLCastString(index);
1187char buffer[strlen(forced) + strlen(".kext") +1];
1188//snprintf(buffer, strlen(forced) + strlen(".kext") +1, "%s%s", forced, ".kext");
1189
1190sprintf(buffer, "%s%s", forced, ".kext");
1191
1192if (!strcmp(buffer, kext))
1193{
1194verbose("- %s forced loaded\n", kext);
1195return true;
1196}
1197}
1198}
1199}
1200}
1201return false;
1202}
1203
1204//==========================================================================
1205// ParseXML
1206static long ParseXML( char *buffer, ModulePtr *module, TagPtr *personalities, bool forceKextToLoad )
1207{
1208longlength;
1209longpos = 0;
1210TagPtrmoduleDict;
1211TagPtrrequired;
1212ModulePtrtmpModule;
1213
1214while (1)
1215{
1216length = XMLParseNextTag(buffer + pos, &moduleDict);
1217if (length == -1)
1218{
1219break;
1220}
1221
1222pos += length;
1223
1224if (moduleDict == 0)
1225{
1226continue;
1227}
1228if (moduleDict->type == kTagTypeDict)
1229{
1230break;
1231}
1232XMLFreeTag(moduleDict);
1233}
1234
1235if (length == -1)
1236{
1237return -1;
1238}
1239
1240required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
1241
1242// if forceKextToLoad is true, the kext will be force to load even if OSBundleRequired has value set to "Safe Boot" instead of "Root"
1243if (!forceKextToLoad)
1244{
1245if ( (required == 0) || (required->type != kTagTypeString) || !strncmp(required->string, "Safe Boot", sizeof("Safe Boot")))
1246{
1247XMLFreeTag(moduleDict);
1248return -2;
1249}
1250}
1251
1252tmpModule = malloc(sizeof(Module));
1253if (tmpModule == 0)
1254{
1255XMLFreeTag(moduleDict);
1256return -1;
1257}
1258tmpModule->dict = moduleDict;
1259
1260// For now, load any module that has OSBundleRequired != "Safe Boot".
1261
1262tmpModule->willLoad = 1;
1263
1264*module = tmpModule;
1265
1266// Get the personalities.
1267
1268*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
1269
1270return 0;
1271}
1272
1273#if NOTDEF
1274static char gPlatformName[64];
1275#endif
1276
1277long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
1278{
1279long ret = 0;
1280compressed_kernel_header *kernel_header = (compressed_kernel_header *)binary;
1281u_int32_t uncompressed_size = 0, size = 0, adler32 = 0;
1282void *buffer = NULL;
1283unsigned long len = 0;
1284
1285/*#if 0
1286printf("kernel header:\n");
1287printf("signature: 0x%x\n", kernel_header->signature);
1288printf("compress_type: 0x%x\n", kernel_header->compress_type);
1289printf("adler32: 0x%x\n", kernel_header->adler32);
1290printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
1291printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
1292getchar();
1293#endif*/
1294
1295if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
1296{
1297DBG("Decompressing Kernel Cache:\n");
1298
1299if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) &&
1300(kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn')))
1301{
1302error("\tERROR: kernel compression is bad!\n");
1303return -1;
1304}
1305
1306if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
1307{
1308verbose ("\t- Decompressing Kernel Using lzss\n");
1309}
1310
1311if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
1312{
1313verbose ("\t- Decompressing Kernel Using lzvn\n");
1314}
1315
1316#if NOTDEF
1317if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
1318{
1319return -1;
1320}
1321
1322if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
1323{
1324return -1;
1325}
1326#endif
1327uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
1328binary = buffer = malloc(uncompressed_size);
1329
1330// MinusZwei
1331size = 0;
1332switch (kernel_header->compress_type)
1333{
1334case OSSwapBigToHostConstInt32('lzvn'):
1335size = lzvn_decode(binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
1336break;
1337
1338case OSSwapBigToHostConstInt32('lzss'):
1339size = decompress_lzss((u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
1340break;
1341
1342default:
1343break;
1344}
1345// MinusZwei
1346
1347if (uncompressed_size != size)
1348{
1349if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
1350{
1351error("ERROR! Size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size);
1352}
1353
1354if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
1355{
1356error("ERROR! size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size);
1357}
1358
1359return -1;
1360}
1361
1362adler32 = Adler32(binary, uncompressed_size);
1363if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32)
1364{
1365error("ERROR! Adler mismatch (found: %X, expected: %X).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32));
1366return -1;
1367}
1368
1369DBG("\n");
1370}
1371
1372ret = ThinFatFile(&binary, &len);
1373if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
1374{
1375archCpuType=CPU_TYPE_I386;
1376ret = ThinFatFile(&binary, &len);
1377}
1378
1379// Bungo: scan binary for Darwin Kernel Version string
1380useDarwinVersion = true;
1381uint32_t offset = 0;
1382strncpy(gDarwinBuildVerStr, "Darwin Kernel Version", sizeof(gDarwinBuildVerStr));
1383
1384while ((offset < 0xFFFFFFFF - (uint32_t)binary - 256) && memcmp(binary + offset, gDarwinBuildVerStr, 21))
1385{
1386offset++;
1387}
1388if (offset < 0xFFFFFFFF - (uint32_t)binary - 256)
1389{
1390strncpy(gDarwinBuildVerStr, (char *)(binary + offset), sizeof(gDarwinBuildVerStr));
1391}
1392else
1393{
1394strcat(gDarwinBuildVerStr, ": Unknown");
1395useDarwinVersion = false;
1396}
1397// Micky1979 use Bungo gDarwinBuildVerStr and split into gDarwinMajor, gDarwinMinor and gDarwinRev
1398if (useDarwinVersion)
1399{
1400useDarwinVersion = false;
1401const char *pattern = strstr(gDarwinBuildVerStr, "Darwin Kernel Version ")+22;
1402const char *until = strstr(pattern, ":");
1403size_t vlen = until - pattern;
1404char *ver = (char *)malloc(sizeof(char)*(len+1));
1405strncpy(ver, pattern, vlen);
1406ver[vlen] = '\0';
1407char *delim;
1408char *temp;
1409gDarwinMajor = -1; gDarwinMinor = -1; gDarwinRev = -1;
1410if (ver != NULL)
1411{
1412temp = ver;
1413int count = 1;
1414while ((delim = strsep_c(&ver, ".")) != NULL)
1415{
1416switch (count)
1417{
1418case 1: gDarwinMajor = atoi(delim); break;
1419case 2: gDarwinMinor = atoi(delim); break;
1420case 3: gDarwinRev = atoi(delim); break;
1421default: break;
1422}
1423count ++;
1424}
1425free(temp);
1426}
1427
1428if (gDarwinMajor >= 0 && gDarwinMinor >= 0 && gDarwinRev >= 0)
1429{
1430useDarwinVersion = true;
1431}
1432
1433switch (gDarwinMajor)
1434{
1435case 10:
1436switch (gDarwinMinor)
1437{
1438case 0: kernelOSVer = 0xA060000; break;
1439case 1: kernelOSVer = 0xA060100; break;
1440case 2: kernelOSVer = 0xA060200; break;
1441case 3: kernelOSVer = 0xA060300; break;
1442case 4: kernelOSVer = 0xA060400; break;
1443case 5: kernelOSVer = 0xA060500; break;
1444case 6: kernelOSVer = 0xA060600; break;
1445case 7: kernelOSVer = 0xA060700; break;
1446case 8: kernelOSVer = 0xA060800; break;
1447default:kernelOSVer = 0xA060800; break; //Last known kernel
1448}
1449break;
1450case 11:
1451switch (gDarwinMinor)
1452{
1453case 0: kernelOSVer = 0xA070000; break;
1454case 1: kernelOSVer = 0xA070100; break;
1455case 2: kernelOSVer = 0xA070200; break;
1456case 3: kernelOSVer = 0xA070300; break;
1457case 4:
1458switch (gDarwinRev)
1459{
1460case 0: kernelOSVer = 0xA070400; break;
1461case 1: kernelOSVer = 0xA070400; break;
1462case 2: kernelOSVer = 0xA070500; break;
1463default:kernelOSVer = 0xA070500; break; //Last known kernel
1464}
1465default:kernelOSVer = 0xA070500; break; //Last known kernel
1466}
1467break;
1468case 12:
1469switch (gDarwinMinor)
1470{
1471case 0: kernelOSVer = 0xA080000; break;
1472case 1: kernelOSVer = 0xA080100; break;
1473case 2: kernelOSVer = 0xA080200; break;
1474case 3: kernelOSVer = 0xA080300; break;
1475case 4: kernelOSVer = 0xA080400; break;
1476case 5: kernelOSVer = 0xA080500; break; // 10.8.5
1477case 6: kernelOSVer = 0xA080500; break; // 10.8.5 update
1478default:kernelOSVer = 0xA080500; break; //Last known kernel
1479}
1480break;
1481case 13:
1482switch (gDarwinMinor)
1483{
1484case 0: kernelOSVer = 0xA090000;
1485switch (gDarwinRev)
1486{
1487case 0: kernelOSVer = 0xA090000; break;
1488case 1: kernelOSVer = 0xA090000; break; // never exist (or released)
1489case 2: kernelOSVer = 0xA090100; break;
1490default:kernelOSVer = 0xA090100; break; //Last known kernel
1491}
1492break;
1493case 1: kernelOSVer = 0xA090100; break; // never exist (or released)
1494case 2: kernelOSVer = 0xA090200; break;
1495case 3: kernelOSVer = 0xA090300; break;
1496case 4: kernelOSVer = 0xA090400; break;
1497case 5: kernelOSVer = 0xA090500; break;
1498default:kernelOSVer = 0xA090500; break; //Last known kernel
1499}
1500break;
1501case 14:
1502switch (gDarwinMinor)
1503{
1504case 0: kernelOSVer = 0xA0A0000; break; // same kernel of 10.10.1
1505case 1: kernelOSVer = 0xA0A0100; break; // same kernel of 10.10
1506case 2: kernelOSVer = 0xA0A0200; break;
1507case 3: kernelOSVer = 0xA0A0300; break;
1508case 4: kernelOSVer = 0xA0A0400; break;
1509case 5: kernelOSVer = 0xA0A0500; break;
1510default:kernelOSVer = 0xA0A0500; break; //Last known kernel
1511}
1512break;
1513case 15: /* El Capitan */
1514switch (gDarwinMinor)
1515{
1516case 0: kernelOSVer = 0xA0B0000; break;
1517case 1: kernelOSVer = 0xA0B0100; break;
1518case 2: kernelOSVer = 0xA0B0200; break;
1519case 3: kernelOSVer = 0xA0B0300; break;
1520case 4: kernelOSVer = 0xA0B0400; break;
1521case 5: kernelOSVer = 0xA0B0500; break;
1522case 6: kernelOSVer = 0xA0B0600; break;
1523default:kernelOSVer = 0xA0B0600; break; //Last known kernel (add here updates)
1524}
1525break;
1526case 16: /* Sierra */
1527switch (gDarwinMinor)
1528{
1529case 0: kernelOSVer = 0xA0C0000; break;
1530case 1: kernelOSVer = 0xA0C0100; break;
1531case 2: kernelOSVer = 0xA0C0200; break;
1532case 3: kernelOSVer = 0xA0C0200; break;
1533case 4: kernelOSVer = 0xA0C0300; break;
1534case 5: kernelOSVer = 0xA0C0400; break;
1535case 6: kernelOSVer = 0xA0C0500; break;
1536case 7: kernelOSVer = 0xA0C0600; break;
1537//case 8: kernelOSVer = 0xA0C0700; break;
1538default:kernelOSVer = 0xA0C0600; break; //Last known kernel (add here updates)
1539}
1540break;
1541//case 17: /* High Sierra */
1542//switch (gDarwinMinor)
1543//{
1544//case 0: kernelOSVer = 0xA0C0000; break;
1545//case 1: kernelOSVer = 0xA0C0100; break;
1546//case 2: kernelOSVer = 0xA0C0200; break;
1547//case 3: kernelOSVer = 0xA0C0200; break;
1548//case 4: kernelOSVer = 0xA0C0300; break;
1549//case 5: kernelOSVer = 0xA0C0400; break;
1550//case 6: kernelOSVer = 0xA0C0500; break;
1551//case 7: kernelOSVer = 0xA0C0600; break;
1552//case 8: kernelOSVer = 0xA0C0700; break;
1553//default:kernelOSVer = 0xA0C0600; break; //Last known kernel (add here updates)
1554//}
1555//break;
1556default:
1557kernelOSVer = 0xA0C0600;
1558break; //Last known kernel is Sierra 10.12.6
1559}
1560}
1561else
1562{
1563switch (MacOSVerCurrent)
1564{
1565// Snow
1566case 0xA060000: gDarwinMajor = 10; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.6
1567case 0xA060100: gDarwinMajor = 10; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.6.1
1568case 0xA060200: gDarwinMajor = 10; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.6.2
1569case 0xA060300: gDarwinMajor = 10; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.6.3
1570case 0xA060400: gDarwinMajor = 10; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.6.4
1571case 0xA060500: gDarwinMajor = 10; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.6.5
1572case 0xA060600: gDarwinMajor = 10; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.6.6
1573case 0xA060700: gDarwinMajor = 10; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.6.7
1574case 0xA060800: gDarwinMajor = 10; gDarwinMinor = 8; gDarwinRev = 0; break; // 10.6.8
1575// Lion
1576case 0xA070000: gDarwinMajor = 11; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.7
1577case 0xA070100: gDarwinMajor = 11; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.7.1
1578case 0xA070200: gDarwinMajor = 11; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.7.2
1579case 0xA070300: gDarwinMajor = 11; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.7.3
1580case 0xA070400: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.7.4
1581case 0xA070500: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 2; break; // 10.7.5
1582// ML
1583case 0xA080000: gDarwinMajor = 12; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.8
1584case 0xA080100: gDarwinMajor = 12; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.8.1
1585case 0xA080200: gDarwinMajor = 12; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.8.2
1586case 0xA080300: gDarwinMajor = 12; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.8.3
1587case 0xA080400: gDarwinMajor = 12; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.8.4
1588case 0xA080500: gDarwinMajor = 12; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.8.5
1589// Mavericks
1590case 0xA090000: gDarwinMajor = 13; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.9
1591case 0xA090100: gDarwinMajor = 13; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.9.1
1592case 0xA090200: gDarwinMajor = 13; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.9.2
1593case 0xA090300: gDarwinMajor = 13; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.9.3
1594case 0xA090400: gDarwinMajor = 13; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.9.4
1595case 0xA090500: gDarwinMajor = 13; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.9.5
1596// Yosemite
1597case 0xA0A0000: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10
1598case 0xA0A0100: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10.1
1599case 0xA0A0200: gDarwinMajor = 14; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.10.2
1600case 0xA0A0300: gDarwinMajor = 14; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.10.3
1601case 0xA0A0400: gDarwinMajor = 14; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.10.4
1602case 0xA0A0500: gDarwinMajor = 14; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.10.5
1603// El Capitan
1604case 0xA0B0000: gDarwinMajor = 15; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.11
1605case 0xA0B0100: gDarwinMajor = 15; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.11.1
1606case 0xA0B0200: gDarwinMajor = 15; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.11.2
1607case 0xA0B0300: gDarwinMajor = 15; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.11.3
1608case 0xA0B0400: gDarwinMajor = 15; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.11.4
1609case 0xA0B0500: gDarwinMajor = 15; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.11.5
1610case 0xA0B0600: gDarwinMajor = 15; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.11.6
1611// Sierra
1612case 0xA0C0000: gDarwinMajor = 16; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.12
1613case 0xA0C0100: gDarwinMajor = 16; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.12.1
1614case 0xA0C0200: gDarwinMajor = 16; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.12.2
1615case 0xA0C0300: gDarwinMajor = 16; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.12.3
1616case 0xA0C0400: gDarwinMajor = 16; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.12.4
1617case 0xA0C0500: gDarwinMajor = 16; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.12.5
1618case 0xA0C0600: gDarwinMajor = 16; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.12.6
1619//case 0xA0C0700: gDarwinMajor = 16; gDarwinMinor = x; gDarwinRev = x; break; // 10.12.7
1620// High Sierra
1621
1622// default = last known kernel
1623default: gDarwinMajor = 16; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.12.6;
1624}
1625}
1626
1627// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
1628execute_hook("DecodeKernel", (void *)binary, NULL, NULL, NULL);
1629
1630/* ================================================================ */
1631
1632ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1633if (ret < 0 && archCpuType == CPU_TYPE_X86_64)
1634{
1635archCpuType = CPU_TYPE_I386;
1636ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1637}
1638
1639return ret;
1640}
1641

Archive Download this file

Revision: 2897