The Universal Binary of Crashiness

June 9th, 2008 by Joe Ranieri

What would you say to an application that crashes Finder to the point of being useless? One that merely has to be downloaded, and not even run? I present NukeApp.

For those who don’t feel like experiencing this firsthand, the behavior will vary depending on your Safari download settings. If you’ve set it automatically open downloaded files, Safari will crash and the world will be happy. If you have that option turned off, and you open the zip file up in Finder, Finder will enter a crash loop.

View a movie of the experience.


So, on to the technical details. I’ll start off by saying that this binary has been specifically crafted and is not a valid universal binary — it lies horribly about the number of architectures it contains.

Let’s take a look at the stack trace for where it dies (only showing the top few frames):

_LSAddExecutableFormatInfo
_LSAddBundleExecutableInfo
_LSRegisterDirectoryNode
_LSFindOrRegisterBundleNode
_LSCopyInfoForNode
_LSCopyItemInfoForRefInfo

Aha, it’s LaunchServices giving us the trouble! It looks like Finder is asking it for information about the application and LaunchServices is registering the application in its database. From the looks of it, it’s trying to determine the format of the executable. A closer look at the top function reveals that it’s opening the file and reading it in:

movl        0xfffffb08(%ebp),%eax
leal        0xfffffd34(%ebp),%edx
movl        $0x00000200,0x08(%esp)
movl        %edx,0xfffffafc(%ebp)
movl        %edx,0x04(%esp)
movl        %eax,(%esp)
calll       read$UNIX2003

You’ll notice it’s only reading 512 (0×200) bytes. A bit after this it checks the first long in the data to see which type of executable it is - Mach-O, Mach-O 64-bit, PEF, or a fat binary. If we go down the function a bit more, you’ll notice there’s some strings for each arch type (ppc, ppc64, i386, x86_64). So, what it must be doing is looping through each fat_arch that follows the fat_header. However, since we’re getting crashes, it must not be making sure that it stops reading at the end of its buffer.

Here’s an example that suffers the same issue (ignoring endian issues):

int file = open("/path/to/binary")
char buffer[512];
 
read(buffer, sizeof(buffer), file);
 
fat_header *header = buffer;
fat_arch *archs = buffer + sizeof(fat_header);
 
for(int i = 0; i < header->nfat_archs; i++) {
	// do something with archs[i]
}

This situation comes up in a few diferent places… so how do they handle it?:

  • CFBundle restricts nfat_archs count to the most that fits in the buffer
  • the kernel loader returns error if the archs exceed the size of its buffer (one page size)

I’ll also note that this is not exploitable (it ONLY reads 512 bytes into a 512 byte buffer) and occurs in every version of OS X we could lay our hands on (10.4, 10.5, etc). You cannot inject code into Finder, the Dock, or any other process that crashes in this routine. It’s simply a crash.

We reported this to Apple February 28th (radar 5771210), and have received no response.


Post updated June 9th, with video and slightly better explanation.


Wyoming, Michigan, you’re not alone (cities named after states)

April 9th, 2008 by Jonathan Johnson

I ordered some new sandals online this weekend, and they shipped last night from Wyoming, Michigan. Cities named like this confuse me, and I felt prompted to figure out what other cities are named after states. After doing some quick searches, I couldn’t find a full list, and decided it would be a fun little problem to solve.

So I coded it up really quickly. It turns out there’s a lot — 289 to be exact. Click through to the full post to see the complete list.

This list doesn’t include cities that are named after countries or foreign cities. For example, another common shipping origin seems to be Ontario, CA (California, not Canada). That one confused me even more when I first read it on my tracking information.

Read the rest of this entry »


A Bit of RB Trivia: The Answer

April 4th, 2008 by Joe Ranieri

So, the question I asked last time was this:
Name a situation when the global App object is nil (while executing user code).

The two answers that were submitted and correct are:

  • Charles Yeomans pointed out that properties in modules are destructed after the global App object has been set to nil. Example project.
  • Ben Johnson went the other way around and noticed that the global App object is nil in your Application subclass’ constructor. Example project.

However, neither of these were the answer I was looking for. What happens is that REALbasic does a bit of initialization before setting the global App object. Part of that initialization is setting up the menubar, which entails creating the MenuItems. If you have a subclass of MenuItem in that menubar, REALbasic invokes your constructor, and at that point, the global App object is nil. Example project.

Congratulations to Charles and Ben, both of which will be receiving a free license to CalendarKit.


A Bit of RB Trivia

March 31st, 2008 by Joe Ranieri

There’s a free license to CalendarKit 2 to the first person who can answer this question:

Name a situation when the global App object is nil (while executing user code).

* Offer not applicable to Norman Palardy or past or present REAL Software employees.

Update: We have posted the answers.


Demangling C++ Names

March 26th, 2008 by Joe Ranieri

RuntimeException.stack is one of the most useful things to be added to REALbasic. However, we can make it a bit better by demangling any C++ function names that might be in the stack trace.

Function CPPDemangle(name as string) As string
  //! Demangles a C++ function name. Returns an empty string on failure.
  //! Only works on Mac OS X.
 
  #if targetMacOS
      declare function __cxa_demangle lib "/usr/lib/libstdc++.6.dylib" ( name as CString, _
      outBuffer as ptr, outLength as ptr, byref outState as integer ) as CString
    declare sub free lib "System" ( value as CString )
    const kStateSuccess = 0
 
    dim state as integer
    dim demangledString as CString = __cxa_demangle( name, nil, nil, state )
 
    if state = kStateSuccess then
      // create our RB string, then free the string demangle gave us
      dim result as string = demangledString
      free( demangledString )
 
      return result
    end if
  #endif
