How to replace boot.efi with mine

El Capitan now runs on unsupported hardware, but that was only step one. We have a few more hurdles to take. Let’s start with the installation process. Take a look at this snippet from ia.log:

Extracting boot files from /Volumes/OS X Install ESD/BaseSystem.dmg
Extracting Boot Bits from Inner DMG:
Copied prelinkedkernel
Copied Boot.efi
Copied PlatformSupport.plist
Ejecting disk images
Generating the com.apple.Boot.plist file
com.apple.Boot.plist: {
	    "Kernel Cache" = "/.IABootFiles/prelinkedkernel";
	    "Kernel Flags" = "container-dmg=file:///Applications/Install%20OS%20X%2010.11.1.app/Contents/SharedSupport/InstallESD.dmg root-dmg=file:///BaseSystem.dmg";
	}
Done generating the com.apple.Boot.plist file
Blessing /Volumes/MacintoshHD -- /Volumes/MacintoshHD/.IABootFiles

After which the InstallAssistantTool takes over:

Blessing Mount Point:/Volumes/MacintoshHD Folder:/Volumes/MacintoshHD/.IABootFiles plist:com.apple.Boot.plist
***************************** Setting Startup Disk *****************************
******           Path: /Volumes/MacintoshHD
******     Boot Plist: /Volumes/MacintoshHD/.IABootFiles/com.apple.Boot.plist
/usr/sbin/bless -setBoot -folder /Volumes/MacintoshHD/.IABootFiles -bootefi /Volumes/MacintoshHD/.IABootFiles/boot.efi -options config="\.IABootFiles\com.apple.Boot" -label OS X Installer
Bless on /Volumes/MacintoshHD succeeded

Note: The boot drive (ElCapitanSSD) had El Capitan 10.11.1 installed on it and the target drive (MacintoshHD) had Yosemite 10.10.5 installed on it.

But if I install El Capitan straight from the Yosemite drive (MacintoshHD) – after downloading it from the AppStore – then bless looks like this:

/usr/sbin/bless -setBoot -folder /OS X Install Data -bootefi /OS X Install Data/boot.efi -options config="\OS X Install Data\com.apple.Boot" -label OS X Installer

The only difference here is the folder name i.e. OS X Install Data instead of .IABootfiles. And after all required files are extracted from the DMG and are saved in the target folder, then your computer will reboot. The firmware will then load/execute boot.efi which will fail, of course… if that isn’t the 32-bit one!

You can setup the initial OS X Install Data directory by entering the following terminal commands:

cd /Applications/Install OS X 10.11 El Capitan.app/Contents/Resources
sudo ./startosinstall --applicationpath "/Applications/Install OS X El Capitan.app" --volume /Volumes/MacintoshHD

This installation phase is called “Boot 1” by Apple and also sets a (visible) NVRAM variable with the name rc_imgsrc_info and the data contains a binary plist with the UUID of the installation target. Other NVRAM variables written by the InstallAssitantTool include:

4d1ede05-38c7-4a6a-9cc6-4bcca8b38c14:IASCurrentInstallPhase
4d1ede05-38c7-4a6a-9cc6-4bcca8b38c14:IASInstallPhaseList
8D63D4FE-BD3C-4AAD-881D-86FD974BC1DF:boot-info-payload

But I have yet to find its content.

Ok. Fine. So how are we going to solve this problem? Well. I was wondering if anyone had tried using a launch daemon. Something my late sister used for FileGuard:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.fileguard.watcher</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Extra/FileGuard/Daemon/daemon</string>
	</array>
	<key>WatchPaths</key>
	<array>
		<string>/.IABootFiles/boot.efi</string>
		<string>/.IABootFiles/PlatformSupport.plist</string>
		<string>/OS X Install Data/boot.efi</string>
		<string>/OS X Install Data/PlatformSupport.plist</string>
		<string>/usr/standalone/i386/boot.efi</string>
		<string>/System /Library/CoreServices/boot.efi</string>
	</array>
	<key>StandardErrorPath</key>
	<string>/var/log/FileGuardDaemon.log</string>
	<key>StandardOutPath</key>
	<string>/var/log/FileGuardDaemon.log</string>
</dict>
</plist>

What this does is actually quite simple. It checks for changes/removal of the files in the above list (see array) and when that happens it triggers the daemon, where we can restore the file(s) that we want to use. This should work for the first two file in the list (array) – so that you don’t have to modify the DMG(?) – but I don’t know if it also works for the other two files. We need to verify this. And if it doesn’t work, then we can boot from the RecoveryHD and replace the files.

Update: The installer extracts bootbase.efi from the DMG and saves it as /.IABootfiles/boot.efi or /OS X Instal Data/boot.efi. This ‘special version’ of boot.efi has System Integrity Protection disabled and that allows Apple’s installer to work. You may lose track of which is which, but you can easily verify the version info. The shortest way is to enter:

grep 'bootbase.efi' boot.efi

That won’t return anything on the ‘normal’ copies of boot.efi. Only the extracted and renamed copies of bootbase.efi includes the name. Another way is to check the “booter-name” property with ioreg.

Note: I also made a similar version of bootbase.efi so that you can replace the one found in the DMG. Just wait for Peter Holbrook to compile it, and Mike to test it 😉

Update: Confirmed to be working by mikeboss!

Advertisements

El Capitan support for unsupported hardware is here!

