Hopper Disassembler

You may have heard of Hex-Rays IDA Pro. You may even have used their demo version, to run into the 32-bit only code restriction. Not only that, the full version is also way too expensive for us hobby developers.

The good news is that we don’t have to use IDA Pro. I myself use the Hopper Disassembler. This is a very nice and affordable tool. Even the demo version supports 64-bit code, and the full version is only $59.99 so that is pie-nuts compared to IDA Pro. And here is an example of why I like it so much:

function X86PlatformShim::start(IOService*)
{
    r15 = rsi;
    rbx = rdi;
    var_4 = 0x0;
    *(rbx + 0x88) = 0x0;
    *(rbx + 0xd0) = 0x0;
    rax = (*(*0x5058 + 0x5d0))();
    r14 = rax;
    rax = loc_b8c();
    *(rbx + 0x90) = rax;
    if (rax == 0x0) goto loc_ec0;
    goto loc_b98;

loc_ec0:
    r14 = 0x0;
    loc_ed3(0x0, 0x3, 0x0);

loc_ed3:
    rax = r14;
    return rax;

loc_b98:
    rax = loc_ba2(rbx, 0x0);
    *(rbx + 0x98) = rax;
    if (rax == 0x0) goto loc_bda;
    goto loc_bae;

loc_bda:

loc_be1:
    loc_bf1(0x0, 0x3, 0x0);

loc_bf1:
    rax = loc_bfd("CPU_Power_Limits");
    *_gIOPMCPUPowerLimitsKey = rax;
    rax = loc_c10("CPU_Speed_Limit");
    *_gIOPMCPUPowerLimitProcessorSpeedKey = rax;
    rax = loc_c23("CPU_Available_CPUs");
    *_gIOPMCPUPowerLimitProcessorCountKey = rax;
    rax = loc_c36("CPU_Scheduler_Limit");
    *_gIOPMCPUPowerLimitSchedulerTimeKey = rax;
    rax = loc_c49("cpu-plimit-notification");
    *(rbx + 0x108) = rax;
    if (rax == 0x0) goto loc_ec0;
    rax = loc_c65("cpu-idle-plimit-notification");
    *(rbx + 0x110) = rax;
    if (rax == 0x0) goto loc_ec0;
    rax = loc_c81("CPUCStates");
    *(rbx + 0xa0) = rax;
    if (rax == 0x0) goto loc_ec0;
    rax = loc_c9d("CPUOnACPower");
    *(rbx + 0xa8) = rax;
    if (rax == 0x0) goto loc_ec0;
    rax = loc_cbf(r15, **0x5018);
    *(rbx + 0x150) = rax;
    if (rax == 0x0) goto loc_ec0;
    rax = loc_cdd("IOPMrootDomain", 0x0);
    if (rax == 0x0) goto loc_eef;
    goto loc_ce9;

loc_eef:
    r14 = 0x0;
    loc_f02(0x0, 0x3, 0x0);
    goto loc_ed3;

loc_ce9:
    rax = loc_cf8(r15, 0xffffffff);
    rax = loc_d0a(rax, **0x5010);
    *(rbx + 0xc8) = rax;
    (*(*r15 + 0x28))(r15);
    if (*(rbx + 0xc8) == 0x0) goto loc_eb9;
    goto loc_d28;

loc_eb9:
    goto loc_ec0;

loc_d28:
    rax = loc_d36(0xc0045800, &var_4);
    if ((rax == 0x0) && (var_4 == 0x2)) goto loc_d48;
    goto loc_e07;

loc_d48:
    *(int32_t *)(rbx + 0xc4) = 0x1;
    rax = loc_d5e("XCPM");
    *(rbx + 0x88) = rax;
    *(rbx + 0x128) = X86PlatformShim::setPStateEntryInfoXCPM(int, int, int);
    *(rbx + 0x130) = X86PlatformShim::sendPStateTableInfoXCPM(int);
    *(rbx + 0x138) = X86PlatformShim::sendPLimitXCPM(int);
    *(rbx + 0x140) = X86PlatformShim::sendIdlePLimitXCPM(int, int);
    *(rbx + 0x148) = X86PlatformShim::sendPStateStepperTableXCPM(IOService*);
    X86PlatformShim::initializePMInfo(rbx);
    goto loc_ed3;

loc_e07:
    *(int32_t *)(rbx + 0xc4) = 0x0;
    *(rbx + 0x128) = X86PlatformShim::setPStateEntryInfoAICPM(int, int, int);
    *(rbx + 0x130) = X86PlatformShim::sendPStateTableInfoAICPM(int);
    *(rbx + 0x138) = X86PlatformShim::sendPLimitAICPM(int);
    *(rbx + 0x140) = X86PlatformShim::sendIdlePLimitAICPM(int, int);
    *(rbx + 0x148) = X86PlatformShim::sendPStateStepperTableAICPM(IOService*);
    rax = loc_e65("AppleIntelCPUPowerManagement", 0x0);
    if (rax == 0x0) goto loc_ee1;
    goto loc_e6d;

loc_ee1:
    goto loc_eef;

loc_e6d:
    rax = loc_e8f(**0x5068, r15, X86PlatformShim::aicpmNotification(void*, IOService*, IONotifier*), rbx, 0x0, 0x0);
    *(rbx + 0xd0) = rax;
    (*(*r15 + 0x28))(r15);
    if (*(rbx + 0xd0) != 0x0) goto loc_ed3;
    goto loc_eef;

loc_bae:
    rax = (*(**(rbx + 0x90) + 0x140))(*(rbx + 0x90), rax);
    if (rax == 0x0) goto loc_bf1;
    goto loc_be1;
}

