views:

1122

answers:

8

Hi,

What is a good place to learn reverse engineering, specifically as it applies to Mac OS X? Two apps that I admire in terms of this subject:

Hyperspaces – http://thecocoabots.com/hyperspaces/

and

Orbit – http://www.steventroughtonsmith.com/orbit/

Thanks guys.

+13  A: 

You should grab a copy of Mac OS X Internals which is an awesome book about everything that Apple does not tell you. Not only is this great if you are interested in reverse engineering, it will also make you a better OS X programmer in general.

St3fan
MacOSX Internals does not help you for programming tasks. It will not help here where the task is obviously the GUI. I'm pretty disappointed with this book - well kernel driver writers may like it.
Lothar
The book is not about Cocoa programming indeed. However, in my opinion you will create better software if you also understand the non-gui layers on which your GUI lives.
St3fan
OS X internals is a book, like Windows internals, that talks about the guts of the system. It won't teach you coding, but if you're reversing, it'll help you understand how the code functions. Quite simple to understand his recommendation.
Daniel Goldberg
+4  A: 

Apple releases a ton of the foundation of OS X as open source. See here.

In addition, F-Script Anywhere will help a ton with dissecting the Finder and/or any other closed source application.

Martin Gordon
F-Script would have been my answer. It really lets you get inside apps. Of course, that will only work on the Mac.
TechZen
+2  A: 

Use class-dump-x/-z to get the private Objective-C headers for OS X/iPhone OS system frameworks. There are a lot of classes/methods hidden from the public (some rightly so)

rpetrich
+2  A: 

For iPhoneOS specifically, class-dump-z is a great way to dump headers. The only problem, of course, is that you can't actually see what is going on inside of each method. IDA Pro and a few scripts make it possible to see the assembly instructions for these system frameworks. (example picture: http://grab.by/1Vn6).

The most handy IDC scripts are fixobjc2 and dyldinfo. You can find each of these linked from this blog post: http://networkpx.blogspot.com/2010/01/two-ida-pro-5x-scripts-for-iphoneos.html

But, what good is this information if you can't use it? iPhone developer saurik has written something called MobileSubstrate that enables hooking onto any method. http://svn.saurik.com/repos/menes/trunk/mobilesubstrate/

Charybdis
Note that MobileSubstrate is also possible to use on a Mac, and also check out SIMBL!
chpwn
A: 

Others have already mentioned class-dump, which is an excellent tool for retrieving the class definitions from a compiled executable. On a related note, you should also take a look at otx, which is provides very nice (readable), disassembled output.

If you need a way to quickly test snippets of code, use F-Script (mentioned by others), Nu or MacRuby. Of these, I've mainly used Nu. It has the capability to define bridged functions on the fly, and can handle pointers, both of which are pretty handy if you need to call arbitrary C functions.

Since you mentioned being interesting in Spaces and other screen managers, you should also read A brief tutorial on reverse engineering OS X. It's an old article by Rich Wareham (author of the pre-Spaces multi-desktop app: 'Desktop Manager') on how he figured out the call syntax for few private CoreGraphics methods in order to do nice desktop transitions. The source code for Desktop Manager is also available, which might be useful to you.

Brian Chapados
A: 

This site shows how to patch an existing Objective C program: http://www.culater.net/wiki/moin.cgi/CocoaReverseEngineering

Namely posing:

[[B class] poseAsClass:[A class]];

and method swizzling:

 /**
 * Renames the selector for a given method.
 * Searches for a method with _oldSelector and reassigned _newSelector to that
 * implementation.
 * @return NO on an error and the methods were not swizzled
 */
BOOL DTRenameSelector(Class _class, SEL _oldSelector, SEL _newSelector)
{
        Method method = nil;

        // First, look for the methods
        method = class_getInstanceMethod(_class, _oldSelector);
        if (method == nil)
                return NO;

        method->method_name = _newSelector;
        return YES;
}

// *** Example ***


// never implemented, just here to silence a compiler warning
@interface WebInternalImage (PHWebInternalImageSwizzle)
- (void) _webkit_scheduleFrame;
@end

@implementation WebInternalImage (PHWebInternalImage)

+ (void) initialize
{
        DTRenameSelector([self class], @selector(scheduleFrame), @selector (_webkit_scheduleFrame));
        DTRenameSelector([self class], @selector(_ph_scheduleFrame), @selector(scheduleFrame));
}

- (void) _ph_scheduleFrame
{
        // do something crazy...
        ...
        // call the "super" method - this method doesn't exist until runtime
        [self _webkit_scheduleFrame];
}

@end

(code copied from http://www.culater.net/wiki/moin.cgi/CocoaReverseEngineering)

Robert
That doesn't really tell how to patch a program. Like, you must have already patched the program in order to be posing inside of it. Also, class posing is deprecated and doesn't work in the 64-bit runtime afaik.
Chuck
The patching part is explained in the link as making a SIMBL plugin.Didn't realize it was depreciated, so here's a SO link about alternatives to poseAsClass: http://stackoverflow.com/questions/1289757/alternative-to-poseasclass-in-mac-os-x-10-5-and-higher
Robert
A: 

As an addition to the other answers, you are going to want to check out DYLD_INSERT_LIBRARIES to inject your code into a Cocoa program.

chpwn
A: 

You should definitely consider using DTrace. There is an excellent BlackHat presentation on using DTrace for reverse engineering on OS X entitled, "DTRACE: The Reverse Engineer's Unexpected Swiss Army Knife".

You can get a copy and view the video presentation here.

There are also some excellent papers at www.uninformed.org on reverse engineering OS X.

bdmcbri