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

Archive Download this file

Revision: 2872