This sort of pseudo code makes finding the stuff that we are interested in easy to locate. Let’s take a look at one particular line in the above code snippet:

if ((rax == 0x0) && (var_4 == 0x2)) goto loc_d48;

This selects the desired power management features. In our case we use XCPM but older (like Sandy Bridge) processors will fall back to using the AppleIntelCPUPowerManagement (kext).

Anyway. Next time you are looking for a disassembler… give Hopper Disassembler a go 😉

Advertisement

About lost and altered comments

Someone over at insanelymac.com mentioned that his comment here was removed. Which sucks. And I do remember one comment from him (“I figured it out“) but it appears that someone here may have been removing one or more comments without my approval. Or can comments somehow be retracted perhaps?

Note: I rejected one of his comments simply because there was no solution. It only said: “I figure it out”. Which to me at that time was correct, not knowing about possible other removals.

If you happen to be one of the people that had their comment(s) here removed. As in it was approved and showed up, but then some time later if was removed, then I like to know about it. Please provide as much info as you can share so that we (as in: The WordPress folks) can look into it and hopefully resolve this issue for me as I have no idea what has been going on here lately.

Update:
So far nobody stepped forward, but I did ask WordPress to look into the so called removal of comments. The problem is that they cannot find a single shred of evidence that such event ever happened.

What they did see was an unusual number of attempts where someone tried to login to my account, with a password that I use(d) for a forum, so that looks pretty suspicious.

Again. Anyone who claims to have their comments removed here should step forward, or contact WordPress themselves. I’m sure that nothing will come out of it, but nevertheless. This was all I could do for you.

Will Apple sue Quo Computers?

Yes!

It is quite obviously to me. After all. They released a firmware update via projectosx.com which includes everything to boot OS X, including FakeSMC.kext. They only used projectosx.com to hide their involvement. This is also why ‘TheKing‘ made this post at insanelymac.com, to make it clear that they used tor to hide their trails:
TheKingWhyTorWasUsed
And he said to be one of the developers here:
TheKingQuoDeveloper
Which to me is not so smart. In fact it is a rather stupid action. And since I obtained his address info last year for Sam – you may recall him begging her to remove it from her blog – so can Apple.

So it is not a matter of if but when. I mean come on. Apple fights big guns like Samsung, so who is Quo Computer again? Right. A company using the hard work of other people to make money.

Remember the guy that made that silly USB dongle and used software and other code from the community? They screamed rape and murder, but now we should all be happy and be quiet. Why? Because some silly company, and a hand full of jokers like ‘TheKing‘, want to make money over the backs of hard working people. Not to mention Apple, for their use of OS X, which is why I don’t like companies like Quo Computers. Or people asking for donations.

Note: Hacking OS X is just a hobby for me. Not to earn my money, which I do with real Apple hardware by the way. And what is the fun when everything works out-of-the-box? None for a hacker like me, which is why I keep up with the latest available hardware. Yup. New hardware means a new challenge to get everything going, but after that I lose all interest in it.

Tip: Get yourself a VPN connection for cheap and you will be safe i.e. do not ever visit a forum or use e-mail without a proper VPN network!

Update: The comments are now moderated. We had to do this as a precaution when rampagedev questioned my sisters passing. Which is uncalled for and show you what kind of sick people we have to deal with.

We’re moving again

