2019-09-03 11:58:42 +02:00
/*
* Copyright ( c ) 2011 - 2012 Frank Peng . All rights reserved .
*
*/
# include "Platform.h"
# include "LoaderUefi.h"
2019-12-18 19:41:07 +01:00
//#include "device_tree.h"
2019-09-03 11:58:42 +02:00
# include "kernel_patcher.h"
2020-05-07 20:13:08 +02:00
# define OLD_METHOD 0
2020-05-02 18:00:31 +02:00
2020-03-26 13:59:20 +01:00
# ifndef DEBUG_ALL
2019-09-03 11:58:42 +02:00
# define KEXT_DEBUG 0
2020-03-26 13:59:20 +01:00
# else
# define KEXT_DEBUG DEBUG_ALL
# endif
2019-09-03 11:58:42 +02:00
# if KEXT_DEBUG
2020-03-26 13:59:20 +01:00
# define DBG(...) printf(__VA_ARGS__);
2019-09-03 11:58:42 +02:00
# else
# define DBG(...)
# endif
// runtime debug
2020-05-01 18:26:28 +02:00
# define DBG_RT(...) if ((KernelAndKextPatches != NULL) && KernelAndKextPatches->KPDebug) { printf(__VA_ARGS__); }
2019-09-03 11:58:42 +02:00
//
// Searches Source for Search pattern of size SearchSize
// and returns the number of occurences.
//
2020-05-02 18:00:31 +02:00
UINTN SearchAndCount ( const UINT8 * Source , UINT64 SourceSize , const UINT8 * Search , UINTN SearchSize )
2019-09-03 11:58:42 +02:00
{
2020-05-02 18:00:31 +02:00
UINTN NumFounds = 0 ;
const UINT8 * End = Source + SourceSize ;
2019-09-03 11:58:42 +02:00
while ( Source < End ) {
if ( CompareMem ( Source , Search , SearchSize ) = = 0 ) {
NumFounds + + ;
Source + = SearchSize ;
} else {
Source + + ;
}
}
return NumFounds ;
}
//
// Searches Source for Search pattern of size SearchSize
// and replaces it with Replace up to MaxReplaces times.
// If MaxReplaces <= 0, then there is no restriction on number of replaces.
// Replace should have the same size as Search.
// Returns number of replaces done.
//
2020-05-02 05:38:38 +02:00
UINTN SearchAndReplace ( UINT8 * Source , UINT64 SourceSize , const UINT8 * Search , UINTN SearchSize , const UINT8 * Replace , INTN MaxReplaces )
2019-09-03 11:58:42 +02:00
{
UINTN NumReplaces = 0 ;
BOOLEAN NoReplacesRestriction = MaxReplaces < = 0 ;
2020-05-01 18:26:28 +02:00
// UINT8 *Begin = Source;
2019-09-03 11:58:42 +02:00
UINT8 * End = Source + SourceSize ;
if ( ! Source | | ! Search | | ! Replace | | ! SearchSize ) {
return 0 ;
}
while ( ( Source < End ) & & ( NoReplacesRestriction | | ( MaxReplaces > 0 ) ) ) {
if ( CompareMem ( Source , Search , SearchSize ) = = 0 ) {
2020-05-01 18:26:28 +02:00
// printf(" found pattern at %llx\n", (UINTN)(Source - Begin));
2019-09-03 11:58:42 +02:00
CopyMem ( Source , Replace , SearchSize ) ;
NumReplaces + + ;
MaxReplaces - - ;
Source + = SearchSize ;
} else {
Source + + ;
}
}
return NumReplaces ;
}
2020-05-02 05:38:38 +02:00
BOOLEAN CompareMemMask ( const UINT8 * Source , const UINT8 * Search , UINTN SearchSize , const UINT8 * Mask , UINTN MaskSize )
2019-10-08 22:57:18 +02:00
{
UINT8 M ;
2020-04-24 11:01:28 +02:00
2020-05-02 05:38:38 +02:00
if ( ! Mask | | MaskSize = = 0 ) {
2019-10-08 22:57:18 +02:00
return ! CompareMem ( Source , Search , SearchSize ) ;
}
2020-04-24 11:01:28 +02:00
for ( UINTN Ind = 0 ; Ind < SearchSize ; Ind + + ) {
2020-05-02 05:38:38 +02:00
if ( Ind < MaskSize )
M = * Mask + + ;
else M = 0xFF ;
2019-10-08 22:57:18 +02:00
if ( ( * Source + + & M ) ! = ( * Search + + & M ) ) {
return FALSE ;
}
}
return TRUE ;
}
2020-05-02 05:38:38 +02:00
VOID CopyMemMask ( UINT8 * Dest , const UINT8 * Replace , const UINT8 * Mask , UINTN SearchSize )
2019-10-08 22:57:18 +02:00
{
UINT8 M , D ;
2020-04-24 11:01:28 +02:00
// the procedure is called from SearchAndReplaceMask with own check but for future it is better to check twice
if ( ! Dest | | ! Replace ) {
return ;
}
2019-10-08 22:57:18 +02:00
if ( ! Mask ) {
2020-04-24 11:01:28 +02:00
CopyMem ( Dest , Replace , SearchSize ) ; //old behavior
2019-10-08 22:57:18 +02:00
return ;
}
2020-04-24 11:01:28 +02:00
for ( UINTN Ind = 0 ; Ind < SearchSize ; Ind + + ) {
2019-10-08 22:57:18 +02:00
M = * Mask + + ;
D = * Dest ;
2019-10-10 21:04:12 +02:00
* Dest + + = ( ( D ^ * Replace + + ) & M ) ^ D ;
2019-10-08 22:57:18 +02:00
}
}
2020-05-03 06:10:02 +02:00
// search a pattern like
// call task or jmp address
//return the address next to the command
// 0 if not found
UINTN FindRelative32 ( const UINT8 * Source , UINTN Start , UINTN SourceSize , UINTN taskLocation )
{
2020-05-03 19:16:50 +02:00
INT32 Offset ; //can be negative, so 0xFFFFFFFF == -1
2020-05-03 06:10:02 +02:00
for ( UINTN i = Start ; i < Start + SourceSize - 4 ; + + i ) {
2020-05-03 19:16:50 +02:00
Offset = ( INT32 ) ( ( UINT32 ) Source [ i ] + ( ( UINT32 ) Source [ i + 1 ] < < 8 ) + ( ( UINT32 ) Source [ i + 2 ] < < 16 ) + ( ( UINT32 ) Source [ i + 3 ] < < 24 ) ) ; //should not use *(UINT32*) because of alignment
2020-05-03 06:10:02 +02:00
if ( taskLocation = = i + Offset + 4 ) {
return ( i + 4 ) ;
}
}
return 0 ;
}
2020-05-02 05:38:38 +02:00
UINTN FindMemMask ( const UINT8 * Source , UINTN SourceSize , const UINT8 * Search , UINTN SearchSize , const UINT8 * MaskSearch , UINTN MaskSize )
{
if ( ! Source | | ! Search | | ! SearchSize ) {
return KERNEL_MAX_SIZE ;
}
for ( UINTN i = 0 ; i < SourceSize - SearchSize ; + + i ) {
if ( CompareMemMask ( & Source [ i ] , Search , SearchSize , MaskSearch , MaskSize ) ) {
return i ;
}
}
return KERNEL_MAX_SIZE ;
}
UINTN SearchAndReplaceMask ( UINT8 * Source , UINT64 SourceSize , const UINT8 * Search , const UINT8 * MaskSearch , UINTN SearchSize ,
const UINT8 * Replace , const UINT8 * MaskReplace , INTN MaxReplaces )
2019-10-08 22:57:18 +02:00
{
UINTN NumReplaces = 0 ;
BOOLEAN NoReplacesRestriction = MaxReplaces < = 0 ;
UINT8 * End = Source + SourceSize ;
if ( ! Source | | ! Search | | ! Replace | | ! SearchSize ) {
return 0 ;
}
while ( ( Source < End ) & & ( NoReplacesRestriction | | ( MaxReplaces > 0 ) ) ) {
2020-05-02 05:38:38 +02:00
if ( CompareMemMask ( ( const UINT8 * ) Source , Search , SearchSize , MaskSearch , SearchSize ) ) {
2019-10-08 22:57:18 +02:00
CopyMemMask ( Source , Replace , MaskReplace , SearchSize ) ;
NumReplaces + + ;
MaxReplaces - - ;
Source + = SearchSize ;
} else {
Source + + ;
}
}
return NumReplaces ;
}
2019-09-03 11:58:42 +02:00
UINTN SearchAndReplaceTxt ( UINT8 * Source , UINT64 SourceSize , UINT8 * Search , UINTN SearchSize , UINT8 * Replace , INTN MaxReplaces )
{
UINTN NumReplaces = 0 ;
UINTN Skip = 0 ;
BOOLEAN NoReplacesRestriction = MaxReplaces < = 0 ;
UINT8 * End = Source + SourceSize ;
UINT8 * SearchEnd = Search + SearchSize ;
UINT8 * Pos = NULL ;
UINT8 * FirstMatch = Source ;
if ( ! Source | | ! Search | | ! Replace | | ! SearchSize ) {
return 0 ;
}
while ( ( ( Source + SearchSize ) < = End ) & &
( NoReplacesRestriction | | ( MaxReplaces > 0 ) ) ) { // num replaces
while ( * Source ! = ' \0 ' ) { //comparison
Pos = Search ;
FirstMatch = Source ;
Skip = 0 ;
while ( * Source ! = ' \0 ' & & Pos ! = SearchEnd ) {
if ( * Source < = 0x20 ) { //skip invisibles in sources
Source + + ;
Skip + + ;
continue ;
}
if ( * Source ! = * Pos ) {
break ;
}
2020-03-29 14:47:04 +02:00
// printf("%c", *Source);
2019-09-03 11:58:42 +02:00
Source + + ;
Pos + + ;
}
if ( Pos = = SearchEnd ) { // pattern found
Pos = FirstMatch ;
break ;
}
else
Pos = NULL ;
Source = FirstMatch + 1 ;
/* if (Pos != Search) {
2020-03-29 14:47:04 +02:00
printf ( " \n " ) ;
2019-09-03 11:58:42 +02:00
} */
}
if ( ! Pos ) {
break ;
}
2020-05-01 18:26:28 +02:00
CopyMem ( Pos , Replace , SearchSize ) ;
SetMem ( Pos + SearchSize , Skip , 0x20 ) ; //fill skip places with spaces
2019-09-03 11:58:42 +02:00
NumReplaces + + ;
MaxReplaces - - ;
Source = FirstMatch + SearchSize + Skip ;
}
return NumReplaces ;
}
/** Global for storing KextBundleIdentifier */
CHAR8 gKextBundleIdentifier [ 256 ] ;
/** Extracts kext BundleIdentifier from given Plist into gKextBundleIdentifier */
VOID ExtractKextBundleIdentifier ( CHAR8 * Plist )
{
CHAR8 * Tag ;
CHAR8 * BIStart ;
CHAR8 * BIEnd ;
INTN DictLevel = 0 ;
gKextBundleIdentifier [ 0 ] = ' \0 ' ;
// start with first <dict>
Tag = AsciiStrStr ( Plist , " <dict> " ) ;
if ( Tag = = NULL ) {
return ;
}
Tag + = 6 ;
DictLevel + + ;
while ( * Tag ! = ' \0 ' ) {
2020-05-16 21:30:29 +02:00
if ( strncmp ( Tag , " <dict> " , 6 ) = = 0 ) {
2019-09-03 11:58:42 +02:00
// opening dict
DictLevel + + ;
Tag + = 6 ;
2020-05-16 21:30:29 +02:00
} else if ( strncmp ( Tag , " </dict> " , 7 ) = = 0 ) {
2019-09-03 11:58:42 +02:00
// closing dict
DictLevel - - ;
Tag + = 7 ;
2020-05-16 21:30:29 +02:00
} else if ( DictLevel = = 1 & & strncmp ( Tag , " <key>CFBundleIdentifier</key> " , 29 ) = = 0 ) {
2019-09-03 11:58:42 +02:00
// BundleIdentifier is next <string>...</string>
BIStart = AsciiStrStr ( Tag + 29 , " <string> " ) ;
if ( BIStart ! = NULL ) {
BIStart + = 8 ; // skip "<string>"
BIEnd = AsciiStrStr ( BIStart , " </string> " ) ;
2020-02-17 21:41:09 +01:00
if ( BIEnd ! = NULL & & ( UINTN ) ( BIEnd - BIStart + 1 ) < sizeof ( gKextBundleIdentifier ) ) { // (UINTN)(BIEnd - BIStart + 1) = valid cast because BIEnd is > BIStart
2019-09-03 11:58:42 +02:00
CopyMem ( gKextBundleIdentifier , BIStart , BIEnd - BIStart ) ;
gKextBundleIdentifier [ BIEnd - BIStart ] = ' \0 ' ;
return ;
}
}
Tag + + ;
} else {
Tag + + ;
}
// advance to next tag
while ( * Tag ! = ' < ' & & * Tag ! = ' \0 ' ) {
Tag + + ;
}
}
}
BOOLEAN
isPatchNameMatch ( CHAR8 * BundleIdentifier , CHAR8 * Name )
{
BOOLEAN isBundle = ( AsciiStrStr ( Name , " . " ) ! = NULL ) ;
return
isBundle
? ( AsciiStrCmp ( BundleIdentifier , Name ) = = 0 )
: ( AsciiStrStr ( BundleIdentifier , Name ) ! = NULL ) ;
}
////////////////////////////////////
//
// ATIConnectors patch
//
// bcc9's patch: http://www.insanelymac.com/forum/index.php?showtopic=249642
//
// inited or not?
BOOLEAN ATIConnectorsPatchInited = FALSE ;
// ATIConnectorsController's boundle IDs for
// 0: ATI version - Lion, SnowLeo 10.6.7 2011 MBP
// 1: AMD version - ML
CHAR8 ATIKextBundleId [ 2 ] [ 64 ] ;
//
// Inits patcher: prepares ATIKextBundleIds.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : ATIConnectorsPatchInit ( )
2019-09-03 11:58:42 +02:00
{
//
// prepar boundle ids
//
// Lion, SnowLeo 10.6.7 2011 MBP
2020-04-10 15:17:50 +02:00
snprintf ( ATIKextBundleId [ 0 ] ,
2019-09-03 11:58:42 +02:00
sizeof ( ATIKextBundleId [ 0 ] ) ,
2020-04-10 15:17:50 +02:00
" com.apple.kext.ATI%sController " , // when it was AsciiSPrint, %a was used with KPATIConnectorsController which is CHAR16 ??? Result is printing stop at first char <= 255
2020-04-11 17:36:40 +02:00
//now it is CHAR8*
2020-05-01 18:26:28 +02:00
KernelAndKextPatches - > KPATIConnectorsController
2019-09-03 11:58:42 +02:00
) ;
// ML
2020-04-10 15:17:50 +02:00
snprintf ( ATIKextBundleId [ 1 ] ,
2019-09-03 11:58:42 +02:00
sizeof ( ATIKextBundleId [ 1 ] ) ,
2020-04-10 15:17:50 +02:00
" com.apple.kext.AMD%sController " , // when it was AsciiSPrint, %a was used with KPATIConnectorsController which is CHAR16 ??? Result is printing stop at first char <= 255
2020-05-01 18:26:28 +02:00
KernelAndKextPatches - > KPATIConnectorsController
2019-09-03 11:58:42 +02:00
) ;
ATIConnectorsPatchInited = TRUE ;
2020-03-25 19:32:44 +01:00
//DBG(L"Bundle1: %s\n", ATIKextBundleId[0]);
//DBG(L"Bundle2: %s\n", ATIKextBundleId[1]);
2019-09-03 11:58:42 +02:00
//gBS->Stall(10000000);
}
//
// Registers kexts that need force-load during WithKexts boot.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : ATIConnectorsPatchRegisterKexts ( void * FSInject_v , void * ForceLoadKexts_v )
2019-09-03 11:58:42 +02:00
{
2020-05-01 18:26:28 +02:00
FSINJECTION_PROTOCOL * FSInject = ( FSINJECTION_PROTOCOL * ) FSInject_v ;
FSI_STRING_LIST * ForceLoadKexts = ( FSI_STRING_LIST * ) ForceLoadKexts_v ;
2019-09-03 11:58:42 +02:00
// for future?
FSInject - > AddStringToList ( ForceLoadKexts ,
2020-05-01 18:26:28 +02:00
PoolPrint ( L " \\ AMD%aController.kext \\ Contents \\ Info.plist " , KernelAndKextPatches - > KPATIConnectorsController )
2019-09-03 11:58:42 +02:00
) ;
// Lion, ML, SnowLeo 10.6.7 2011 MBP
FSInject - > AddStringToList ( ForceLoadKexts ,
2020-05-01 18:26:28 +02:00
PoolPrint ( L " \\ ATI%aController.kext \\ Contents \\ Info.plist " , KernelAndKextPatches - > KPATIConnectorsController )
2019-09-03 11:58:42 +02:00
) ;
// SnowLeo
FSInject - > AddStringToList ( ForceLoadKexts , L " \\ ATIFramebuffer.kext \\ Contents \\ Info.plist " ) ;
FSInject - > AddStringToList ( ForceLoadKexts , L " \\ AMDFramebuffer.kext \\ Contents \\ Info.plist " ) ;
// dependencies
FSInject - > AddStringToList ( ForceLoadKexts , L " \\ IOGraphicsFamily.kext \\ Info.plist " ) ;
FSInject - > AddStringToList ( ForceLoadKexts , L " \\ ATISupport.kext \\ Contents \\ Info.plist " ) ;
FSInject - > AddStringToList ( ForceLoadKexts , L " \\ AMDSupport.kext \\ Contents \\ Info.plist " ) ;
FSInject - > AddStringToList ( ForceLoadKexts , L " \\ AppleGraphicsControl.kext \\ Info.plist " ) ;
FSInject - > AddStringToList ( ForceLoadKexts , L " \\ AppleGraphicsControl.kext \\ Contents \\ PlugIns \\ AppleGraphicsDeviceControl.kext \\ Info.plist " ) ;
//as well IOAcceleratorFamily2
}
//
// Patch function.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : ATIConnectorsPatch ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize )
2019-09-03 11:58:42 +02:00
{
UINTN Num = 0 ;
2020-05-03 19:34:46 +02:00
DBG_RT ( " \n ATIConnectorsPatch: driverAddr = %llx, driverSize = %x \n Controller = %s \n " ,
( UINTN ) Driver , DriverSize , KernelAndKextPatches - > KPATIConnectorsController ) ;
2019-09-03 11:58:42 +02:00
ExtractKextBundleIdentifier ( InfoPlist ) ;
2020-05-01 18:26:28 +02:00
DBG_RT ( " Kext: %s \n " , gKextBundleIdentifier ) ;
2019-09-03 11:58:42 +02:00
// number of occurences od Data should be 1
2020-05-01 18:26:28 +02:00
Num = SearchAndCount ( Driver , DriverSize , KernelAndKextPatches - > KPATIConnectorsData , KernelAndKextPatches - > KPATIConnectorsDataLen ) ;
2019-09-03 11:58:42 +02:00
if ( Num > 1 ) {
// error message - shoud always be printed
2020-03-28 07:36:07 +01:00
printf ( " ==> KPATIConnectorsData found %llu times in %s - skipping patching! \n " , Num , gKextBundleIdentifier ) ;
2020-05-01 18:26:28 +02:00
Stall ( 5 * 1000000 ) ;
2019-09-03 11:58:42 +02:00
return ;
}
// patch
Num = SearchAndReplace ( Driver ,
DriverSize ,
2020-05-01 18:26:28 +02:00
KernelAndKextPatches - > KPATIConnectorsData ,
KernelAndKextPatches - > KPATIConnectorsDataLen ,
KernelAndKextPatches - > KPATIConnectorsPatch ,
2019-09-03 11:58:42 +02:00
1 ) ;
if ( Num > 0 ) {
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> patched %llu times! \n " , Num ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> NOT patched! \n " ) ;
2019-09-03 11:58:42 +02:00
}
2020-05-01 18:26:28 +02:00
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
}
////////////////////////////////////
//
// AppleIntelCPUPM patch
//
// fLaked's SpeedStepper patch for Asus (and some other) boards:
// http://www.insanelymac.com/forum/index.php?showtopic=258611
//
// Credits: Samantha/RevoGirl/DHP
// http://www.insanelymac.com/forum/topic/253642-dsdt-for-asus-p8p67-m-pro/page__st__200#entry1681099
// Rehabman corrections 2014
//
2020-05-07 20:13:08 +02:00
const UINT8 MovlE2ToEcx [ ] = { 0xB9 , 0xE2 , 0x00 , 0x00 , 0x00 } ;
const UINT8 MovE2ToCx [ ] = { 0x66 , 0xB9 , 0xE2 , 0x00 } ;
const UINT8 Wrmsr [ ] = { 0x0F , 0x30 } ;
2019-09-03 11:58:42 +02:00
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : AppleIntelCPUPMPatch ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize )
2019-09-03 11:58:42 +02:00
{
UINTN Index1 ;
UINTN Index2 ;
UINTN Count = 0 ;
2020-05-06 15:35:25 +02:00
UINTN Start = 0 ;
UINTN Size = DriverSize ;
2019-09-03 11:58:42 +02:00
2020-05-03 19:34:46 +02:00
DBG_RT ( " \n AppleIntelCPUPMPatch: driverAddr = %llx, driverSize = %x \n " , ( UINTN ) Driver , DriverSize ) ;
2020-05-06 15:35:25 +02:00
// if (KernelAndKextPatches->KPDebug) {
// ExtractKextBundleIdentifier(InfoPlist);
// }
// DBG_RT("Kext: %s\n", gKextBundleIdentifier);
2019-09-03 11:58:42 +02:00
2020-05-05 21:15:59 +02:00
// we should scan only __text __TEXT | Slice -> do this
2020-05-06 15:35:25 +02:00
INTN textName = FindMem ( Driver , DriverSize , kPrelinkTextSection , sizeof ( kPrelinkTextSection ) ) ;
if ( textName > 0 ) {
SEGMENT * textSeg = ( SEGMENT * ) & Driver [ textName ] ;
Start = textSeg - > fileoff ;
Size = textSeg - > filesize ;
2020-05-10 11:41:34 +02:00
DBG ( " found __text [%llu,%llu] \n " , Start , Size ) ;
2020-05-06 15:35:25 +02:00
if ( Start > DriverSize ) Start = 0 ;
if ( Size > DriverSize ) {
Size = DriverSize ;
}
}
2020-05-05 21:15:59 +02:00
for ( Index1 = Start ; Index1 < Start + Size ; Index1 + + ) {
2019-09-03 11:58:42 +02:00
// search for MovlE2ToEcx
if ( CompareMem ( Driver + Index1 , MovlE2ToEcx , sizeof ( MovlE2ToEcx ) ) = = 0 ) {
// search for wrmsr in next few bytes
for ( Index2 = Index1 + sizeof ( MovlE2ToEcx ) ; Index2 < Index1 + sizeof ( MovlE2ToEcx ) + 32 ; Index2 + + ) {
if ( Driver [ Index2 ] = = Wrmsr [ 0 ] & & Driver [ Index2 + 1 ] = = Wrmsr [ 1 ] ) {
// found it - patch it with nops
Count + + ;
Driver [ Index2 ] = 0x90 ;
Driver [ Index2 + 1 ] = 0x90 ;
2020-05-01 18:26:28 +02:00
DBG_RT ( " %llu. patched at 0x%llx \n " , Count , Index2 ) ;
2019-09-03 11:58:42 +02:00
break ;
} else if ( ( Driver [ Index2 ] = = 0xC9 & & Driver [ Index2 + 1 ] = = 0xC3 ) | |
( Driver [ Index2 ] = = 0x5D & & Driver [ Index2 + 1 ] = = 0xC3 ) | |
( Driver [ Index2 ] = = 0xB9 & & Driver [ Index2 + 3 ] = = 0 & & Driver [ Index2 + 4 ] = = 0 ) | |
( Driver [ Index2 ] = = 0x66 & & Driver [ Index2 + 1 ] = = 0xB9 & & Driver [ Index2 + 3 ] = = 0 ) ) {
// a leave/ret will cancel the search
// so will an intervening "mov[l] $xx, [e]cx"
break ;
}
}
} else if ( CompareMem ( Driver + Index1 , MovE2ToCx , sizeof ( MovE2ToCx ) ) = = 0 ) {
// search for wrmsr in next few bytes
for ( Index2 = Index1 + sizeof ( MovE2ToCx ) ; Index2 < Index1 + sizeof ( MovE2ToCx ) + 32 ; Index2 + + ) {
if ( Driver [ Index2 ] = = Wrmsr [ 0 ] & & Driver [ Index2 + 1 ] = = Wrmsr [ 1 ] ) {
// found it - patch it with nops
Count + + ;
Driver [ Index2 ] = 0x90 ;
Driver [ Index2 + 1 ] = 0x90 ;
2020-05-05 21:15:59 +02:00
DBG_RT ( " %llu. patched CX at 0x%llx \n " , Count , Index2 ) ;
2019-09-03 11:58:42 +02:00
break ;
} else if ( ( Driver [ Index2 ] = = 0xC9 & & Driver [ Index2 + 1 ] = = 0xC3 ) | |
( Driver [ Index2 ] = = 0x5D & & Driver [ Index2 + 1 ] = = 0xC3 ) | |
( Driver [ Index2 ] = = 0xB9 & & Driver [ Index2 + 3 ] = = 0 & & Driver [ Index2 + 4 ] = = 0 ) | |
( Driver [ Index2 ] = = 0x66 & & Driver [ Index2 + 1 ] = = 0xB9 & & Driver [ Index2 + 3 ] = = 0 ) ) {
// a leave/ret will cancel the search
// so will an intervening "mov[l] $xx, [e]cx"
break ;
}
}
}
}
2020-05-01 18:26:28 +02:00
DBG_RT ( " = %llu patches \n " , Count ) ;
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
}
////////////////////////////////////
//
// AppleRTC patch to prevent CMOS reset
//
// http://www.insanelymac.com/forum/index.php?showtopic=253992
// http://www.insanelymac.com/forum/index.php?showtopic=276066
//
2020-05-02 18:00:31 +02:00
# if OLD_METHOD
const UINT8 LionSearch_X64 [ ] = { 0x75 , 0x30 , 0x44 , 0x89 , 0xf8 } ;
const UINT8 LionReplace_X64 [ ] = { 0xeb , 0x30 , 0x44 , 0x89 , 0xf8 } ;
2019-09-03 11:58:42 +02:00
2020-05-02 18:00:31 +02:00
const UINT8 LionSearch_i386 [ ] = { 0x75 , 0x3d , 0x8b , 0x75 , 0x08 } ;
const UINT8 LionReplace_i386 [ ] = { 0xeb , 0x3d , 0x8b , 0x75 , 0x08 } ;
2019-09-03 11:58:42 +02:00
2020-05-02 18:00:31 +02:00
const UINT8 MLSearch [ ] = { 0x75 , 0x30 , 0x89 , 0xd8 } ;
const UINT8 MLReplace [ ] = { 0xeb , 0x30 , 0x89 , 0xd8 } ;
2019-09-03 11:58:42 +02:00
// SunKi: 10.9 - 10.14.3
2020-05-02 18:00:31 +02:00
const UINT8 MavMoj3Search [ ] = { 0x75 , 0x2e , 0x0f , 0xb6 } ;
const UINT8 MavMoj3Replace [ ] = { 0xeb , 0x2e , 0x0f , 0xb6 } ;
2019-09-03 11:58:42 +02:00
// RodionS: 10.14.4+ / 10.15 DB1
2020-05-02 18:00:31 +02:00
const UINT8 Moj4CataSearch [ ] = { 0x75 , 0x33 , 0x0f , 0xb7 } ;
const UINT8 Moj4CataReplace [ ] = { 0xeb , 0x33 , 0x0f , 0xb7 } ;
# endif
2019-09-03 11:58:42 +02:00
//
// We can not rely on OSVersion global variable for OS version detection,
2020-05-07 20:13:08 +02:00
// since in some cases it is not correct (install of ML from Lion, for example). -- AppleRTC patch is not needed for installation
2019-09-03 11:58:42 +02:00
// So, we'll use "brute-force" method - just try to patch.
// Actually, we'll at least check that if we can find only one instance of code that
// we are planning to patch.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : AppleRTCPatch ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize )
2019-09-03 11:58:42 +02:00
{
2020-05-02 18:00:31 +02:00
# if OLD_METHOD
2019-09-03 11:58:42 +02:00
UINTN Num = 0 ;
UINTN NumLion_X64 = 0 ;
UINTN NumLion_i386 = 0 ;
UINTN NumML = 0 ;
UINTN NumMavMoj3 = 0 ;
UINTN NumMoj4 = 0 ;
2020-05-03 19:34:46 +02:00
DBG_RT ( " \n AppleRTCPatch: driverAddr = %llx, driverSize = %x \n " , ( UINTN ) Driver , DriverSize ) ;
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPDebug ) {
2019-09-03 11:58:42 +02:00
ExtractKextBundleIdentifier ( InfoPlist ) ;
}
2020-05-01 18:26:28 +02:00
DBG_RT ( " Kext: %s \n " , gKextBundleIdentifier ) ;
2019-09-03 11:58:42 +02:00
if ( is64BitKernel ) {
NumLion_X64 = SearchAndCount ( Driver , DriverSize , LionSearch_X64 , sizeof ( LionSearch_X64 ) ) ;
NumML = SearchAndCount ( Driver , DriverSize , MLSearch , sizeof ( MLSearch ) ) ;
NumMavMoj3 = SearchAndCount ( Driver , DriverSize , MavMoj3Search , sizeof ( MavMoj3Search ) ) ;
NumMoj4 = SearchAndCount ( Driver , DriverSize , Moj4CataSearch , sizeof ( Moj4CataSearch ) ) ;
} else {
NumLion_i386 = SearchAndCount ( Driver , DriverSize , LionSearch_i386 , sizeof ( LionSearch_i386 ) ) ;
}
if ( NumLion_X64 + NumLion_i386 + NumML + NumMavMoj3 + NumMoj4 > 1 ) {
// more then one pattern found - we do not know what to do with it
2019-10-08 22:57:18 +02:00
// and we'll skip it
2020-03-28 07:36:07 +01:00
printf ( " AppleRTCPatch: ERROR: multiple patterns found (LionX64: %llu, Lioni386: %llu, ML: %llu, MavMoj3: %llu, Moj4: %llu) - skipping patching! \n " ,
2019-09-03 11:58:42 +02:00
NumLion_X64 , NumLion_i386 , NumML , NumMavMoj3 , NumMoj4 ) ;
2020-05-01 18:26:28 +02:00
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
return ;
}
if ( NumLion_X64 = = 1 ) {
Num = SearchAndReplace ( Driver , DriverSize , LionSearch_X64 , sizeof ( LionSearch_X64 ) , LionReplace_X64 , 1 ) ;
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> Lion X64: %llu replaces done. \n " , Num ) ;
2019-09-03 11:58:42 +02:00
} else if ( NumLion_i386 = = 1 ) {
Num = SearchAndReplace ( Driver , DriverSize , LionSearch_i386 , sizeof ( LionSearch_i386 ) , LionReplace_i386 , 1 ) ;
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> Lion i386: %llu replaces done. \n " , Num ) ;
2019-09-03 11:58:42 +02:00
} else if ( NumML = = 1 ) {
Num = SearchAndReplace ( Driver , DriverSize , MLSearch , sizeof ( MLSearch ) , MLReplace , 1 ) ;
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> MountainLion X64: %llu replaces done. \n " , Num ) ;
2019-09-03 11:58:42 +02:00
} else if ( NumMavMoj3 = = 1 ) {
Num = SearchAndReplace ( Driver , DriverSize , MavMoj3Search , sizeof ( MavMoj3Search ) , MavMoj3Replace , 1 ) ;
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> Mav/Yos/El/Sie/HS/Moj3 X64: %llu replaces done. \n " , Num ) ;
2019-09-03 11:58:42 +02:00
} else if ( NumMoj4 = = 1 ) {
Num = SearchAndReplace ( Driver , DriverSize , Moj4CataSearch , sizeof ( Moj4CataSearch ) , Moj4CataReplace , 1 ) ;
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> Mojave4 X64: %llu replaces done. \n " , Num ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> Patterns not found - patching NOT done. \n " ) ;
2019-09-03 11:58:42 +02:00
}
2020-05-02 18:00:31 +02:00
# else
//RodionS
2020-05-03 19:16:50 +02:00
UINTN procLocation = searchProcInDriver ( Driver , DriverSize , " updateChecksum " ) ;
2020-05-02 18:00:31 +02:00
if ( procLocation ! = 0 ) {
Driver [ procLocation ] = 0xC3 ;
2020-05-03 19:16:50 +02:00
DBG_RT ( " AppleRTC: patched \n " ) ;
} else {
DBG_RT ( " AppleRTC: not patched \n " ) ;
}
2020-05-02 18:00:31 +02:00
# endif
2020-05-01 18:26:28 +02:00
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
}
///////////////////////////////////
//
// InjectKexts if no FakeSMC: Detect FakeSMC and if present then
// disable kext injection InjectKexts()
//
// not used since 4242
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : CheckForFakeSMC ( CHAR8 * InfoPlist )
2019-09-03 11:58:42 +02:00
{
2020-05-01 18:26:28 +02:00
if ( OSFLAG_ISSET ( Flags , OSFLAG_CHECKFAKESMC ) & &
OSFLAG_ISSET ( Flags , OSFLAG_WITHKEXTS ) ) {
2019-09-03 11:58:42 +02:00
if ( AsciiStrStr ( InfoPlist , " <string>org.netkas.driver.FakeSMC</string> " ) ! = NULL
| | AsciiStrStr ( InfoPlist , " <string>org.netkas.FakeSMC</string> " ) ! = NULL
| | AsciiStrStr ( InfoPlist , " <string>as.vit9696.VirtualSMC</string> " ) ! = NULL )
{
2020-05-01 18:26:28 +02:00
Flags = OSFLAG_UNSET ( Flags , OSFLAG_WITHKEXTS ) ;
DBG_RT ( " \n FakeSMC or VirtualSMC found, UNSET WITHKEXTS \n " ) ;
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
}
}
}
////////////////////////////////////
//
// Dell SMBIOS Patch by syscl
//
// Remap SMBIOS Table 1 for both AppleSMBIOS and AppleACPIPlatform
//
// EB9D2D31-2D88-11D3-9A16-0090273F -> EB9D2D35-2D88-11D3-9A16-0090273F
//
STATIC UINT8 DELL_SMBIOS_GUID_Search [ ] = { 0x45 , 0x42 , 0x39 , 0x44 , 0x32 , 0x44 , 0x33 , 0x31 } ;
STATIC UINT8 DELL_SMBIOS_GUID_Replace [ ] = { 0x45 , 0x42 , 0x39 , 0x44 , 0x32 , 0x44 , 0x33 , 0x35 } ;
//
// EB9D2D31-2D88-11D3-9A16-0090273F is the standard SMBIOS Table Type 1 for
// all computers even though Apple.Inc should obey the rule
// that's why we can be so confident to write patch pattern this way - syscl
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : DellSMBIOSPatch ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize )
2019-09-03 11:58:42 +02:00
{
2020-05-01 18:26:28 +02:00
//
// syscl
// Note, smbios truncate issue only affects Broadwell platform and platform
// later than Broadwell thus we don't need to consider OS versinos earlier
// than Yosemite, they are all pure 64bit platforms
//
UINTN gPatchCount = 0 ;
2020-05-03 19:34:46 +02:00
DBG_RT ( " \n DellSMBIOSPatch: driverAddr = %llx, driverSize = %x \n " , ( UINTN ) Driver , DriverSize ) ;
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPDebug )
{
ExtractKextBundleIdentifier ( InfoPlist ) ;
}
DBG_RT ( " Kext: %s \n " , gKextBundleIdentifier ) ;
//
// now, let's patch it!
//
gPatchCount = SearchAndReplace ( Driver , DriverSize , DELL_SMBIOS_GUID_Search , sizeof ( DELL_SMBIOS_GUID_Search ) , DELL_SMBIOS_GUID_Replace , 1 ) ;
if ( gPatchCount > = 1 )
{
DBG_RT ( " ==> AppleSMBIOS: %llu replaces done. \n " , gPatchCount ) ;
}
else
{
DBG_RT ( " ==> Patterns not found - patching NOT done. \n " ) ;
}
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
}
////////////////////////////////////
//
// SNBE_AICPUPatch implemented by syscl
// Fix AppleIntelCPUPowerManagement on SandyBridge-E (c) omni, stinga11
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : SNBE_AICPUPatch ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize )
2019-09-03 11:58:42 +02:00
{
UINT32 i ;
2020-05-01 18:26:28 +02:00
UINT64 os_ver = AsciiOSVersionToUint64 ( OSVersion ) ;
2019-09-03 11:58:42 +02:00
2020-05-03 19:34:46 +02:00
DBG_RT ( " \n SNBE_AICPUPatch: driverAddr = %llx, driverSize = %x \n " , ( UINTN ) Driver , DriverSize ) ;
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPDebug ) {
2019-09-03 11:58:42 +02:00
ExtractKextBundleIdentifier ( InfoPlist ) ;
}
2020-05-01 18:26:28 +02:00
DBG_RT ( " Kext: %s \n " , gKextBundleIdentifier ) ;
2019-09-03 11:58:42 +02:00
// now let's patch it
if ( os_ver < AsciiOSVersionToUint64 ( " 10.9 " ) | | os_ver > = AsciiOSVersionToUint64 ( " 10.14 " ) ) {
DBG ( " Unsupported macOS. \n SandyBridge-E requires macOS 10.9 - 10.13.x, aborted \n " ) ;
DBG ( " SNBE_AICPUPatch() <===FALSE \n " ) ;
return ;
}
if ( os_ver < AsciiOSVersionToUint64 ( " 10.10 " ) ) {
// 10.9.x
2020-05-03 19:34:46 +02:00
const UINT8 find [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x84 , 0x2F , 0x01 } ,
{ 0x3E , 0x75 , 0x3A } ,
{ 0x84 , 0x5F , 0x01 } ,
{ 0x74 , 0x10 , 0xB9 } ,
{ 0x75 , 0x07 , 0xB9 } ,
{ 0xFC , 0x02 , 0x74 } ,
{ 0x01 , 0x74 , 0x58 }
} ;
2020-05-03 19:34:46 +02:00
const UINT8 repl [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x85 , 0x2F , 0x01 } ,
{ 0x3E , 0x90 , 0x90 } ,
{ 0x85 , 0x5F , 0x01 } ,
{ 0xEB , 0x10 , 0xB9 } ,
{ 0xEB , 0x07 , 0xB9 } ,
{ 0xFC , 0x02 , 0xEB } ,
{ 0x01 , 0xEB , 0x58 }
} ;
for ( i = 0 ; i < 7 ; i + + ) {
if ( SearchAndReplace ( Driver , DriverSize , find [ i ] , sizeof ( find [ i ] ) , repl [ i ] , 0 ) ) {
DBG ( " SNBE_AICPUPatch (%d/7) applied \n " , i ) ;
} else {
DBG ( " SNBE_AICPUPatch (%d/7) not apply \n " , i ) ;
}
}
} else if ( os_ver < AsciiOSVersionToUint64 ( " 10.11 " ) ) {
// 10.10.x
2020-05-03 19:34:46 +02:00
const UINT8 find [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x3E , 0x75 , 0x39 } ,
{ 0x74 , 0x11 , 0xB9 } ,
{ 0x01 , 0x74 , 0x56 }
} ;
2020-05-03 19:34:46 +02:00
const UINT8 repl [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x3E , 0x90 , 0x90 } ,
{ 0xEB , 0x11 , 0xB9 } ,
{ 0x01 , 0xEB , 0x56 }
} ;
for ( i = 0 ; i < 3 ; i + + ) {
if ( SearchAndReplace ( Driver , DriverSize , find [ i ] , sizeof ( find [ i ] ) , repl [ i ] , 0 ) ) {
DBG ( " SNBE_AICPUPatch (%d/7) applied \n " , i ) ;
} else {
DBG ( " SNBE_AICPUPatch (%d/7) not apply \n " , i ) ;
}
}
2020-05-03 19:34:46 +02:00
const UINT8 find_1 [ ] = { 0xFF , 0x0F , 0x84 , 0x2D } ;
const UINT8 repl_1 [ ] = { 0xFF , 0x0F , 0x85 , 0x2D } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_1 , sizeof ( find_1 ) , repl_1 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (4/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (4/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x84 } ;
const UINT8 repl_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x85 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_2 , sizeof ( find_2 ) , repl_2 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (5/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (5/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_3 [ ] = { 0x02 , 0x74 , 0x0B , 0x41 , 0x83 , 0xFC , 0x03 , 0x75 , 0x22 , 0xB9 , 0x02 , 0x06 } ;
const UINT8 repl_3 [ ] = { 0x02 , 0xEB , 0x0B , 0x41 , 0x83 , 0xFC , 0x03 , 0x75 , 0x22 , 0xB9 , 0x02 , 0x06 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_3 , sizeof ( find_3 ) , repl_3 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (6/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (6/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_4 [ ] = { 0x74 , 0x0B , 0x41 , 0x83 , 0xFC , 0x03 , 0x75 , 0x11 , 0xB9 , 0x42 , 0x06 , 0x00 } ;
const UINT8 repl_4 [ ] = { 0xEB , 0x0B , 0x41 , 0x83 , 0xFC , 0x03 , 0x75 , 0x11 , 0xB9 , 0x42 , 0x06 , 0x00 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_4 , sizeof ( find_4 ) , repl_4 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (7/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (7/7) not apply \n " ) ;
}
} else if ( os_ver < AsciiOSVersionToUint64 ( " 10.12 " ) ) {
// 10.11
2020-05-03 19:34:46 +02:00
const UINT8 find [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x3E , 0x75 , 0x39 } ,
{ 0x75 , 0x11 , 0xB9 } ,
{ 0x01 , 0x74 , 0x5F }
} ;
2020-05-03 19:34:46 +02:00
const UINT8 repl [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x3E , 0x90 , 0x90 } ,
{ 0xEB , 0x11 , 0xB9 } ,
{ 0x01 , 0xEB , 0x5F }
} ;
for ( i = 0 ; i < 3 ; i + + ) {
if ( SearchAndReplace ( Driver , DriverSize , find [ i ] , sizeof ( find [ i ] ) , repl [ i ] , 0 ) ) {
DBG ( " SNBE_AICPUPatch (%d/7) applied \n " , i ) ;
} else {
DBG ( " SNBE_AICPUPatch (%d/7) not apply \n " , i ) ;
}
}
2020-05-03 19:34:46 +02:00
const UINT8 find_1 [ ] = { 0xFF , 0x0F , 0x84 , 0x2D } ;
const UINT8 repl_1 [ ] = { 0xFF , 0x0F , 0x85 , 0x2D } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_1 , sizeof ( find_1 ) , repl_1 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (4/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (4/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x84 } ;
const UINT8 repl_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x85 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_2 , sizeof ( find_2 ) , repl_2 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (5/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (5/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_3 [ ] = { 0xC9 , 0x74 , 0x16 , 0x0F , 0x32 , 0x48 , 0x25 , 0xFF , 0x0F , 0x00 , 0x00 , 0x48 } ;
const UINT8 repl_3 [ ] = { 0xC9 , 0xEB , 0x16 , 0x0F , 0x32 , 0x48 , 0x25 , 0xFF , 0x0F , 0x00 , 0x00 , 0x48 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_3 , sizeof ( find_3 ) , repl_3 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (6/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (6/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_4 [ ] = { 0xC9 , 0x74 , 0x0C , 0x0F , 0x32 , 0x83 , 0xE0 , 0x1F , 0x42 , 0x89 , 0x44 , 0x3B } ;
const UINT8 repl_4 [ ] = { 0xC9 , 0xEB , 0x0C , 0x0F , 0x32 , 0x83 , 0xE0 , 0x1F , 0x42 , 0x89 , 0x44 , 0x3B } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_4 , sizeof ( find_4 ) , repl_4 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (7/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (7/7) not apply \n " ) ;
}
} else if ( os_ver < AsciiOSVersionToUint64 ( " 10.13 " ) ) {
// 10.12
2020-05-03 19:34:46 +02:00
const UINT8 find [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x01 , 0x74 , 0x61 } ,
{ 0x3E , 0x75 , 0x38 } ,
{ 0x75 , 0x11 , 0xB9 }
} ;
2020-05-03 19:34:46 +02:00
const UINT8 repl [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x01 , 0xEB , 0x61 } ,
{ 0x3E , 0x90 , 0x90 } ,
{ 0xEB , 0x11 , 0xB9 }
} ;
for ( i = 0 ; i < 3 ; i + + ) {
if ( SearchAndReplace ( Driver , DriverSize , find [ i ] , sizeof ( find [ i ] ) , repl [ i ] , 0 ) ) {
DBG ( " SNBE_AICPUPatch (%d/7) applied \n " , i ) ;
} else {
DBG ( " SNBE_AICPUPatch (%d/7) not apply \n " , i ) ;
}
}
2020-05-03 19:34:46 +02:00
const UINT8 find_1 [ ] = { 0xFF , 0x0F , 0x84 , 0x2D } ;
const UINT8 repl_1 [ ] = { 0xFF , 0x0F , 0x85 , 0x2D } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_1 , sizeof ( find_1 ) , repl_1 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (4/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (4/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x84 } ;
const UINT8 repl_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x85 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_2 , sizeof ( find_2 ) , repl_2 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (5/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (5/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_3 [ ] = { 0xC9 , 0x74 , 0x15 , 0x0F , 0x32 , 0x25 , 0xFF , 0x0F , 0x00 , 0x00 , 0x48 } ;
const UINT8 repl_3 [ ] = { 0xC9 , 0xEB , 0x15 , 0x0F , 0x32 , 0x25 , 0xFF , 0x0F , 0x00 , 0x00 , 0x48 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_3 , sizeof ( find_3 ) , repl_3 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (6/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (6/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_4 [ ] = { 0xC9 , 0x74 , 0x0C , 0x0F , 0x32 , 0x83 , 0xE0 , 0x1F , 0x42 , 0x89 , 0x44 , 0x3B } ;
const UINT8 repl_4 [ ] = { 0xC9 , 0xEB , 0x0C , 0x0F , 0x32 , 0x83 , 0xE0 , 0x1F , 0x42 , 0x89 , 0x44 , 0x3B } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_4 , sizeof ( find_4 ) , repl_4 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (7/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (7/7) not apply \n " ) ;
}
} else if ( os_ver < AsciiOSVersionToUint64 ( " 10.15 " ) ) {
// 10.13/10.14
2020-05-03 19:34:46 +02:00
const UINT8 find [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x01 , 0x74 , 0x61 } ,
{ 0x3E , 0x75 , 0x38 } ,
{ 0x75 , 0x11 , 0xB9 }
} ;
2020-05-03 19:34:46 +02:00
const UINT8 repl [ ] [ 3 ] = {
2019-09-03 11:58:42 +02:00
{ 0x01 , 0xEB , 0x61 } ,
{ 0x3E , 0x90 , 0x90 } ,
{ 0xEB , 0x11 , 0xB9 }
} ;
for ( i = 0 ; i < 3 ; i + + ) {
if ( SearchAndReplace ( Driver , DriverSize , find [ i ] , sizeof ( find [ i ] ) , repl [ i ] , 0 ) ) {
DBG ( " SNBE_AICPUPatch (%d/7) applied \n " , i ) ;
} else {
DBG ( " SNBE_AICPUPatch (%d/7) not apply \n " , i ) ;
}
}
2020-05-03 19:34:46 +02:00
const UINT8 find_1 [ ] = { 0xFF , 0x0F , 0x84 , 0xD3 } ;
const UINT8 repl_1 [ ] = { 0xFF , 0x0F , 0x85 , 0xD3 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_1 , sizeof ( find_1 ) , repl_1 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (4/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (4/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x84 } ;
const UINT8 repl_2 [ ] = { 0x01 , 0x00 , 0x01 , 0x0F , 0x85 } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_2 , sizeof ( find_2 ) , repl_2 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (5/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (5/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_3 [ ] = { 0xC9 , 0x74 , 0x14 , 0x0F , 0x32 , 0x25 , 0xFF , 0x0F , 0x00 , 0x00 , 0x6B } ;
const UINT8 repl_3 [ ] = { 0xC9 , 0xEB , 0x14 , 0x0F , 0x32 , 0x25 , 0xFF , 0x0F , 0x00 , 0x00 , 0x6B } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_3 , sizeof ( find_3 ) , repl_3 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (6/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (6/7) not apply \n " ) ;
}
2020-05-03 19:34:46 +02:00
const UINT8 find_4 [ ] = { 0xC9 , 0x74 , 0x0C , 0x0F , 0x32 , 0x83 , 0xE0 , 0x1F , 0x42 , 0x89 , 0x44 , 0x3B } ;
const UINT8 repl_4 [ ] = { 0xC9 , 0xEB , 0x0C , 0x0F , 0x32 , 0x83 , 0xE0 , 0x1F , 0x42 , 0x89 , 0x44 , 0x3B } ;
2019-09-03 11:58:42 +02:00
if ( SearchAndReplace ( Driver , DriverSize , find_4 , sizeof ( find_4 ) , repl_4 , 0 ) ) {
DBG ( " SNBE_AICPUPatch (7/7) applied \n " ) ;
} else {
DBG ( " SNBE_AICPUPatch (7/7) not apply \n " ) ;
}
}
2020-05-01 18:26:28 +02:00
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
}
////////////////////////////////////
//
// BDWE_IOPCIPatch implemented by syscl
// Fix Broadwell-E IOPCIFamily issue
//
// El Capitan
2020-05-03 19:34:46 +02:00
const UINT8 BroadwellE_IOPCI_Find_El [ ] = { 0x48 , 0x81 , 0xF9 , 0x01 , 0x00 , 0x00 , 0x40 } ;
const UINT8 BroadwellE_IOPCI_Repl_El [ ] = { 0x48 , 0x81 , 0xF9 , 0x01 , 0x00 , 0x00 , 0x80 } ;
2019-09-03 11:58:42 +02:00
// Sierra/High Sierra
2020-05-03 19:34:46 +02:00
const UINT8 BroadwellE_IOPCI_Find_SieHS [ ] = { 0x48 , 0x81 , 0xFB , 0x00 , 0x00 , 0x00 , 0x40 } ;
const UINT8 BroadwellE_IOPCI_Repl_SieHS [ ] = { 0x48 , 0x81 , 0xFB , 0x00 , 0x00 , 0x00 , 0x80 } ;
2019-09-03 11:58:42 +02:00
// Mojave
2020-05-03 19:34:46 +02:00
const UINT8 BroadwellE_IOPCI_Find_MojCata [ ] = { 0x48 , 0x3D , 0x00 , 0x00 , 0x00 , 0x40 } ;
const UINT8 BroadwellE_IOPCI_Repl_MojCata [ ] = { 0x48 , 0x3D , 0x00 , 0x00 , 0x00 , 0x80 } ;
2019-09-03 11:58:42 +02:00
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : BDWE_IOPCIPatch ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize )
2019-09-03 11:58:42 +02:00
{
UINTN count = 0 ;
2020-05-01 18:26:28 +02:00
UINT64 os_ver = AsciiOSVersionToUint64 ( OSVersion ) ;
2019-09-03 11:58:42 +02:00
2020-05-03 19:34:46 +02:00
DBG_RT ( " \n BDWE_IOPCIPatch: driverAddr = %llx, driverSize = %x \n " , ( UINTN ) Driver , DriverSize ) ;
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPDebug ) {
2019-09-03 11:58:42 +02:00
ExtractKextBundleIdentifier ( InfoPlist ) ;
}
2020-05-01 18:26:28 +02:00
DBG_RT ( " Kext: %s \n " , gKextBundleIdentifier ) ;
2019-09-03 11:58:42 +02:00
//
// now, let's patch it!
//
if ( os_ver < AsciiOSVersionToUint64 ( " 10.12 " ) ) {
count = SearchAndReplace ( Driver , DriverSize , BroadwellE_IOPCI_Find_El , sizeof ( BroadwellE_IOPCI_Find_El ) , BroadwellE_IOPCI_Repl_El , 0 ) ;
} else if ( os_ver < AsciiOSVersionToUint64 ( " 10.14 " ) ) {
count = SearchAndReplace ( Driver , DriverSize , BroadwellE_IOPCI_Find_SieHS , sizeof ( BroadwellE_IOPCI_Find_SieHS ) , BroadwellE_IOPCI_Repl_SieHS , 0 ) ;
} else {
count = SearchAndReplace ( Driver , DriverSize , BroadwellE_IOPCI_Find_MojCata , sizeof ( BroadwellE_IOPCI_Find_MojCata ) , BroadwellE_IOPCI_Repl_MojCata , 0 ) ;
}
if ( count ) {
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> IOPCIFamily: %llu replaces done. \n " , count ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> Patterns not found - patching NOT done. \n " ) ;
2019-09-03 11:58:42 +02:00
}
2020-05-01 18:26:28 +02:00
Stall ( 5000000 ) ;
2019-09-03 11:58:42 +02:00
}
////////////////////////////////////
//
// Place other kext patches here
//
// ...
////////////////////////////////////
//
// Generic kext patch functions
//
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : AnyKextPatch ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize , INT32 N )
2019-09-03 11:58:42 +02:00
{
UINTN Num = 0 ;
INTN Ind ;
2020-05-03 09:03:06 +02:00
// if we modify value directly at KernelAndKextPatches->KextPatches[N].SearchLen, it will be wrong for next driver
UINTN SearchLen = KernelAndKextPatches - > KextPatches [ N ] . SearchLen ;
2019-09-03 11:58:42 +02:00
2020-05-03 19:20:34 +02:00
DBG_RT ( " \n AnyKextPatch %d: driverAddr = %llx, driverSize = %x \n AnyKext = %s \n " ,
N , ( UINTN ) Driver , DriverSize , KernelAndKextPatches - > KextPatches [ N ] . Label ) ;
2019-09-03 11:58:42 +02:00
2020-05-01 18:26:28 +02:00
if ( ! KernelAndKextPatches - > KextPatches [ N ] . MenuItem . BValue ) {
2019-09-03 11:58:42 +02:00
return ;
}
2020-05-03 19:16:50 +02:00
2020-04-25 18:18:18 +02:00
2020-05-03 09:03:06 +02:00
if ( ! SearchLen | |
( SearchLen > DriverSize ) ) {
SearchLen = DriverSize ;
2020-04-25 18:18:18 +02:00
}
2019-09-03 11:58:42 +02:00
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPDebug ) {
2019-09-03 11:58:42 +02:00
ExtractKextBundleIdentifier ( InfoPlist ) ;
}
2020-05-01 18:26:28 +02:00
DBG_RT ( " Kext: %s \n " , gKextBundleIdentifier ) ;
2019-09-03 11:58:42 +02:00
2020-05-01 18:26:28 +02:00
if ( ! KernelAndKextPatches - > KextPatches [ N ] . IsPlistPatch ) {
2019-09-03 11:58:42 +02:00
// kext binary patch
2020-05-01 18:26:28 +02:00
DBG_RT ( " Binary patch \n " ) ;
2020-04-27 17:16:43 +02:00
bool once = false ;
UINTN procLen = 0 ;
2020-05-03 19:16:50 +02:00
UINTN procAddr = searchProcInDriver ( Driver , DriverSize , KernelAndKextPatches - > KextPatches [ N ] . ProcedureName ) ;
2020-04-27 17:16:43 +02:00
2020-05-04 21:31:12 +02:00
if ( SearchLen = = DriverSize ) {
procLen = DriverSize - procAddr ;
once = true ;
2020-04-27 17:16:43 +02:00
} else {
2020-05-03 09:03:06 +02:00
procLen = SearchLen ;
2020-04-27 17:16:43 +02:00
}
2020-05-03 19:16:50 +02:00
UINT8 * curs = & Driver [ procAddr ] ;
2020-04-25 18:18:18 +02:00
UINTN j = 0 ;
while ( j < DriverSize ) {
2020-05-01 18:26:28 +02:00
if ( ! KernelAndKextPatches - > KextPatches [ N ] . StartPattern | | //old behavior
2020-05-02 05:38:38 +02:00
CompareMemMask ( ( const UINT8 * ) curs ,
( const UINT8 * ) KernelAndKextPatches - > KextPatches [ N ] . StartPattern ,
KernelAndKextPatches - > KextPatches [ N ] . StartPatternLen ,
( const UINT8 * ) KernelAndKextPatches - > KextPatches [ N ] . StartMask ,
2020-05-01 18:26:28 +02:00
KernelAndKextPatches - > KextPatches [ N ] . StartPatternLen ) ) {
DBG_RT ( " StartPattern found \n " ) ;
2020-04-25 18:18:18 +02:00
2020-05-03 19:16:50 +02:00
Num = SearchAndReplaceMask ( curs ,
2020-04-27 17:16:43 +02:00
procLen ,
2020-05-02 05:38:38 +02:00
( const UINT8 * ) KernelAndKextPatches - > KextPatches [ N ] . Data ,
( const UINT8 * ) KernelAndKextPatches - > KextPatches [ N ] . MaskFind ,
2020-05-01 18:26:28 +02:00
KernelAndKextPatches - > KextPatches [ N ] . DataLen ,
2020-05-02 05:38:38 +02:00
( const UINT8 * ) KernelAndKextPatches - > KextPatches [ N ] . Patch ,
( const UINT8 * ) KernelAndKextPatches - > KextPatches [ N ] . MaskReplace ,
2020-04-25 18:18:18 +02:00
- 1 ) ;
if ( Num ) {
2020-05-03 09:03:06 +02:00
curs + = SearchLen - 1 ;
j + = SearchLen - 1 ;
2020-04-25 18:18:18 +02:00
}
}
2020-04-27 17:16:43 +02:00
if ( once | |
2020-05-01 18:26:28 +02:00
! KernelAndKextPatches - > KextPatches [ N ] . StartPattern | |
! KernelAndKextPatches - > KextPatches [ N ] . StartPatternLen ) {
2020-04-26 07:32:48 +02:00
break ;
}
2020-04-25 18:18:18 +02:00
j + + ; curs + + ;
}
2019-09-03 11:58:42 +02:00
} else {
// Info plist patch
2020-05-01 18:26:28 +02:00
DBG_RT ( " Info.plist data : ' " ) ;
for ( Ind = 0 ; Ind < KernelAndKextPatches - > KextPatches [ N ] . DataLen ; Ind + + ) {
DBG_RT ( " %c " , KernelAndKextPatches - > KextPatches [ N ] . Data [ Ind ] ) ;
2019-09-03 11:58:42 +02:00
}
2020-05-01 18:26:28 +02:00
DBG_RT ( " ' -> \n " ) ;
DBG_RT ( " Info.plist patch: ' " ) ;
for ( Ind = 0 ; Ind < KernelAndKextPatches - > KextPatches [ N ] . DataLen ; Ind + + ) {
DBG_RT ( " %c " , KernelAndKextPatches - > KextPatches [ N ] . Patch [ Ind ] ) ;
2019-09-03 11:58:42 +02:00
}
2020-05-01 18:26:28 +02:00
DBG_RT ( " ' \n " ) ;
2019-09-03 11:58:42 +02:00
Num = SearchAndReplaceTxt ( ( UINT8 * ) InfoPlist ,
InfoPlistSize ,
2020-05-01 18:26:28 +02:00
KernelAndKextPatches - > KextPatches [ N ] . Data ,
KernelAndKextPatches - > KextPatches [ N ] . DataLen ,
KernelAndKextPatches - > KextPatches [ N ] . Patch ,
2019-09-03 11:58:42 +02:00
- 1 ) ;
}
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPDebug ) {
2019-09-03 11:58:42 +02:00
if ( Num > 0 ) {
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> patched %llu times! \n " , Num ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-05-01 18:26:28 +02:00
DBG_RT ( " ==> NOT patched! \n " ) ;
2019-09-03 11:58:42 +02:00
}
gBS - > Stall ( 2000000 ) ;
}
}
//
// Called from SetFSInjection(), before boot.efi is started,
// to allow patchers to prepare FSInject to force load needed kexts.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : KextPatcherRegisterKexts ( void * FSInject_v , void * ForceLoadKexts )
2019-09-03 11:58:42 +02:00
{
2020-05-01 18:26:28 +02:00
FSINJECTION_PROTOCOL * FSInject = ( FSINJECTION_PROTOCOL * ) FSInject_v ;
if ( KernelAndKextPatches - > KPATIConnectorsController ! = NULL ) {
ATIConnectorsPatchRegisterKexts ( FSInject_v , ForceLoadKexts ) ;
2019-09-03 11:58:42 +02:00
}
2020-05-01 18:26:28 +02:00
for ( INTN i = 0 ; i < KernelAndKextPatches - > NrKexts ; i + + ) {
FSInject - > AddStringToList ( ( FSI_STRING_LIST * ) ForceLoadKexts ,
2019-09-03 11:58:42 +02:00
PoolPrint ( L " \\ %a.kext \\ Contents \\ Info.plist " ,
2020-05-01 18:26:28 +02:00
KernelAndKextPatches - > KextPatches [ i ] . Name ) ) ;
2019-09-03 11:58:42 +02:00
}
}
//
// PatchKext is called for every kext from prelinked kernel (kernelcache) or from DevTree (booting with drivers).
// Add kext detection code here and call kext specific patch function.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : PatchKext ( UINT8 * Driver , UINT32 DriverSize , CHAR8 * InfoPlist , UINT32 InfoPlistSize )
2019-09-03 11:58:42 +02:00
{
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPATIConnectorsController ! = NULL ) {
2019-09-03 11:58:42 +02:00
//
// ATIConnectors
//
if ( ! ATIConnectorsPatchInited ) {
2020-05-01 18:26:28 +02:00
ATIConnectorsPatchInit ( ) ;
2019-09-03 11:58:42 +02:00
}
if ( AsciiStrStr ( InfoPlist , ATIKextBundleId [ 0 ] ) ! = NULL // ATI boundle id
| | AsciiStrStr ( InfoPlist , ATIKextBundleId [ 1 ] ) ! = NULL // AMD boundle id
| | AsciiStrStr ( InfoPlist , " com.apple.kext.ATIFramebuffer " ) ! = NULL // SnowLeo
| | AsciiStrStr ( InfoPlist , " com.apple.kext.AMDFramebuffer " ) ! = NULL //Maverics
) {
2020-05-01 18:26:28 +02:00
ATIConnectorsPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize ) ;
2019-09-03 11:58:42 +02:00
return ;
}
}
ExtractKextBundleIdentifier ( InfoPlist ) ;
2020-05-01 18:26:28 +02:00
if ( KernelAndKextPatches - > KPAppleIntelCPUPM & &
2019-09-03 11:58:42 +02:00
( AsciiStrStr ( InfoPlist ,
" <string>com.apple.driver.AppleIntelCPUPowerManagement</string> " ) ! = NULL ) ) {
//
// AppleIntelCPUPM
//
2020-05-01 18:26:28 +02:00
AppleIntelCPUPMPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize ) ;
} else if ( KernelAndKextPatches - > KPAppleRTC & &
2019-09-03 11:58:42 +02:00
( AsciiStrStr ( InfoPlist , " com.apple.driver.AppleRTC " ) ! = NULL ) ) {
//
// AppleRTC
//
2020-05-01 18:26:28 +02:00
AppleRTCPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize ) ;
} else if ( KernelAndKextPatches - > KPDELLSMBIOS & &
2019-09-03 11:58:42 +02:00
( AsciiStrStr ( InfoPlist , " com.apple.driver.AppleSMBIOS " ) ! = NULL ) ) {
//
// DellSMBIOSPatch
//
2020-05-01 18:26:28 +02:00
DBG_RT ( " Remap SMBIOS Table require, AppleSMBIOS... \n " ) ;
DellSMBIOSPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize ) ;
} else if ( KernelAndKextPatches - > KPDELLSMBIOS & &
2019-09-03 11:58:42 +02:00
( AsciiStrStr ( InfoPlist , " com.apple.driver.AppleACPIPlatform " ) ! = NULL ) ) {
//
// DellSMBIOS
//
// AppleACPIPlatform
//
2020-05-01 18:26:28 +02:00
DellSMBIOSPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize ) ;
2019-09-03 11:58:42 +02:00
} else if ( gBDWEIOPCIFixRequire & & ( AsciiStrStr ( InfoPlist , " com.apple.iokit.IOPCIFamily " ) ! = NULL ) ) {
//
2020-05-01 18:26:28 +02:00
// Broadwell-E IOPCIFamily Patch
2019-09-03 11:58:42 +02:00
//
2020-05-01 18:26:28 +02:00
BDWE_IOPCIPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize ) ;
2019-09-03 11:58:42 +02:00
} else if ( gSNBEAICPUFixRequire & & ( AsciiStrStr ( InfoPlist , " com.apple.driver.AppleIntelCPUPowerManagement " ) ! = NULL ) ) {
//
// SandyBridge-E AppleIntelCPUPowerManagement Patch implemented by syscl
//
2020-05-01 18:26:28 +02:00
SNBE_AICPUPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize ) ;
2019-09-03 11:58:42 +02:00
}
2020-05-01 18:26:28 +02:00
for ( INT32 i = 0 ; i < KernelAndKextPatches - > NrKexts ; i + + ) {
CHAR8 * Name = KernelAndKextPatches - > KextPatches [ i ] . Name ;
2019-09-03 11:58:42 +02:00
BOOLEAN isBundle = ( AsciiStrStr ( Name , " . " ) ! = NULL ) ;
2020-05-01 18:26:28 +02:00
if ( ( KernelAndKextPatches - > KextPatches [ i ] . DataLen > 0 ) & &
2019-09-03 11:58:42 +02:00
isBundle ? ( AsciiStrCmp ( gKextBundleIdentifier , Name ) = = 0 ) : ( AsciiStrStr ( gKextBundleIdentifier , Name ) ! = NULL ) ) {
2020-05-01 18:26:28 +02:00
// (AsciiStrStr(InfoPlist, KernelAndKextPatches->KextPatches[i].Name) != NULL)) {
DBG_RT ( " \n \n Patch kext: %s \n " , KernelAndKextPatches - > KextPatches [ i ] . Name ) ;
AnyKextPatch ( Driver , DriverSize , InfoPlist , InfoPlistSize , i ) ;
2019-09-03 11:58:42 +02:00
}
}
}
//
// Returns parsed hex integer key.
// Plist - kext pist
// Key - key to find
// WholePlist - _PrelinkInfoDictionary, used to find referenced values
//
// Searches for Key in Plist and it's value:
// a) <integer ID="26" size="64">0x2b000</integer>
// returns 0x2b000
// b) <integer IDREF="26"/>
// searches for <integer ID="26"... from WholePlist
// and returns value from that referenced field
//
// Whole function is here since we should avoid ParseXML() and it's
// memory allocations during ExitBootServices(). And it seems that
// ParseXML() does not support IDREF.
// This func is hard to read and debug and probably not reliable,
// but it seems it works.
//
2020-02-17 21:41:09 +01:00
UINT64 GetPlistHexValue ( CONST CHAR8 * Plist , CONST CHAR8 * Key , CONST CHAR8 * WholePlist )
2019-09-03 11:58:42 +02:00
{
CHAR8 * Value ;
CHAR8 * IntTag ;
UINT64 NumValue = 0 ;
CHAR8 * IDStart ;
CHAR8 * IDEnd ;
UINTN IDLen ;
CHAR8 Buffer [ 48 ] ;
//static INTN DbgCount = 0;
// search for Key
Value = AsciiStrStr ( Plist , Key ) ;
if ( Value = = NULL ) {
2020-03-25 19:32:44 +01:00
//DBG(L"\nNo key: %s\n", Key);
2019-09-03 11:58:42 +02:00
return 0 ;
}
// search for <integer
IntTag = AsciiStrStr ( Value , " <integer " ) ;
if ( IntTag = = NULL ) {
2020-03-26 13:59:20 +01:00
DBG ( " \n No integer \n " ) ;
2019-09-03 11:58:42 +02:00
return 0 ;
}
// find <integer end
Value = AsciiStrStr ( IntTag , " > " ) ;
if ( Value = = NULL ) {
2020-03-26 13:59:20 +01:00
DBG ( " \n No <integer end \n " ) ;
2019-09-03 11:58:42 +02:00
return 0 ;
}
if ( Value [ - 1 ] ! = ' / ' ) {
// normal case: value is here
NumValue = AsciiStrHexToUint64 ( Value + 1 ) ;
return NumValue ;
}
// it might be a reference: IDREF="173"/>
Value = AsciiStrStr ( IntTag , " <integer IDREF= \" " ) ;
if ( Value ! = IntTag ) {
2020-03-26 13:59:20 +01:00
DBG ( " \n No <integer IDREF= \" \n " ) ;
2019-09-03 11:58:42 +02:00
return 0 ;
}
// compose <integer ID="xxx" in the Buffer
IDStart = AsciiStrStr ( IntTag , " \" " ) + 1 ;
IDEnd = AsciiStrStr ( IDStart , " \" " ) ;
IDLen = IDEnd - IDStart ;
/*
if ( DbgCount < 3 ) {
AsciiStrnCpy ( Buffer , Value , sizeof ( Buffer ) - 1 ) ;
2020-03-25 19:32:44 +01:00
DBG ( L " \n Ref: '%s' \n " , Buffer ) ;
2019-09-03 11:58:42 +02:00
}
*/
if ( IDLen > 8 ) {
2020-03-26 13:59:20 +01:00
DBG ( " \n IDLen too big \n " ) ;
2019-09-03 11:58:42 +02:00
return 0 ;
}
AsciiStrCpyS ( Buffer , 48 , " <integer ID= \" " ) ;
AsciiStrnCatS ( Buffer , 48 , IDStart , IDLen ) ;
AsciiStrCatS ( Buffer , 48 , " \" " ) ;
/*
if ( DbgCount < 3 ) {
2020-03-25 19:32:44 +01:00
DBG ( L " Searching: '%s' \n " , Buffer ) ;
2019-09-03 11:58:42 +02:00
}
*/
// and search whole plist for ID
IntTag = AsciiStrStr ( WholePlist , Buffer ) ;
if ( IntTag = = NULL ) {
2020-03-26 13:59:20 +01:00
DBG ( " \n No %s \n " , Buffer ) ;
2019-09-03 11:58:42 +02:00
return 0 ;
}
// got it. find closing >
/*
if ( DbgCount < 3 ) {
AsciiStrnCpy ( Buffer , IntTag , sizeof ( Buffer ) - 1 ) ;
2020-03-25 19:32:44 +01:00
DBG ( L " Found: '%s' \n " , Buffer ) ;
2019-09-03 11:58:42 +02:00
}
*/
Value = AsciiStrStr ( IntTag , " > " ) ;
if ( Value = = NULL ) {
2020-03-26 13:59:20 +01:00
DBG ( " \n No <integer end \n " ) ;
2019-09-03 11:58:42 +02:00
return 0 ;
}
if ( Value [ - 1 ] = = ' / ' ) {
2020-03-26 13:59:20 +01:00
DBG ( " \n Invalid <integer IDREF end \n " ) ;
2019-09-03 11:58:42 +02:00
return 0 ;
}
// we should have value now
NumValue = AsciiStrHexToUint64 ( Value + 1 ) ;
/*
if ( DbgCount < 3 ) {
AsciiStrnCpy ( Buffer , IntTag , sizeof ( Buffer ) - 1 ) ;
2020-04-17 15:14:24 +02:00
DBG ( L " Found num: %hhX \n " , NumValue ) ;
2019-09-03 11:58:42 +02:00
gBS - > Stall ( 10000000 ) ;
}
DbgCount + + ;
*/
return NumValue ;
}
//
// Iterates over kexts in kernelcache
// and calls PatchKext() for each.
//
// PrelinkInfo section contains following plist, without spaces:
// <dict>
// <key>_PrelinkInfoDictionary</key>
// <array>
// <!-- start of kext Info.plist -->
// <dict>
// <key>CFBundleName</key>
// <string>MAC Framework Pseudoextension</string>
// <key>_PrelinkExecutableLoadAddr</key>
// <integer size="64">0xffffff7f8072f000</integer>
// <!-- Kext size -->
// <key>_PrelinkExecutableSize</key>
// <integer size="64">0x3d0</integer>
// <!-- Kext address -->
// <key>_PrelinkExecutableSourceAddr</key>
// <integer size="64">0xffffff80009a3000</integer>
// ...
// </dict>
// <!-- start of next kext Info.plist -->
// <dict>
// ...
// </dict>
// ...
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : PatchPrelinkedKexts ( )
2019-09-03 11:58:42 +02:00
{
CHAR8 * WholePlist ;
CHAR8 * DictPtr ;
CHAR8 * InfoPlistStart = NULL ;
CHAR8 * InfoPlistEnd = NULL ;
INTN DictLevel = 0 ;
CHAR8 SavedValue ;
//INTN DbgCount = 0;
UINT32 KextAddr ;
UINT32 KextSize ;
WholePlist = ( CHAR8 * ) ( UINTN ) PrelinkInfoAddr ;
//
// Detect FakeSMC and if present then
// disable kext injection InjectKexts().
// There is some bug in the folowing code that
// searches for individual kexts in prelink info
// and FakeSMC is not found on my SnowLeo although
// it is present in kernelcache.
// But searching through the whole prelink info
// works and that's the reason why it is here.
//
//Slice
// I see no reason to disable kext injection if FakeSMC found in cache
//since rev4240 we have manual kext inject disable
2020-05-01 18:26:28 +02:00
CheckForFakeSMC ( WholePlist ) ;
2019-09-03 11:58:42 +02:00
DictPtr = WholePlist ;
while ( ( DictPtr = AsciiStrStr ( DictPtr , " dict> " ) ) ! = NULL ) {
if ( DictPtr [ - 1 ] = = ' < ' ) {
// opening dict
DictLevel + + ;
if ( DictLevel = = 2 ) {
// kext start
InfoPlistStart = DictPtr - 1 ;
}
} else if ( DictPtr [ - 2 ] = = ' < ' & & DictPtr [ - 1 ] = = ' / ' ) {
// closing dict
if ( DictLevel = = 2 & & InfoPlistStart ! = NULL ) {
// kext end
InfoPlistEnd = DictPtr + 5 /* "dict>" */ ;
// terminate Info.plist with 0
SavedValue = * InfoPlistEnd ;
* InfoPlistEnd = ' \0 ' ;
// get kext address from _PrelinkExecutableSourceAddr
// truncate to 32 bit to get physical addr
KextAddr = ( UINT32 ) GetPlistHexValue ( InfoPlistStart , kPrelinkExecutableSourceKey , WholePlist ) ;
// KextAddr is always relative to 0x200000
// and if KernelSlide is != 0 then KextAddr must be adjusted
KextAddr + = KernelSlide ;
// and adjust for AptioFixDrv's KernelRelocBase
KextAddr + = ( UINT32 ) KernelRelocBase ;
KextSize = ( UINT32 ) GetPlistHexValue ( InfoPlistStart , kPrelinkExecutableSizeKey , WholePlist ) ;
/*if (DbgCount < 3
| | DbgCount = = 100 | | DbgCount = = 101 | | DbgCount = = 102
) {
2020-04-17 15:14:24 +02:00
DBG ( L " \n \n Kext: St = %hhX, Size = %hhX \n " , KextAddr , KextSize ) ;
2020-03-25 19:32:44 +01:00
DBG ( L " Info: St = %p, End = %p \n %s \n " , InfoPlistStart , InfoPlistEnd , InfoPlistStart ) ;
2019-09-03 11:58:42 +02:00
gBS - > Stall ( 20000000 ) ;
}
*/
// patch it
PatchKext (
( UINT8 * ) ( UINTN ) KextAddr ,
KextSize ,
InfoPlistStart ,
2020-05-01 18:26:28 +02:00
( UINT32 ) ( InfoPlistEnd - InfoPlistStart )
2019-09-03 11:58:42 +02:00
) ;
// return saved char
* InfoPlistEnd = SavedValue ;
//DbgCount++;
}
DictLevel - - ;
}
DictPtr + = 5 ;
}
}
//
// Iterates over kexts loaded by booter
// and calls PatchKext() for each.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : PatchLoadedKexts ( )
2019-09-03 11:58:42 +02:00
{
DTEntry MMEntry ;
_BooterKextFileInfo * KextFileInfo ;
CHAR8 * PropName ;
_DeviceTreeBuffer * PropEntry ;
CHAR8 SavedValue ;
CHAR8 * InfoPlist ;
2019-12-18 19:41:07 +01:00
OpaqueDTPropertyIterator OPropIter ;
2019-09-03 11:58:42 +02:00
DTPropertyIterator PropIter = & OPropIter ;
//UINTN DbgCount = 0;
2020-05-03 19:34:46 +02:00
DBG ( " \n PatchLoadedKexts ... dtRoot = %llx \n " , ( UINTN ) dtRoot ) ;
2019-09-03 11:58:42 +02:00
2019-12-18 18:34:26 +01:00
if ( ! dtRoot | | ! dtLength ) {
2019-09-03 11:58:42 +02:00
return ;
}
2019-12-18 18:34:26 +01:00
DTInit ( dtRoot , dtLength ) ;
2019-09-03 11:58:42 +02:00
2019-12-18 18:34:26 +01:00
if ( ! EFI_ERROR ( DTLookupEntry ( NULL , " /chosen/memory-map " , & MMEntry ) ) ) {
if ( ! EFI_ERROR ( DTCreatePropertyIterator ( MMEntry , PropIter ) ) ) {
while ( ! EFI_ERROR ( DTIterateProperties ( PropIter , & PropName ) ) ) {
2020-03-25 19:32:44 +01:00
//DBG(L"Prop: %s\n", PropName);
2019-09-03 11:58:42 +02:00
if ( AsciiStrStr ( PropName , " Driver- " ) ) {
// PropEntry _DeviceTreeBuffer is the value of Driver-XXXXXX property
2019-12-18 19:41:07 +01:00
PropEntry = ( _DeviceTreeBuffer * ) ( ( ( UINT8 * ) PropIter - > CurrentProperty ) + sizeof ( DeviceTreeNodeProperty ) ) ;
2020-04-17 15:14:24 +02:00
//if (DbgCount < 3) DBG(L"%s: paddr = %hhX, length = %hhX\n", PropName, PropEntry->paddr, PropEntry->length);
2019-09-03 11:58:42 +02:00
// PropEntry->paddr points to _BooterKextFileInfo
KextFileInfo = ( _BooterKextFileInfo * ) ( UINTN ) PropEntry - > paddr ;
// Info.plist should be terminated with 0, but will also do it just in case
InfoPlist = ( CHAR8 * ) ( UINTN ) KextFileInfo - > infoDictPhysAddr ;
SavedValue = InfoPlist [ KextFileInfo - > infoDictLength ] ;
InfoPlist [ KextFileInfo - > infoDictLength ] = ' \0 ' ;
PatchKext (
( UINT8 * ) ( UINTN ) KextFileInfo - > executablePhysAddr ,
KextFileInfo - > executableLength ,
InfoPlist ,
2020-05-01 18:26:28 +02:00
KextFileInfo - > infoDictLength
2019-09-03 11:58:42 +02:00
) ;
InfoPlist [ KextFileInfo - > infoDictLength ] = SavedValue ;
}
//if(AsciiStrStr(PropName,"DriversPackage-")!=0)
//{
2020-03-25 19:32:44 +01:00
// DBG(L"Found %s\n", PropName);
2019-09-03 11:58:42 +02:00
// break;
//}
}
}
}
}
//
// Entry for all kext patches.
// Will iterate through kext in prelinked kernel (kernelcache)
// or DevTree (drivers boot) and do patches.
//
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : KextPatcherStart ( )
2019-09-03 11:58:42 +02:00
{
if ( isKernelcache ) {
2020-05-01 18:26:28 +02:00
DBG_RT ( " Patching kernelcache ... \n " ) ;
Stall ( 2000000 ) ;
PatchPrelinkedKexts ( ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-05-01 18:26:28 +02:00
DBG_RT ( " Patching loaded kexts ... \n " ) ;
Stall ( 2000000 ) ;
PatchLoadedKexts ( ) ;
2019-09-03 11:58:42 +02:00
}
}