End Function

Then you can apply this function to the exception’s stack like so:

Function GetErrorStack(err as RuntimeException) As string()
  //! Gets the stack trace for our exception. This differs from
 //! RuntimeException.stack in that it demangles C++ names.
 
  // this can crash in some cases, giving us a completely useless crash log
  // <rb-feedback://keeqghwg>, hopefully this will be fixed someday...
  dim stack() as string = err.stack
  dim cleanedStack() as string
 
  // the order of RB's "for each" isn't defined <rb-feedback://hdcdbgfi>, so we have
  // to use a normal loop
  for i as integer = 0 to stack.ubound
    dim name as string = stack( i )
    dim demangledName as string = cppDemangle( name )
 
    if demangledName <> "" then
      cleanedStack.append( demangledName )
    else
      cleanedStack.append( name )
    end if
  next
 
  return cleanedStack
End Function

So, instead of seeing “__ZN14RuntimeListbox7GetTextE15getTextSelectorll” in an exception trace, you will see “RuntimeListbox::GetText(getTextSelector, long, long)“. Much, much easier on the eyes. :)


Review of Vista SP 1

March 19th, 2008 by Ryan Govostes

The Internets are abuzz with the news that Microsoft has finally released the first service pack to its widely successful Windows Vista, just one year (plus change) after it first hit retail store shelves.

As a user of Windows Vista Ultimate, I watched the service pack through its beta period with interest. As I’ve mentioned before, Windows and I don’t always see eye-to-eye, so I decided it best to refrain from installing an unstable, pre-release quality operating system on my production machine — a MacBook Pro.

So, I grabbed the Service Pack 1 updater from Microsoft. Weighing in at over 400 MB, the download took roughly an hour to complete. I giddily started the installation at a quarter past 11 PM; after a few reboots during the install process, I was greeted with a fresh view of Windows:

It isn’t often that a 255 by 139 pixel screenshot conveys so many layers of information. Your eye might first be drawn to the third line of text, suggesting that I have pirated Windows. Not so — in fact, my cell phone shows that I placed a 6 minute, 17 second call to Microsoft’s activation center at 8:50 PM, when I activated Windows for the nth time. The update seems to have deactivated my install; I haven’t tried to activate for the (n + 1)th time to see if it will work.

Second, you might notice that the time is 3:06 AM. That’s right — it took four hours to get me back into Windows. Consider that a fresh Windows Vista install takes around 45 minutes (if I remember correctly); OS X takes around 20. Never mind why I’m up at 3 AM on a school night, four hours is a ridiculous amount of time for a system update.

Third, the well-informed reader will note that the build number in the screenshot, 6000, does not match the build number of Windows Vista SP 1, which is 6001. That’s right. After four excruciating hours, the install failed — with no particularly informative error message. I can’t find the exact error number in my Windows logs, but there are thousands of entries at 3:01:37, all reading

Windows Servicing failed to complete the process of setting package
Package_82_for_KB936330~31bf3856ad364e35~x86~~6.0.1.18000 () into Staged(Staged) state

Finally, we note that the screenshot has a hideous red outline. I couldn’t figure out how the equivalent of print screen on my MacBook Pro keyboard, so I used the “Snipping Tool.”


Not sure of the point of allowing signups then…

March 14th, 2008 by Jonathan Johnson

I received this email a few minutes ago:

Dear Registered iPhone Developer,

Thank you for expressing interest in the iPhone Developer Program. We have received your enrollment request. As this time, the iPhone Developer Program is available to a limited number of developers and we plan to expand during the beta period. We will contact you again regarding your enrollment status at the appropriate time.

It seems to me if they were only opening it up to select people, they should have held off on the signup form until they were actually ready for people to sign up. I guess they have to wait to get our $99.

Update:
It sounds like it was either first-come or random. I guess we fail for now.


Another CKFrameworks Teaser

March 9th, 2008 by Joe Ranieri

I spent a bit of time this weekend working on CKFrameworks, so I figured I’d give another teaser. This time I’ll show off the CFType support…

// load our bundle
dim myFile as FolderItem = desktopFolder.child( "test.ape" )
dim bundle as CFTypeRef = CKFrameworks.CFBundleCreate( myFile )
 
// do some random stuff with it
bundle.loadExecutable()
msgbox( bundle.identifier )

Or perhaps you want to get time zone information:

dim timezone as CFTypeRef = CKFrameworks.CFTimeZoneCreateWithName( "EST", true )
msgbox( timezone.name )

As you can see, this is all pure magic. I’m hoping to have an alpha to show at REAL World, so be there or miss out.


Legally Insane

March 8th, 2008 by Joe Ranieri

You probably all are aware that Apple released the iPhone SDK a couple of days ago.

We’ve played around with it and definitely intend on developing for it. Ryan and I are getting iPod Touches, and Jon already has his iPhone. :)

Sadly, we can’t say too much about the SDK itself, because the whole thing is under NDA. That’s right, even though anyone can download it and use it, nobody is allowed to talk about it.

Oh well, lawyers are such silly things.


REAL World 2008 Agenda Calendar

March 8th, 2008 by Jonathan Johnson

In addition to Norman’s REAL World 2008 Track Calendar, I’ve created an iCal file for the conference agenda itself, excluding the session blocks. Combining his calendars with mine, you can now have the entire REAL World 2008 schedule in iCal. More importantly, it allows me to have everything on my iPhone :)

Subscribe

Download

Also, anyone who’s interested in meeting up with me and discussing any of our products, seek me out on Tuesday night, Wednesday, or Thursday. I’m also giving a talk on Team Development at 1:00 on Wednesday, so be sure to come if that sort of thing interests you.