Just to let you know. I am still here, but I am extremely busy with something else right – we’re moving into a new apartment (south of Barcelona) later this week. Yah! No more barking dogs to keep us awake at night. We also get our own parking spot. Two actually. Having air-conditioning is a plus, but packing and move itself isn’t. Not at these temperatures. And knowing that we will have to move out in like five or six months again, when our new house is ready. Yup. We became property owner today. Ok. Our “bungalow” is nothing more than a large piece of rubble right now. Waiting for the bulldozer to demo it, but at least the plot is ours now. And to get it for a mere 35.000 Euro (includes everything gas/aqua/eléctrico) for this spot was a real bargain. I mean who would reject a view like this:

BayView
The better half of me is so exited that she is calling all of her friends. Me? I just tell you folks the news here and that’s about it. I mean. Who gives a beep. Right?

Update: We’re almost done and the better half of me is unpacking the boxes that we moved so far already. Our bed and other heavy stuff will be moved Friday/Saterday with rent-a-truck (dad and two of his friends are coming over this week end). This means that we won’t have Internet access over the weekend, but I do have some news about Intel CPU power management that I like to share with you. I hope to have time for it some time later this week.

Resolving the DP4 HDMI hang

People with a HDMI (only) display plugged-in at boot time, may run into a system hang with OS X 10.9 DP4 on Haswell systems. We here resolved this with a workaround – modified the PlatformInformation for one of the frame buffers:

03 00 22 0D 00 03 03 03 00 00 00 02 00 00 00 01
00 00 00 00 00 00 00 40 99 14 00 00 99 14 00 00
00 00 00 00 00 00 00 00 03 06 10 00 01 00 00 00
00 00 00 00 01 05 12 00 04 00 00 00 00 00 00 00
02 04 14 00 00 08 00 00 00 00 00 00 FF 00 01 00
01 00 00 00 40 00 00 00 02 00 00 00 01 01 00 00
04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

Apple is probably going to fix the HDMI problems in OS X 10.9 DP5 or with a Graphics Update for DP4 but until then this workaround can be used. Just give it a try and let us know if it works for your setup/motherboard as well. Thanks!

Did you notice what we did with the FB Index? Indeed. We removed the delays and changed the FB Index order to: 3, 1 and 2. This gives us port-number: 7, 5 and 6.

Adding a delay on the last framebuffer (used for HDMI here) changes the port-number from 6 to 0, but that isn’t causing us any problem. At least not here with our setups.

Update-1:

We now have a small bash script (AIFBAzul.sh) to patch platformInfo in AppleIntelFramebufferAzul.kext It is very easy to use and not only enables you to patch/replace platformInfo, but also to undo/restore a patch. All you need for this is to run AIFBAzul.sh with the same AAPL,ig-platform-id (see example below).

1.) Download AIFBAzul.
2.) Rename the file to AIFBAzul.sh (required due to a WordPress limitation).
3.) Change the data of: AAPL,ig-platform-id: 0x0d220003
4.) Open a terminal window and run: sudo ./AIFBAzul.sh 0x0d220003 replace
or: ./AIFBAzul.sh 0x0d220003 patch
5.) reboot

You can run: sudo ./AIFBAzul.sh 0x0d220003 restore
or: sudo ./AIFBAzul.sh 0x0d220003 undo
to restore/undo a patch.

You can run: sudo ./AIFBAzul.sh 0x0d220003 show
to get the platformInfo data:

AAPL,ig-platform-id: 0x0d220003 located @ 317368
————————————————
004d7b8: 0300 220d 0003 0303 0000 0002 0000 0001 ..”………….
004d7c8: 0000 0000 0000 0040 9914 0000 9914 0000 …….@……..
004d7d8: 0000 0000 0000 0000 0105 1200 0004 0000 …………….
004d7e8: 8700 0000 0204 1400 0004 0000 8700 0000 …………….
004d7f8: 0306 1000 0004 0000 1100 0000 ff00 0100 …………….
004d808: 0100 0000 4000 0000 0200 0000 0101 0000 ….@………..
004d818: 0400 0000 0000 0000 0000 0000 0000 0000 …………….
004d828: 0000 0000 0000 0000 ……..

Tip: Booting in single-user mode enables you to restore the platformInfo. For example, when a patch isn’t working for you.

The fun part is that people can now share patched platformInfo data, and all other people will have to do is to replace PATCHED_PLATFORM_INFO (in function initPatchedPlatformInfo) and run AIFBAzul.sh to patch their copy of AppleIntelFramebufferAzul.kext

