OpenCore-Legacy-Patcher icon indicating copy to clipboard operation
OpenCore-Legacy-Patcher copied to clipboard

AirPlay to Mac with macOS 12.1 and iMac14,x

Open khronokernel opened this issue 3 years ago • 4 comments

With the first beta of macOS 12.1, FeatureUnlock.kext started having patching issues with with regards to enabling AirPlay to Mac support on pre-Skylake machines.

Upon further inspection, we found the issue to be our iMac patch set:

static const uint8_t kSideCarAirPlayiMacOriginal[] = {
    // iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2 iMac14,3 iMac14,4 iMac15,1 iMac16,1 iMac16,2
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x34, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x35, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x36, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x36, 0x2C, 0x32, 0x00,
};

Specifically the early iMac14,x family:

    // iMac14,1 iMac14,2 iMac14,3 iMac14,4
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x34, 0x00,

The cause of this issue is due to the page size limitation of cs_validate_page, as patching data on the edge of the array can result in issues when sections of the dyld grow or shrink.

Work-Arounds

Currently with OCLP 0.3.2, I've added a new build of FeatureUnlock that splits the iMac patch set into 3 portions:

static const uint8_t kSideCarAirPlayiMacPart1Original[] = {
    // iMac13,1 iMac13,2 iMac13,3
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
};

static const uint8_t kSideCarAirPlayiMacPart2Original[] = {
    // iMac14,1 iMac14,2 iMac14,3 iMac14,4
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x34, 0x00,
};

static const uint8_t kSideCarAirPlayiMacPart3Original[] = {
    // iMac15,1 iMac16,1 iMac16,2
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x35, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x36, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x36, 0x2C, 0x32, 0x00,
};

This means that whenever we receive a patch failure for iMac14,x, only that model family is affected. Unfortunately this still means iMac14,x users will not have AirPlay to Mac on 12.1 and newer.

Additionally we have attempted to patch out the model check in AirPlaySupport.framework within the dyld, but have been unsuccessful.

Additional Testing


// Good 12.1 Beta 1 (21C5021h):
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x34, 0x2C,

// Good 12.1 Beta 2 (21C5031d):
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2 iMac14,3
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x33,

// Good 12.1 Beta 3 (21C5039b):
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2 iMac14,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C,

   
// Good 12.1 RC 1:
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2 iMac14,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C,

-----------------------------------------------------------

// Bad 12.1 Beta 1 (21C5021h):
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4E, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32,

// Bad 12.1 Beta 2 (21C5031d):
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2 iMac14,3 
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x33, 0x00,

// Bad 12.1 Beta 3 (21C5039b):
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2 iMac14,3
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x33,

// Bad 12.1 RC 1:
// iMac13,1 iMac13,2 iMac13,3 iMac14,1 iMac14,2 iMac14,3
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x33, 0x2C, 0x33, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x31, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x32, 0x00,
    0x69, 0x4D, 0x61, 0x63, 0x31, 0x34, 0x2C, 0x33,

khronokernel avatar Dec 09 '21 18:12 khronokernel

I can confirm that on iMac14,2 with final 12.1 the Airplay Receiver in System/Sharing is no longer available and I am using oclp 0.3.3. It was working on 12.0 and oclp 0.3.2. Did an OTA update of Monterey to 12.1 and no more Airplay to Mac.

thierryrama avatar Dec 17 '21 03:12 thierryrama

Airplay to AppleTV stutters on MacBook Pro 10,1. All OCLP with all versions of Monterey. All works flawlessly prior to Monterey.

spida007 avatar Jan 30 '22 09:01 spida007

Confirming AirPlay Receiver is missing on iMac14,2 with final MacOS 12.1 and OCLP 0.3.3

marcpbailey avatar Feb 01 '22 15:02 marcpbailey

It may be beneficial to work on the virtual memory level instead of pointers to individual pages. XNU provides a vm_shared_region_vm_map function, which may be used to obtain a vm_map_t for a given shared region.

As, on Big Sur and newer, the shared cache is static and may not change (through Signed & Read-only System Volume and dylib binaries no longer on disk), every process will, in virtually all cases, use the same shared region.

XNU also provides a vm_shared_region_get function, which may be used to obtain a vm_shared_region_t for a given Mach task, for which we can use launchd after obtaining its task with its pid.

After all of this, vm_map_(write|read)_user may be used to scan the shared region for our find and replace. However, my fear is that the shared region pager may prevent this. Specifically, the page-out handler.

flagersgit avatar Feb 09 '22 19:02 flagersgit