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;
1219ModulePtrtmpModule;
1220
1221while (1)
1222{
1223length = XMLParseNextTag(buffer + pos, &moduleDict);
1224if (length == -1)
1225{
1226break;
1227}
1228
1229pos += length;
1230
1231if (moduleDict == 0)
1232{
1233continue;
1234}
1235if (moduleDict->type == kTagTypeDict)
1236{
1237break;
1238}
1239XMLFreeTag(moduleDict);
1240}
1241
1242if (length == -1)
1243{
1244return -1;
1245}
1246
1247required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
1248
1249// if forceKextToLoad is true, the kext will be force to load even if OSBundleRequired has value set to "Safe Boot" instead of "Root"
1250if (!forceKextToLoad)
1251{
1252if ( (required == 0) || (required->type != kTagTypeString) || !strncmp(required->string, "Safe Boot", sizeof("Safe Boot")))
1253{
1254XMLFreeTag(moduleDict);
1255return -2;
1256}
1257}
1258
1259tmpModule = malloc(sizeof(Module));
1260if (tmpModule == 0)
1261{
1262XMLFreeTag(moduleDict);
1263return -1;
1264}
1265tmpModule->dict = moduleDict;
1266
1267// For now, load any module that has OSBundleRequired != "Safe Boot".
1268
1269tmpModule->willLoad = 1;
1270
1271*module = tmpModule;
1272
1273// Get the personalities.
1274
1275*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
1276
1277return 0;
1278}
1279
1280#if NOTDEF
1281static char gPlatformName[64];
1282#endif
1283
1284long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
1285{
1286long ret = 0;
1287compressed_kernel_header *kernel_header = (compressed_kernel_header *)binary;
1288u_int32_t uncompressed_size = 0, size = 0, adler32 = 0;
1289void *buffer = NULL;
1290unsigned long len = 0;
1291
1292/*#if 0
1293printf("kernel header:\n");
1294printf("signature: 0x%x\n", kernel_header->signature);
1295printf("compress_type: 0x%x\n", kernel_header->compress_type);
1296printf("adler32: 0x%x\n", kernel_header->adler32);
1297printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
1298printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
1299getchar();
1300#endif*/
1301
1302if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
1303{
1304DBG("Decompressing Kernel Cache:\n");
1305
1306if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) &&
1307(kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn')))
1308{
1309error("\tERROR: kernel compression is bad!\n");
1310return -1;
1311}
1312
1313if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
1314{
1315verbose ("\t- Decompressing Kernel Using lzss\n");
1316}
1317
1318if (kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
1319{
1320verbose ("\t- Decompressing Kernel Using lzvn\n");
1321}
1322
1323#if NOTDEF
1324if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
1325{
1326return -1;
1327}
1328
1329if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
1330{
1331return -1;
1332}
1333#endif
1334uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
1335binary = buffer = malloc(uncompressed_size);
1336
1337// MinusZwei
1338size = 0;
1339switch (kernel_header->compress_type)
1340{
1341case OSSwapBigToHostConstInt32('lzvn'):
1342size = lzvn_decode(binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
1343break;
1344
1345case OSSwapBigToHostConstInt32('lzss'):
1346size = decompress_lzss((u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
1347break;
1348
1349default:
1350break;
1351}
1352// MinusZwei
1353
1354if (uncompressed_size != size)
1355{
1356if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
1357{
1358error("ERROR! Size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size);
1359}
1360
1361if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
1362{
1363error("ERROR! size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size);
1364}
1365
1366return -1;
1367}
1368
1369adler32 = Adler32(binary, uncompressed_size);
1370if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32)
1371{
1372error("ERROR! Adler mismatch (found: %X, expected: %X).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32));
1373return -1;
1374}
1375
1376DBG("\n");
1377}
1378
1379ret = ThinFatFile(&binary, &len);
1380if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
1381{
1382archCpuType=CPU_TYPE_I386;
1383ret = ThinFatFile(&binary, &len);
1384}
1385
1386// Bungo: scan binary for Darwin Kernel Version string
1387useDarwinVersion = true;
1388uint32_t offset = 0;
1389strncpy(gDarwinBuildVerStr, "Darwin Kernel Version", sizeof(gDarwinBuildVerStr));
1390
1391while ((offset < 0xFFFFFFFF - (uint32_t)binary - 256) && memcmp(binary + offset, gDarwinBuildVerStr, 21))
1392{
1393offset++;
1394}
1395if (offset < 0xFFFFFFFF - (uint32_t)binary - 256)
1396{
1397strncpy(gDarwinBuildVerStr, (char *)(binary + offset), sizeof(gDarwinBuildVerStr));
1398}
1399else
1400{
1401strcat(gDarwinBuildVerStr, ": Unknown");
1402useDarwinVersion = false;
1403}
1404// Micky1979 use Bungo gDarwinBuildVerStr and split into gDarwinMajor, gDarwinMinor and gDarwinRev
1405if (useDarwinVersion)
1406{
1407useDarwinVersion = false;
1408const char *pattern = strstr(gDarwinBuildVerStr, "Darwin Kernel Version ")+22;
1409const char *until = strstr(pattern, ":");
1410size_t vlen = until - pattern;
1411char *ver = (char *)malloc(sizeof(char)*(len+1));
1412strncpy(ver, pattern, vlen);
1413ver[vlen] = '\0';
1414char *delim;
1415char *temp;
1416gDarwinMajor = -1; gDarwinMinor = -1; gDarwinRev = -1;
1417if (ver != NULL)
1418{
1419temp = ver;
1420int count = 1;
1421while ((delim = strsep_c(&ver, ".")) != NULL)
1422{
1423switch (count)
1424{
1425case 1: gDarwinMajor = atoi(delim); break;
1426case 2: gDarwinMinor = atoi(delim); break;
1427case 3: gDarwinRev = atoi(delim); break;
1428default: break;
1429}
1430count ++;
1431}
1432free(temp);
1433}
1434
1435if (gDarwinMajor >= 0 && gDarwinMinor >= 0 && gDarwinRev >= 0)
1436{
1437useDarwinVersion = true;
1438}
1439
1440switch (gDarwinMajor)
1441{
1442case 10:
1443switch (gDarwinMinor)
1444{
1445case 0: kernelOSVer = 0xA060000; break;
1446case 1: kernelOSVer = 0xA060100; break;
1447case 2: kernelOSVer = 0xA060200; break;
1448case 3: kernelOSVer = 0xA060300; break;
1449case 4: kernelOSVer = 0xA060400; break;
1450case 5: kernelOSVer = 0xA060500; break;
1451case 6: kernelOSVer = 0xA060600; break;
1452case 7: kernelOSVer = 0xA060700; break;
1453case 8: kernelOSVer = 0xA060800; break;
1454default:kernelOSVer = 0xA060800; break; //Last known kernel
1455}
1456break;
1457case 11:
1458switch (gDarwinMinor)
1459{
1460case 0: kernelOSVer = 0xA070000; break;
1461case 1: kernelOSVer = 0xA070100; break;
1462case 2: kernelOSVer = 0xA070200; break;
1463case 3: kernelOSVer = 0xA070300; break;
1464case 4:
1465switch (gDarwinRev)
1466{
1467case 0: kernelOSVer = 0xA070400; break;
1468case 1: kernelOSVer = 0xA070400; break;
1469case 2: kernelOSVer = 0xA070500; break;
1470default:kernelOSVer = 0xA070500; break; //Last known kernel
1471}
1472default:kernelOSVer = 0xA070500; break; //Last known kernel
1473}
1474break;
1475case 12:
1476switch (gDarwinMinor)
1477{
1478case 0: kernelOSVer = 0xA080000; break;
1479case 1: kernelOSVer = 0xA080100; break;
1480case 2: kernelOSVer = 0xA080200; break;
1481case 3: kernelOSVer = 0xA080300; break;
1482case 4: kernelOSVer = 0xA080400; break;
1483case 5: kernelOSVer = 0xA080500; break; // 10.8.5
1484case 6: kernelOSVer = 0xA080500; break; // 10.8.5 update
1485default:kernelOSVer = 0xA080500; break; //Last known kernel
1486}
1487break;
1488case 13:
1489switch (gDarwinMinor)
1490{
1491case 0: kernelOSVer = 0xA090000;
1492switch (gDarwinRev)
1493{
1494case 0: kernelOSVer = 0xA090000; break;
1495case 1: kernelOSVer = 0xA090000; break; // never exist (or released)
1496case 2: kernelOSVer = 0xA090100; break;
1497default:kernelOSVer = 0xA090100; break; //Last known kernel
1498}
1499break;
1500case 1: kernelOSVer = 0xA090100; break; // never exist (or released)
1501case 2: kernelOSVer = 0xA090200; break;
1502case 3: kernelOSVer = 0xA090300; break;
1503case 4: kernelOSVer = 0xA090400; break;
1504case 5: kernelOSVer = 0xA090500; break;
1505default:kernelOSVer = 0xA090500; break; //Last known kernel
1506}
1507break;
1508case 14:
1509switch (gDarwinMinor)
1510{
1511case 0: kernelOSVer = 0xA0A0000; break; // same kernel of 10.10.1
1512case 1: kernelOSVer = 0xA0A0100; break; // same kernel of 10.10
1513case 2: kernelOSVer = 0xA0A0200; break;
1514case 3: kernelOSVer = 0xA0A0300; break;
1515case 4: kernelOSVer = 0xA0A0400; break;
1516case 5: kernelOSVer = 0xA0A0500; break;
1517default:kernelOSVer = 0xA0A0500; break; //Last known kernel
1518}
1519break;
1520case 15: /* El Capitan */
1521switch (gDarwinMinor)
1522{
1523case 0: kernelOSVer = 0xA0B0000; break;
1524case 1: kernelOSVer = 0xA0B0100; break;
1525case 2: kernelOSVer = 0xA0B0200; break;
1526case 3: kernelOSVer = 0xA0B0300; break;
1527case 4: kernelOSVer = 0xA0B0400; break;
1528case 5: kernelOSVer = 0xA0B0500; break;
1529case 6: kernelOSVer = 0xA0B0600; break;
1530default:kernelOSVer = 0xA0B0600; break; //Last known kernel (add here updates)
1531}
1532break;
1533case 16: /* Sierra */
1534switch (gDarwinMinor)
1535{
1536case 0: kernelOSVer = 0xA0C0000; break;
1537case 1: kernelOSVer = 0xA0C0100; break;
1538case 2: kernelOSVer = 0xA0C0200; break;
1539case 3: kernelOSVer = 0xA0C0200; break;
1540case 4: kernelOSVer = 0xA0C0300; break;
1541case 5: kernelOSVer = 0xA0C0400; break;
1542case 6: kernelOSVer = 0xA0C0500; break;
1543case 7: kernelOSVer = 0xA0C0600; break;
1544//case 8: kernelOSVer = 0xA0C0700; break;
1545default:kernelOSVer = 0xA0C0600; break; //Last known kernel (add here updates)
1546}
1547break;
1548case 17: /* High Sierra */
1549switch (gDarwinMinor)
1550{
1551case 0: kernelOSVer = 0xA0D0000; break;
1552case 1: kernelOSVer = 0xA0D0100; break;
1553//case 2: kernelOSVer = 0xA0D0200; break; // 17.2.0
1554//case 3: kernelOSVer = 0xA0C0200; break;
1555//case 4: kernelOSVer = 0xA0C0300; break;
1556//case 5: kernelOSVer = 0xA0C0400; break;
1557//case 6: kernelOSVer = 0xA0C0500; break;
1558//case 7: kernelOSVer = 0xA0C0600; break;
1559//case 8: kernelOSVer = 0xA0C0700; break;
1560default:kernelOSVer = 0xA0D0100; break; //Last known kernel (add here updates)
1561}
1562break;
1563default:
1564kernelOSVer = 0xA0D0100;
1565break; //Last known kernel is Sierra 10.13.1
1566}
1567}
1568else
1569{
1570switch (MacOSVerCurrent)
1571{
1572// Snow
1573case 0xA060000: gDarwinMajor = 10; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.6
1574case 0xA060100: gDarwinMajor = 10; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.6.1
1575case 0xA060200: gDarwinMajor = 10; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.6.2
1576case 0xA060300: gDarwinMajor = 10; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.6.3
1577case 0xA060400: gDarwinMajor = 10; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.6.4
1578case 0xA060500: gDarwinMajor = 10; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.6.5
1579case 0xA060600: gDarwinMajor = 10; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.6.6
1580case 0xA060700: gDarwinMajor = 10; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.6.7
1581case 0xA060800: gDarwinMajor = 10; gDarwinMinor = 8; gDarwinRev = 0; break; // 10.6.8
1582// Lion
1583case 0xA070000: gDarwinMajor = 11; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.7
1584case 0xA070100: gDarwinMajor = 11; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.7.1
1585case 0xA070200: gDarwinMajor = 11; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.7.2
1586case 0xA070300: gDarwinMajor = 11; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.7.3
1587case 0xA070400: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.7.4
1588case 0xA070500: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 2; break; // 10.7.5
1589// ML
1590case 0xA080000: gDarwinMajor = 12; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.8
1591case 0xA080100: gDarwinMajor = 12; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.8.1
1592case 0xA080200: gDarwinMajor = 12; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.8.2
1593case 0xA080300: gDarwinMajor = 12; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.8.3
1594case 0xA080400: gDarwinMajor = 12; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.8.4
1595case 0xA080500: gDarwinMajor = 12; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.8.5
1596// Mavericks
1597case 0xA090000: gDarwinMajor = 13; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.9
1598case 0xA090100: gDarwinMajor = 13; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.9.1
1599case 0xA090200: gDarwinMajor = 13; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.9.2
1600case 0xA090300: gDarwinMajor = 13; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.9.3
1601case 0xA090400: gDarwinMajor = 13; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.9.4
1602case 0xA090500: gDarwinMajor = 13; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.9.5
1603// Yosemite
1604case 0xA0A0000: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10
1605case 0xA0A0100: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10.1
1606case 0xA0A0200: gDarwinMajor = 14; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.10.2
1607case 0xA0A0300: gDarwinMajor = 14; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.10.3
1608case 0xA0A0400: gDarwinMajor = 14; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.10.4
1609case 0xA0A0500: gDarwinMajor = 14; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.10.5
1610// El Capitan
1611case 0xA0B0000: gDarwinMajor = 15; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.11
1612case 0xA0B0100: gDarwinMajor = 15; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.11.1
1613case 0xA0B0200: gDarwinMajor = 15; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.11.2
1614case 0xA0B0300: gDarwinMajor = 15; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.11.3
1615case 0xA0B0400: gDarwinMajor = 15; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.11.4
1616case 0xA0B0500: gDarwinMajor = 15; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.11.5
1617case 0xA0B0600: gDarwinMajor = 15; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.11.6
1618// Sierra
1619case 0xA0C0000: gDarwinMajor = 16; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.12
1620case 0xA0C0100: gDarwinMajor = 16; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.12.1
1621case 0xA0C0200: gDarwinMajor = 16; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.12.2
1622case 0xA0C0300: gDarwinMajor = 16; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.12.3
1623case 0xA0C0400: gDarwinMajor = 16; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.12.4
1624case 0xA0C0500: gDarwinMajor = 16; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.12.5
1625case 0xA0C0600: gDarwinMajor = 16; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.12.6
1626//case 0xA0C0700: gDarwinMajor = 16; gDarwinMinor = x; gDarwinRev = x; break; // 10.12.7
1627// High Sierra
1628case 0xA0D0000: gDarwinMajor = 17; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.13
1629case 0xA0D0100: gDarwinMajor = 17; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.13.1
1630
1631// default = last known kernel
1632default: gDarwinMajor = 17; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.13.1;
1633}
1634}
1635
1636// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
1637execute_hook("DecodeKernel", (void *)binary, NULL, NULL, NULL);
1638
1639/* ================================================================ */
1640
1641ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1642if (ret < 0 && archCpuType == CPU_TYPE_X86_64)
1643{
1644archCpuType = CPU_TYPE_I386;
1645ret = DecodeMachO(binary, uncompressed_size, rentry, raddr, rsize);
1646}
1647
1648return ret;
1649}
1650

Archive Download this file

Revision: 2915