Update-2:

We changed the script a little and now AIFBAzul v1.2 won’t call otool anymore. Please give v1.2 a try and let us know what you think of it. Feedback is welcome here 😉

AppleIntelFramebufferAzul.kext (part II)

A month or so ago I blogged about the framebuffer data in AppleIntelFramebufferAzul.kext and today I had another look at it. Let us start with the framebuffer data that I used before, as an example, to show you what we have learned so far. The green bytes are known, but the red bytes are not:

00 00 16 0A 00 03 03 03 00 00 00 04 00 00 00 01
00 00 F0 00 00 00 00 40 D9 0A 00 00 D9 0A 00 00
00 00 00 00 00 00 00 00 00 00 10 00 02 00 00 00
30 00 00 00 01 05 12 00 04 00 00 00 04 00 00 00
02 04 12 00 00 08 00 00 82 00 00 00 FF 00 01 00
01 00 00 00 40 00 00 00 04 00 00 00 00 00 07 00
04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

That is not all of them, because I think to have figured out the purpose of a few more bytes. Ok. Here we have the same data, but this time it shows you the new findings:

00 00 16 0A 00 03 03 03 00 00 00 04 00 00 00 01
00 00 F0 00 00 00 00 40 D9 0A 00 00 D9 0A 00 00
00 00 00 00 00 00 00 00 00 00 10 00 02 00 00 00
30 00 00 00 01 05 12 00 04 00 00 00 04 00 00 00
02 04 12 00 00 08 00 00 82 00 00 00 FF 00 01 00
01 00 00 00 40 00 00 00 04 00 00 00 00 00 07 00
04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

Let’s start with the green bytes. This represents the delay (4, 48 and 130) in milliseconds after which the framebuffer should be activated. Used to prioritise a certain framebuffer over another. That is when the orange bytes are the same, like in our example data where the framebuffer with fFrameBufferIndex 01 will be disabled – taken over by the one with 02 because it has a longer delay (higher preference). Meaning that when this framebuffer is used – by injecting AAPL,ig-platform-id: 0x0a160000 – that the DVI connector is switched off and the HDMI connector is switched on. Swapping the values will revert it and changing one of the orange values (12) to 14 will add support for a third display.

Oh and by the way. The byte next to the framebuffer index is NOT the port-number. The fact the port-number 0 and 5 are the same as the connection numbers doesn’t mean a thing. Just look at the next value (04) which should have been 06 when this was in fact representing the port-numbers. You can check the MacBook Air ioreg data and see that I am right (04 is either 06 or 07).

Let’s first have a look at a picture of the Processor Display Architecture. Here it is:
Processor Display Architecture
Visualising the number of pipes (03) framebuffers (03) and DDI ports (03) – this is what I found in the Intel datasheet:

The DDI (Digital Display Interface) ports B,C and D on the processor can be configured to support DP/eDP/HDMI and DVI. For desktop designs, DDI port D can be configured as eDPx4 (4 lanes) in addition to dedicated x2 (2 lanes) port for Intel FDI (Flexible Display Interface) for (analog) VGA.

The Intel Flexible Display Interface (Intel FDI) passes display data from the processor (source) to the PCH (sink) for display through a display interface on the PCH (Platform Controller Hub) and supports up to 2 lanes at 2.7 GT/s fixed frequency (can be configured to 1 or 2 lanes depending on the bandwidth requirements).”

And since VGA is analog, there is no support for HDCP either. Which is why you may see this warning message in: /var/log/system.log and after entering: sudo dmesg

iTunes/Apple Store Content Access Problem. Content playback may be disabled on this computer. You can continue to use the machine, but you should contact an Apple support representative. ErrorCode: 8877652

This warning has long been a mystery (see Google search results) but now we know what it means. Next. A motherboard with three display connectors might give you something like this (debug data):

IG:: start:3260 FB Index 0 is Pipe 65535 type 3 fBootPipe 255
IG:: start:3260 FB Index 1 is Pipe 65535 type 2 fBootPipe 255
IG:: start:3260 FB Index 2 is Pipe 65535 type 1 fBootPipe 255

IG:: MapFBToPort:1721 (FB0: 0xffffff819f133000)
IG:: MapFBToPort:1721 (FB1: 0xffffff819f15c000)
IG:: MapFBToPort:1721 (FB2: 0xffffff819f137000)

