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!

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.

Adding an entitlement check to FileNVRAM.kext

Apple protects the SIP settings and won’t allow you – not even as root – to set or change the csr-active-config and csr-data NVRAM variables. Not without using a certain UUID or first booting into the RecoveryHD. Yup. It simply fails with some error. And using

$ sudo csrutil disable

will also fail with an error, but since FileNVRAM.kext isn’t checking the entitlements… that will let you, and anyone else for that matter, add or change the SIP settings! I personally do not want this. Not even on a hack, and that is why I added the missing entitlement check. Here is what I added:

bool FileNVRAM::setProperty(const OSSymbol *aKey, OSObject *anObject)
{
	// Verify permissions.
	if (IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator) != kIOReturnSuccess)
	{
		// Not priveleged!
		return false;
	}
	
	// Check for SIP configuration variables.
	if ((strncmp("csr-data", aKey->getCStringNoCopy(), 8) == 0) || (strncmp("csr-active-config", aKey->getCStringNoCopy(), 17) == 0))
	{
		// We have a match so first verify the entitlements.
		if (IOUserClient::copyClientEntitlement(current_task(), "com.apple.private.iokit.nvram-csr") == NULL)
		{
			LOG(INFO, "setProperty(%s, (%s) %p) failed (not entitled)\n", aKey->getCStringNoCopy(), anObject->getMetaClass()->getClassName(), anObject);
			// Not entitled!
			return false;
		}
	}

Yeah. Checking entitlements is really that easy. Now nvram barks like it should:

sandboxd[270] ([475]): nvram(475) System Policy: deny nvram-set csr-active-config

Same for csrutil:

sandboxd[270] ([473]): csrutil(473) System Policy: deny nvram-set csr-active-config

Have fun with it!

Apple September Event

I had the pleasure of working with the new iPad Pro – for a brief period of time – and I must say… I was impressed. First. I keep zooming in on my iPad Air 2, but that I think is history now. Yeah I know. I have bad eyes. Anyway. I find the iPad Pro a lot heavier than my iPad Air 2, and it’s not a pleasure to carry around with. My gestimate (lol) is that the next iPad Pro will be lighter. Much lighter I hope.

And why isn’t there a new iPad Air 3? Is that because Apple expect people to purchase a new iPad Air, instead of the iPad Pro? Nah. My guess is that a new iPad Air, one with the same processor, would have been even faster than the iPad Pro, and that would have been hard to justify… for something with a price tag starting at $799.

KeyBoard

I find the price of the new keyboard accessory for the iPad Pro a bit too steep. I myself also prefer a Logitech keyboard over the Apple one. Don’t ask me why. I just love Logitech gear.

Apple Pencil

Apple should have called it the Apple Stylus… but that would have been awkward for what Steve Jobs had to say about it; Who needs a stylus. Remember? Well. I do love the new Apple Pencil. Drawing is much more precise and way more fun now, but $99 for this? Come on guys. You don’t have to cash in anymore. $69 is enough IMHO.

Backstage

So you’ve seen pictures of the Apple event huh? Well. I love this one. It’s Tim Cook taken from the back… erm backstage. LOL Yeah. Not too many people can say that they were backstage, so to me this one says it all. Yup. Way more impressive.

TimCookBackstage

AppleTV and tvOS

I don’t know if you were impressed by the new Apple TV/tvOS, but we are going to replace the old AppleTV’s here with the new one… as soon as Apple accepts our order. Being able to play games and install other apps. That’s just great. Even for me as non-gamer. Still a big step forward. Can’t wait to get my hands on one, but there are some things that you should know:

1.) It comes with the A8 Processor. Not the latests (A9) but still. This is a huge improvement over the old A5.
2.) There is no support for Ultra High Definition TV/Video (HDMI port is not 2.0 but 1.4a).
3.) It comes with a 10/100BASE-T Ethernet port. Not a 10/100/1000 one.
4.) There is no optical audio port.
5.) Siri is not available on all EU models.

That is too bad, but I still want one. I guess that Apple knew this, and thus they could get away with it. We just have to wait for the next hardware update. It sucks but hey; this is Apple’s way of telling us what we need. What they think we need.

The best news is probably the fact that it’s no longer another Apple hobby project anymore. That to me is fantastic news, for me as Apple TV owner. Let just wait and see what the future has in mind for us 😉

csrstat.c to show CSR/SIP status

Someone e-mailed me and asked me if it is possible to check the SIP (System Integrity Protection) status from a C program. Yes. That is certainly possible, and I like to shared an example in a new Github repository. One that I added yesterday, and todays update made it even cleaner. Here is a sample of the output:

System Integrity Protection status: enabled (Custom Configuration: 0x00000001).

Configuration:
	Apple Internal: disabled
	Kext Signing Restrictions: disabled
	Filesystem Protections: enabled
	Debugging Restrictions: enabled
	DTrace Restrictions: enabled
	NVRAM Protections: enabled

This is an unsupported configuration, likely to break in the future and leave your machine in an unknown state.

In the same fashion csrutil status does it, but there are four major differences. Did you spot them already?

1.) It will only show “status: disabled” when everything is disabled. Done to stop confusion.

2.) It shows you the actual state e.g. 0x00000001 to assist you, to help you detect the actual value of csr-active-config in NVRAM.

3.) I use: “Kext Signing Restrictions” instead of “Kext Signing” to help you understand what it does.

4.) All changes are displayed in bold to help you spot disabled protections and/or restrictions.

See also csrutil updated in DP7.

Update csrstat v1.5 with Higher Sierra support is now available.

Have fun with it!