<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="/xslt/html.xsl"?>
<page 
	title="software - Machodis - a Mach-O annotating disassembler | robert klep"
	description="Machodis - a Mach-O executable annotating disassembler for Mac OS X"
	keywords="macho, mach-o, disassemble, disassembler, executable, ppc, powerpc, i386, x86, intel, apple, mac, mac os x, leopard, tiger"
	>
	<content>

		<paragraph title="Snow Leopard compatibility">
			machodis can, at the moment, only disassemble 32-bit targets (i386 or
			ppc). Hopefully it will gain 64-bit capabilities soon :)
		</paragraph>
		<paragraph title="Machodis - Description">
			<link url="dl/machodis.pl">This Perl-script</link> 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).
		</paragraph>
		<paragraph>
			The annotation consists of:
			<ul>
				<li>resolving functioncalls</li>
				<li>resolving strings</li>
				<li>resolving 4-byte/single- and 8-byte/double-precision floating point numbers</li>
				<li>resolving int-packed string literals</li>
				<li>Objective-C: resolving classes, methods and method signatures; (partial) tracking of method arguments</li>
				<li>C++: demangling of symbols</li>
				<li>detection of anonymous subroutines</li>
			</ul>
		</paragraph>
		<paragraph title="Usage">
			Download the <link url="dl/machodis.pl">script</link>, fire up
			Terminal.app, and issue the following command to disassemble
			<i>/bin/ls</i>:
			<pre>perl ~/Downloads/machodis.pl /bin/ls</pre>
			(assuming the script was downloaded to <i>~/Downloads</i>)
		</paragraph>
		<paragraph title="Examples">
			Here's a piece of annotated Safari output (ppc):
			<pre>
-(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    
			</pre>
			A piece of the <i>show_compile_settings()</i>-function of Leopard's Apache 2 (x86):
<pre>
_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
...
</pre>
			Some C++ (the <i>AuthDHXBase</i> dtor in Leopard's <i>/usr/sbin/AppleFileServer</i>, x86):
<pre>
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     
</pre>
And finally, another piece of <i>/usr/sbin/AppleFileServer</i> showing <code>%eip</code>-transfers (to <code>%ebx</code>) and stringloads:
<pre>
0007edb7     e800000000   calll   0x0007edbc
0007edbc             5b   popl    %ebx
&lt;snip&gt;
0007edd7   8d83f57d0000   leal    0x00007df5(%ebx),%eax    ; 'SNServer'
</pre>
		</paragraph>
		<paragraph title="Prerequisites">
			<quot>Machodis</quot> depends on three external programs: <i>otool</i>,
			<i>c++filt</i> and <i>sed</i>.
		</paragraph>
		<paragraph>
			These should all be present on a default Mac OS X installation (perhaps
			after installing the Developer Tools first).
		</paragraph>
		<paragraph>
			It also depends on the Perl-module <link url="http://search.cpan.org/perldoc?Getopt%3A%3ALong">Getopt::Long</link>, which is part of a default Perl install so should be present on your Mac.
		</paragraph>
		<paragraph title="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.
		</paragraph>
		<paragraph>
			Annotation of method arguments and arguments to objc_msgSend* isn't
			always correct, especially on PPC.
		</paragraph>

	</content>
</page>