IG:: MapFBToPort:1756 Map fb0 -> Port A (fPortType=3)
IG:: MapFBToPort:1756 Map fb1 -> Port B (fPortType=2)
IG:: MapFBToPort:1756 Map fb2 -> Port C (fPortType=1)

IG:: start:3121 [NFB] fPortToFBMap[0] 0xffffff819f133000
IG:: start:3121 [NFB] fPortToFBMap[1] 0xffffff819f15c000
IG:: start:3121 [NFB] fPortToFBMap[2] 0xffffff819f137000

IG:: start:3299 Starting FB 0
IG:: start:3299 Starting FB 1
IG:: start:3299 Starting FB 2

I also found the following errors, which don’t seem to have a negative impact:

IG:: hwGetMemoryLayoutEFI:5405 (fb0: 0xffffff819f133000)
IG:: hwGetMemoryLayoutEFI:5414 [NFB] This FB does not have FBMemoryIndex
IG:: hwGetMemoryLayoutEFI:5430 UpperFence 0 LowerFence 0 baseAddress 0 stride 0 valid 0
IG:: hwGetMemoryLayoutEFI:5433 return 0

IG:: hwGetMemoryLayoutEFI:5405 (fb1: 0xffffff819f15c000)
IG:: hwGetMemoryLayoutEFI:5414 [NFB] This FB does not have FBMemoryIndex
IG:: hwGetMemoryLayoutEFI:5430 UpperFence 0 LowerFence 0 baseAddress 0 stride 0 valid 0
IG:: hwGetMemoryLayoutEFI:5433 return 0

IG:: hwGetMemoryLayoutEFI:5405 (fb2: 0xffffff819f137000)
IG:: hwGetMemoryLayoutEFI:5414 [NFB] This FB does not have FBMemoryIndex
IG:: hwGetMemoryLayoutEFI:5430 UpperFence 0 LowerFence 0 baseAddress 0 stride 0 valid 0
IG:: hwGetMemoryLayoutEFI:5433 return 0

And with a HDMI monitor/TV plugged-in I also see this:

IG:: hwGetBootPanelFitter:1825 fb2 using Panel fitter 1

Port A (eDP) gives me this:

IG:: hwSetPanelPowerConfig:5199 using the default EDP panel timings

I also looked at the debug text strings in the binary and found a couple of interesting ones:

IG:: %s:%d Found boot pipe – fb%d using Port A (BootPipe=%u)\n
IG:: %s:%d Found boot pipe – fb%d using Port B (BootPipe=%u)\n
IG:: %s:%d Found boot pipe – fb%d using Port C (BootPipe=%u)\n
IG:: %s:%d Found boot pipe – fb%d using Port D (BootPipe=%u)\n

So Apple does seem to support four ports, but where the Intel datasheet mentioned Port D for eDP(x4) and VGA support, Apple is using Port A for eDP (x2) instead:

IG:: %s:%d The final Pipe is not A\n
IG:: %s:%d Pipe A is not eDP\n
IG:: %s:%d return (Pipe A is already taken)\n

I have no idea why so this is something we have to figure out.

Edit: Ok. That is because Port D can be configured for x4 mode (4 lanes) but Port A cannot, and Apple isn’t using 4 lanes (yet) so there is no need for using Port D for eDP (x4).

Note: LVDS is to be phased out/replaced by eDP in 2013.

Now have a look at the framebuffer data for the new 2013 Macmini:

03 00 22 0D 00 03 03 03 00 00 00 02 00 00 00 01
00 00 00 00 00 00 00 40 99 14 00 00 99 14 00 00
00 00 00 00 00 00 00 00 01 05 12 00 00 04 00 00
87 00 00 00 02 04 14 00 00 04 00 00 87 00 00 00
03 06 10 00 00 04 00 00 11 00 00 00 FF 00 01 00
01 00 00 00 40 00 00 00 02 00 00 00 01 01 00 00
04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

It supports up to three active monitors (10, 12 and 14). The MacBook Air “only” supports 2. Also note the bytes in blue, representing the fFrameBufferIndex. Here starting at 1 instead of 0 (without eDP support) and the result is that the debug data looks different. Not to mention that fBootPipe will be 1 or 2 due to the greater delay (0x87/135ms) than the one with framebuffer index 3.

Well folks. This has to be it for today. Now it is time for a nice expresso made with a new Solis Barista (wedding gift) and then I will bolt-on a new set of (Spanish) number plates on my Range Rover. Yeah. It has taken me far too long to give Sam’s passing a place… and since my Ranger was a gift from Sam, we should start using it and have fun with it.

Later!