Skip to content

The fakeEFI iMessage workaround

Piker-Alpha edited this page Jan 19, 2013 · 39 revisions

I received an e-mail from someone a few weeks ago, asking for my help with iMessage login/registration problems. I thought that my iMessage was working. And it did. Until I logged out. Now I had to take a look. Hey. Sometimes I use a hack for fun, and when I do, then I want my messages to come through in a timely fashion.

Also. They told him, very recently, that this problem cannot be solved in a non-Clover world. To me that is a misunderstanding. To say the least. Soon you'll find patched boot loaders that are non-EFI based. So whatever they tell you, that Clover is great and all that, it can be done with a fakeEFI. Maybe not as nice as in the Clover world, but it works. Which is all I care about.

Note: We are secretively working on a groundbreaking and totally awesome RevoUEFI in the same style as our current work. Ultra small, simple and lightning fast. What else is new ;)

You may have missed it, but Sam blogged about why iCloud/iMessage is broken with a self compiled mach_kernel and when you add a boot uuid to com.apple.Boot.plist. This long before anyone knew about it. Not only that. She also figured out how to add a workaround to solve the iCloud/iMessage login/registration problems. Like she did when she introduced people over at insanelymac.com to chosen/boot-uuid. Which is also required for iMessage. Remember? But this time around she had a reason to be quiet about it as not much later... Sam died. A terrible tragic. Not just for us as a family, but for the whole community.

Now. I was made aware of the fact that other people in the community. Like minded people. Worked on this as well. Sure. No problem. That happens more often than one would think so I hereby like to acknowledge their hard work. And to be honest. I have to simply because I would not have found Sam's work if it wasn't for these strings:

4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM
4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB

That got me started. Anyway. They did their thing and Sam. Well. Sam did her part. Be it months earlier. The only thing that counts for me is that I did not break the rules. I did not reverse the Apple code and made it public. Luckily. That was someone else.

Ok. So now we have this sorted. Lets talk about the underlaying problem. Which is that Apple's mach_kernel includes undocumented code, that Apple isn't sharing with us. This may change over time, but this is the current state of affairs. I won't go into the why or what here. I'll leave that up to your own imagination.

Sam's original idea was to patch the mach_kernel with help of a script, as a Proof Of Concept. This script basically locates "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14" in the mach_kernel and replaces it with "NVRAM". Then it locates a certain string ("/options") and replaces it with "RevoEFI". The next step was to implement a kernel patcher. Which we did recently.

My work here is limited. I only have to polish it a little and share my sisters findings. But as usual. Things change over time (bit rotten code) and sometimes Sam just didn't had the time and energy to share it with you. That is where I step in. I like to see her work, this Proof Of Concept, spread out to other boot loaders as well. So. As of today, 10 January 2013, which is when I committed RevoBoot/i386/libsaio/efi.c (among others) into our Clang repository, RevoBoot injects two new EFI properties that the patched mach_kernel will search for. So instead of looking for:

4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM
4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB

It will now look for NVRAM:ROM and NVRAM:MLB instead. A simple but clever trick.

The good news is that RevoBoot will patch the kernel on-the-fly. This means that you don't need to do anything. We have included Sam's iMessagePatch script, but that was only a 'Proof Of Concept'. Something that is used to let people try new stuff. It worked very well, but now a day we use our kernel patch routine to add iMessage support.

The next step is to let my modified copy of Sam's nvramStorage daemon add the next two NVRAM variables:

4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM
4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB

Note that we must to do this, because there are certain (private) frameworks reading IODeviceTree/options(GUID):ROM/MLB. A shadow of the IOPower plane. Which is where the kernel saves the generated hashes. It's just not visible.

You can do this manually, or from a script. Here's what you need:

sudo nvram 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM=%01%02%03%04%05%06%07%08%09%0A%0B%NN%NN%NN%NN%NN%NN

The percent sign (%) is used to store data instead of a string. Use your IOPlatformUUID and replace the last bytes (%NN) with your MAC address. Next up is the board serial number, which we get from the SMBIOS from our Mac, and that is stored with:

sudo nvram 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB=%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11

These are examples only. Of course. But you get the picture. Right?

You may run into a dialog saying: Your Apple ID "[email protected]" can't be used to set up iMessage at this time. Click on the Contact Support... button to land here:

http://www.apple.com/support/validation/?code=1234-5678-9012&lang=en-us

I obviously changed the code, so yours will be different. The problem is that it failed to verify (read: to contact one of the Apple servers). What I did to get by this dialog was to change my computer name (under System Preferences -> Sharing) and a new system id. The latter will also change your hardware uuid and thus certain software packages may require you to re-register. No big deal IMHO but just to assure that you are aware of this.

I myself did get the Call Apple Support dialog, and I have seen it many times, and have contacted Apple, but it never worked for me. Not until I changed the system id. Still using the same (board) serial number, same board and model identifiers. Nothing really changed. Except for my MAC address, because now I am using the one from my Mac. You may not need it, but we have been hammering the Apple servers for too long already.

Like I said. We included Sam's iMessagePatch script, as a reference, because this script was written many moons ago. I only changed it a little. And again. You don't need it. Not with the latest version of RevoBoot, but I expect Chameleon/Chimera to implement something similar very soon. After that... it is time to use iMessage as you would do on a real Mac. Without issues and a lot of fun!


targetVolume="/Volumes/Mountain Lion"

TARGET_PATH="${targetVolume}/"

FILENAME="mach_kernel"

TARGET_FILE="${TARGET_PATH}${FILENAME}"

function _fileExists() { if [ -e "$1" ]; then echo 1 # "File exists" else echo 0 # "File does not exist" fi }

function _notAlreadyPatched() { local retValue=0

Check for: 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14

if [[ /usr/bin/grep -pi '\x34\x44\x31\x45\x44\x45\x30\x35\x2D\x33\x38\x43\x37\x2D\x34\x41\x36\x41\x2D\x39\x43\x43\x36\x2D\x34\x42\x43\x43\x41\x38\x42\x33\x38\x43\x31\x34' "$TARGET_FILE" =~ $TARGET_FILE ]]; then local retValue=$((retValue+1)) fi

Check for: /options.%s:%s

if [[ /usr/bin/grep -pi '\x2F\x6F\x70\x74\x69\x6F\x6E\x73\x00\x25\x73\x3A\x25\x73' "$TARGET_FILE" =~ $TARGET_FILE ]]; then local retValue=$((retValue+2)) fi

echo $retValue }

function _patchTargetFile() { if $(_fileExists "${TARGET_FILE}_backup") -eq 0; then echo "Backing up ${TARGET_FILE}..." /usr/bin/sudo /bin/cp "${TARGET_FILE}" "${TARGET_PATH}${FILENAME}_backup" fi

echo "Patching phase 1 of: ${TARGET_FILE}..."

4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14 -> NVRAM

/usr/bin/perl -pi -e 's|\x34\x44\x31\x45\x44\x45\x30\x35\x2D\x33\x38\x43\x37\x2D\x34\x41\x36\x41\x2D\x39\x43\x43\x36\x2D\x34\x42\x43\x43\x41\x38\x42\x33\x38\x43\x31\x34|\x4E\x56\x52\x41\x4D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|g' $TARGET_FILE

echo "Done!" echo "Patching phase 2 of: ${TARGET_FILE}..."

/options -> /RevoEFI

/usr/bin/perl -pi -e 's|\x2F\x6F\x70\x74\x69\x6F\x6E\x73\x00\x25\x73\x3A\x25\x73|\x2f\52\x65\x76\x6F\x45\x46\x49\x00\x25\x73\x3A\x25\x73|g' $TARGET_FILE

echo "Done!" }

function main() { if $(_notAlreadyPatched) -eq 0; then echo "Already patched." else _patchTargetFile fi }

function _isRoot() { if [ $(id -u) != 0 ]; then echo "This script must be run as root" 1>&2 exit 1 fi

echo 1 }

if [ $(_isRoot) ]; then main fi

exit 0