A little over a month ago I blogged about El Capitan support for macosxbootloader and today, after 80 hours of research and development, I released two versions of boot.efi for El Capitan. One with a black background and a white Apple logo, and another one with a grey background and Apple logo.

You can read more about this project for El Capitan here.

Note: I should have added that using -f (flush caches) is no longer supported, and using it will throw a KP. In short. Please wait for me to add support for it (see development phase 3).

Edit: Great. Mike started a new developer thread over at macrumors.com

Have fun now!

Another one bites the dust…

I found something in the kernel that will likely – with almost 100% certainty – not be released by Apple:
_mac_iokit_check_nvram

int mac_iokit_check_nvram_delete(kauth_cred_t cred, const char *name);
int mac_iokit_check_nvram_get(kauth_cred_t cred, const char *name);
int mac_iokit_check_nvram_set(kauth_cred_t cred, const char *name, io_object_t value);

The last one is called by AppleEFINVRAM to block access to NVRAM for get/set/remove property functions, and the sandbox kext has hooks to it. The sandbox may have the platform profile, but AppleEFINVRAM acts as last defence. The guardian. So how do we bypass this you ask? For now we have three options on hack:

1.) Use FileNVRAM.kext to override the calls to get/set/remove property, and thus it won’t check for it.

2.) Replace AppleEFINVRAM.kext with an older version that does not call to checks. I used the one from 10.9.5 and it worked.

3.) Patch the AppleEFINVRAM.kext binary with:

perl -pi -e 's|\x0F\x85\x40\x01\x00\x00|\x90\x90\x90\x90\x90\x90|' AppleEFINVRAM

What this does is that it NOPs out the JNE instruction. The call to _mac_iokit_check_nvram_set in the kernel, and thus the check won’t be done. That’s all. Nothing more. Meaning that you can run csrutil disable from the command line, without the need to boot into the Recovery HD, and still get:

Successfully disabled System Integrity Protection. Please restart the machine for the changes to take effect.

But running nvram csr-active-config=%77%00%00%00 will fail due to the missing entitlement (com.apple.private.iokit.nvram-csr).

However. The fourth, and best option in my view, is to boot into the Recovery HD and be able to run csrutil disable from there. One problem. On a hack you still need one of the above workarounds, and on unsupported hardware for El Capitan… we need to get csrutil disable going. The problem is that I seem to be the last person willing to help others with running El Capitan on unsupported hardware. Like I did for Yosemite. And things are taking a lot of time. Tons of time… but we already made a lot of progress so hang in guys!!!

Anyway. Sure. Apple may not release all parts of the kernel, but what is the point of having an open source kernel, when almost everything that is interesting… is never released? Think about LZVN, XCPM and now this. Another one bites the dust. Yeah. Someone should kick Apple in the teeth for their lousy open source policy.

Note: I don’t know if csrutil disable works on Clover, but I will add it when I get a confirmation about it.

Edit: I forgot to mention that there a six more routines in the kernel. Look here:

_mac_iokit_check_device
_mac_iokit_check_filter_properties
_mac_iokit_check_get_property
_mac_iokit_check_hid_control
_mac_iokit_check_open
_mac_iokit_check_set_properties

CatalogURL’s

I blogged about changing the CatalogURL back in the days and nowadays websites are no longer shy to mention what you need to do in order to get a Beta or Developer seed without first having to sign up for Apple programs. All you need to do is change the App Store URL – the so called CatalogURL – to one of the following with sudo /usr/sbin/softwareupdate --set-catalog

Developer Program Members

https://swscan.apple.com/content/catalogs/others/index-10.11seed-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz

Beta Program Members

https://swscan.apple.com/content/catalogs/others/index-10.11beta-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz

Regular Updates

https://swscan.apple.com/content/catalogs/others/index-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz

Edit:

You can show/verify the CatalogURL with the following terminal command:

sudo defaults read /Library/Preferences/com.apple.SoftwareUpdate CatalogURL

Et voilà.

xnu-2782.40.9 source code released

This was a bit of a surprise to me, but Apple released the xnu-2782.40.9 source code – among others – used in Yosemite 10.10.5 No idea if this happened before – not that I recall – but a new update of Yosemite may soon be released. Otherwise this is a totally unexpected move from Apple.

Oh and a new version of kext tools (384.30.2) is also available for download. Too bad that this isn’t the latest. Oh well. We can’t have everything at once.

SIP about to change once more?

I blogged about System Integrity Protection here; Apple’s kext signing bypassed… and here; csrutil updated in DP7 and when I released csrstat.c to show CSR/SIP status and I have found a new C string literal in the sandbox daemon – sandboxd – that may be an indication that Apple will extend the SIP configuration with the following setting:

#define CSR_ALLOW_DEVICE_CONFIGURATION	(1 << 7)	// 128

Update: It is already used/checked in function csr_check() in bsd/kern/kern_csr.c (XNU kernel source code) to set csr_allow_all to 1 if it is set.

More importantly. AppleEFINVRAM has two calls to csr_check() with this value. One in AppleEFINVRAM::setProperty(OSSymbol const*, OSObject*) and one in AppleEFINVRAM::removeProperty(OSSymbol const*, bool). There might be more executables that use this value, but at least now we know what it is that blocks nvram settings from being stored. I mean entitlements alone are not enough. We know this because csrutil is in fact entitled to set csr-* properties, but not from all partitions.

I also asked folks in the Clover general and Chameleon threads over at insanelymac.com if they used this value, but nobody replied yet. I presume that they don’t know what this value is used for, and why they should test it. Well. Never mind then.