Robert Klep

Snow Leopard compatibility

machodis can, at the moment, only disassemble 32-bit targets (i386 or ppc). Hopefully it will gain 64-bit capabilities soon :)

Machodis - Description

This Perl-script implements an annotating disassembler for the Mac OS X Mach-O executable file format (universal, non-universal, x86 and/or ppc are supported). It can be used to debug flow-of- execution or reverse-engineering (for instance, potentially malicious code from unknown sources).

The annotation consists of:

  • resolving functioncalls
  • resolving strings
  • resolving 4-byte/single- and 8-byte/double-precision floating point numbers
  • resolving int-packed string literals
  • Objective-C: resolving classes, methods and method signatures; (partial) tracking of method arguments
  • C++: demangling of symbols
  • detection of anonymous subroutines

Usage

Download the script, fire up Terminal.app, and issue the following command to disassemble /bin/ls:

perl ~/Downloads/machodis.pl /bin/ls
(assuming the script was downloaded to ~/Downloads)

Examples

Here's a piece of annotated Safari output (ppc):

-(char)[BrowserParentalControls _isManagedUser]:
00004610    7c0802a6      mfspr  r0,lr
00004614    90010008      stw    r0,0x8(r1)
00004618    9421ff60      stwu   r1,0xff60(r1)
0000461c    480f862d      bl     _NSUserName()         ; @ 0xfcc48
00004620    3c800014      lis    r4,0x14
00004624    3ca00014      lis    r5,0x14
00004628    7c661b78      or     r6,r3,r3
0000462c    3c600015      lis    r3,0x15
00004630    80846e28      lwz    r4,0x6e28(r4)         ; [... stringWithFormat:]
00004634    38a50418      addi   r5,r5,0x418           ; '/Library/Managed Preferences/%@'
00004638    8063340c      lwz    r3,0x340c(r3)         ; [NSString ...]
0000463c    4bfeff03      bla    _objc_msgSend_rtp     ; [NSString stringWithFormat:] @ 0xfffeff00
00004640    3c800014      lis    r4,0x14
00004644    808470ec      lwz    r4,0x70ec(r4)         ; [... fileSystemRepresentation]
00004648    4bfeff03      bla    _objc_msgSend_rtp     ; @0xfffeff00
0000464c    38810038      addi   r4,r1,0x38
00004650    480f8fa9      bl     _stat()               ; @ 0xfd5f8
00004654    382100a0      addi   r1,r1,0xa0
00004658    20030000      subfi  r0,r3,0x0
0000465c    7c601914      adde   r3,r0,r3
00004660    80010008      lwz    r0,0x8(r1)
00004664    7c0803a6      mtspr  lr,r0
00004668    4e800020      blr    
0000466c    60000000      nop    
			
A piece of the show_compile_settings()-function of Leopard's Apache 2 (x86):
_show_compile_settings:
000081fc             55   pushl   %ebp
000081fd           89e5   movl    %esp,%ebp
000081ff             53   pushl   %ebx
00008200         83ec14   subl    $0x14,%esp
00008203     e8fa6d0100   calll   _ap_get_server_description
00008208       89442404   movl    %eax,0x04(%esp)
0000820c     b809d70300   movl    $0x0003d709,%eax         ; 'Server version: %s\n'
00008211         890424   movl    %eax,(%esp)
00008214     e872440400   calll   _printf()                ; 0x0004c68b
00008219     e80497ffff   calll   _ap_get_server_built
0000821e       89442404   movl    %eax,0x04(%esp)
00008222     b81dd70300   movl    $0x0003d71d,%eax         ; 'Server built:   %s\n'
00008227         890424   movl    %eax,(%esp)
0000822a     e85c440400   calll   _printf()                ; 0x0004c68b
...
Some C++ (the AuthDHXBase dtor in Leopard's /usr/sbin/AppleFileServer, x86):
AuthDHXBase::~AuthDHXBase():
0003de10             55   pushl   %ebp
0003de11           89e5   movl    %esp,%ebp
0003de13         8b4508   movl    0x08(%ebp),%eax
0003de16   c70028000b00   movl    $0x000b0028,(%eax)
0003de1c         894508   movl    %eax,0x08(%ebp)
0003de1f             c9   leave   
0003de20     e9dba40800   jmpl    operator delete(void*)() ; 0x000c8300
0003de25                  nop     
And finally, another piece of /usr/sbin/AppleFileServer showing %eip-transfers (to %ebx) and stringloads:
0007edb7     e800000000   calll   0x0007edbc
0007edbc             5b   popl    %ebx
<snip>
0007edd7   8d83f57d0000   leal    0x00007df5(%ebx),%eax    ; 'SNServer'

Prerequisites

«Machodis» depends on three external programs: otool, c++filt and sed.

These should all be present on a default Mac OS X installation (perhaps after installing the Developer Tools first).

It also depends on the Perl-module Getopt::Long, which is part of a default Perl install so should be present on your Mac.

Issues

Resolving symbols in PPC-code is a bit of a hassle and is implemented by keeping track of registervalues (PPC ops are 32-bit, which leaves only 24 bits to encode a symbolreference; the other 8 are stored in a different register and are OR'd together to make up a full 32-bit address) using a very non-failsafe method.

Annotation of method arguments and arguments to objc_msgSend* isn't always correct, especially on PPC.