My favorites | Sign in
Project Logo
                
Search
for
Updated Sep 20, 2009 by kennytm
Labels: Phase-Support
class_dump_z  
class-dump-z — Extracting class interface for Objective-C version 2 ABI.

Download: http://networkpx.googlecode.com/files/class-dump-z_0.2-0.tar.gz .

Why a yet another class-dump?

class-dump is a command-line tool to extract Objective-C class interfaces, written by Steve Nygard 17 years ago. The development however paused in 2007 at version 3.1.2, without support for the newest ABI.

This caused the birth of class-dump-x by Holly Lee in 2008. But being a straight modified version of class-dump, it inherited some of the problems, e.g. the ivar offsets are calculated wrongly, properties are not supported, etc.

I, using class-dump-x a lot for reverse engineering, finds that the ivar offset problem is hard to get over with. Having no answers a few months after a bug report, I decided to just fix the problem myself — hence class-dump-z is started.

(While I was creating class-dump-z, the original class-dump development suddenly reactivated at July 1st. The newest version 3.2 does support 2.0 ABI now, but the ivar offset info is even worse than class-dump-x.)

Why you don't want to use class-dump-z

Instead of a generic-purpose class dumper, class-dump-z was written with iPhoneOS development in mind. Therefore, the following features will probably never be implemented:

In general, if you want to dump Mac OS X, you should use the original class-dump. But if you're dumping iPhoneOS binaries, class-dump-z is definitely the better choice.

Features

10x the speed

Time to dump... class-dump-x 3.1.2 class-dump 3.3.1 class-dump-z 0.2-0
UIKit 2.0 (run in Mac OS X) 2.2s 1.8s 0.13s
UIKit 3.1 (run in Mac OS X) 2.9s 2.1s 0.19s
CoreData 3.0 (run in iPhoneOS) 21s - 2.6s

class-dump-z is written from scratch using C++ avoiding using dynamic calls, unlike class-dump and class-dump-x which are written in Objective-C. Removing these unnecessary calls makes class-dump-z near 10 times faster than the precedences.

Portable

Platforms class-dump-x 3.1.2 class-dump 3.3.1 class-dump-z 0.2-0
Mac OS X 10.6
iPhoneOS 3.1
Linux
Windows

Since class-dump-z is written in C++, it is very easy to port to other platforms. Currently Mac OS X 10.6, iPhoneOS 3.1, Linux (x86 and amd64) and Windows (≥XP) are officially supported.

Correct ivar offsets

UIRemoveControlMultiSelectButton 3.1UIMoreListController 3.1
class-dump-x 3.1.2

unsigned int _isHighlighted:1; // 68 = 0x44
unsigned int _isSelected:1;    // 69 = 0x45

UITableView *_table;                         // 92 = 0x5c
BOOL _allowsCustomizing;                     // 96 = 0x60
NSArray *_moreViewControllers;               // 97 = 0x61
UIMoreListCellLayoutManager *_layoutManager; // 101 = 0x65

class-dump 3.3.1

unsigned int _isHighlighted:1;
unsigned int _isSelected:1;

(No offsets shown. Don't know why.)

UITableView *_table;
BOOL _allowsCustomizing;
NSArray *_moreViewControllers;
UIMoreListCellLayoutManager *_layoutManager;

class-dump-z 0.2-0

unsigned _isHighlighted : 1; // 68 = 0x44
unsigned _isSelected : 1;    // 68 = 0x44

UITableView* _table;                         // 92 = 0x5c
BOOL _allowsCustomizing;                     // 96 = 0x60
NSArray* _moreViewControllers;               // 100 = 0x64
UIMoreListCellLayoutManager* _layoutManager; // 104 = 0x68

  • class-dump-? -a -C UIMoreListController UIKit

Generating ivar offsets by accumulation is a tricky business, due to alignments and bitfield packing. It is so tricky that the compiler will generate this info into the file. class-dump-z will read from that part of memory and give the most correct result.

Struct name prettifying

UIScrollView 3.0
class-dump-x 3.1.2 -(id)hitTest:(struct CGPoint)fp8 forEvent:(struct __GSEvent *)fp16;
class-dump 3.3.1 -(id)hitTest:(struct CGPoint)arg1 forEvent:(struct __GSEvent *)arg2;
class-dump-z 0.2-0 -(id)hitTest:(CGPoint)test forEvent:(GSEventRef)event;

class-dump-z will typedef structs and unions to the most presentable name with heuristics.

This feature can be explicitly turned off with the -N switch.

Stable name generation for anonymous structs

UIThreePartImageView 2.0 UIThreePartImageView 3.0
class-dump-x 3.1.2 -(void)setSlices:(CDAnonymousStruct8)fp8; -(void)setSlices:(CDAnonymousStruct10)fp8;
class-dump 3.3.1 -(void)setSlices:(CDStruct_75b8db5d)arg1; -(void)setSlices:(CDStruct_75b8db5d)arg1;
class-dump-z 0.2-0 -(void)setSlices:(XXStruct_UUz0SD)slices; -(void)setSlices:(XXStruct_UUz0SD)slices;

Ever tried to diff a library between two versions? You'll be frustrated by so many differences that are caused by a change of indices in anonymous structs. No more problem in class-dump-z — as long as the struct is having the same members, the generated name will be fixed.

The name is computed by the CRC-32 checksum of the Objective-C type encoding of the struct.

Properties

UIScrollView 3.0
class-dump-x 3.1.2 N/A
class-dump 3.3.1 @property(nonatomic) struct CGPoint contentOffset;
class-dump-z 0.1-11o @property(assign, nonatomic) CGPoint contentOffset;

class-dump-z supports declared properties. Not only that, it supports every property attributes, including the undocumented ones. Moreover, it will hide the extra copy of getters/setters if a property is present.

Propertization

Some libraries are written before the dot syntax was introduced or by some dot-syntax-haters, so you'll see a long list of getters/setters like

-(void)setTitle:(id)title;
-(id)title;
-(void)setSubtitle:(id)subtitle;
-(id)subtitle;
...

I found it pretty annoying. In class-dump-z you can supply the -p switch to automatically convert them into

@property(retain) id title;
@property(retain) id subtitle;
...

Hide inherited and delegate methods

@interface UITableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
	int _tableViewStyle;
	id _keyboardSupport;
}
@property(retain, nonatomic) UITableView* tableView;
// inherited: -(id)init;
-(id)initWithStyle:(int)style;
// inherited: -(void)dealloc;
-(id)existingTableView;
// declared property getter: -(id)tableView;
// declared property setter: -(void)setTableView:(id)view;
// inherited: -(void)loadView;
// inherited: -(void)viewWillAppear:(BOOL)view;
// inherited: -(void)viewWillDisappear:(BOOL)view;
// inherited: -(void)viewDidAppear:(BOOL)view;
-(void)setEditing:(BOOL)editing animated:(BOOL)animated;
-(void)_adjustTableForKeyboardInfo:(id)keyboardInfo;
// in a protocol: -(int)tableView:(id)view numberOfRowsInSection:(int)section;
// in a protocol: -(id)tableView:(id)view cellForRowAtIndexPath:(id)indexPath;
// in a protocol: -(void)tableView:(id)view willBeginEditingRowAtIndexPath:(id)indexPath;
// in a protocol: -(void)tableView:(id)view didEndEditingRowAtIndexPath:(id)indexPath;
@end

Method overloading in subclass is very common in OO design, but such information is useless when generating headers. Yet, by default a class dumper wouldn't know if an implementation is overloaded or a new method. If it's not useful, why not hide them? class-dump-z does that.

Another class of useless information are those being implemented to adopt a protocol. class-dump-z can also filter them out.

If you are running class-dump-z outside of the iPhoneOS, or you haven't installed the SDK, you have to tell class-dump-z where can the libraries be found by the -y switch. If you using using firmware 3.1, because all framework binaries are removed, hiding inherited methods from external frameworks won't work properly.

Readable argument names

UIImage(UIImageDeprecated) 3.0
class-dump-x 3.1.2 -(void)draw9PartImageWithSliceRects:(CDAnonymousStruct13)fp8 inRect:(struct CGRect)fp152;
class-dump 3.3.1 -(void)draw9PartImageWithSliceRects:(CDStruct_c8cd2c5d)arg1 inRect:(struct CGRect)arg2;
class-dump-z 0.2-0 -(void)draw9PartImageWithSliceRects:(XXStruct_4cr1oD)sliceRects inRect:(CGRect)rect;

No more meaningless fpXX. class-dump-z will give a suitable name to each argument using Apple's coding style guide.

Correct header generation

WebThreadSafeUndoManager 3.1
class-dump-x 3.1.2 #import "NSUndoManager.h"
class-dump 3.3.1 #import "NSUndoManager.h"
class-dump-z 0.2-0 #import <Foundation/NSUndoManager.h>

The headers generated by -H are not immediately usable because the imports usually points to non-existing .h files. There is even a page dedicated to fixing this problem.

class-dump-z now will see which library the external class comes from, and tries to make up a better .h file location to import.

Even with this change, headers generated by class-dump-z is generally not immediately usable either. This is usually because of name clash with Foundation and CoreFoundation objects. Most of the cases supplying the -X NS,CF flag to filter them out is enough to fix it.

Miscellaneous features

What's missing

There are some features I don't find them immediately useful, so they are not supported yet.

Sort by inheritance (-I flag), Recursive dumping (-r)

These are not easy to implement and I find them not so useful so I left them out.


Comment by k...@skomski.com, Aug 26, 2009

Great tool. Thanks for your work!

Skomski

Comment by dsnedecor, Oct 12, 2009

I love it!

Comment by francois.guilleme, Nov 15, 2009

Hi kenny I get garbage for a llot of methods in ChatKit?. example:

@interface mSMSSendButtonView : XXUnknownSuperclass {
}
-(BOOL)Îúíþ;
-(void)Îúíþ;
-(float)Îúíþ;
@end

@interface CKSimpleBalloonView : CKBalloonView {
	NSString* _text;
}
+(float)minimumBubbleHeight;
+(float)heightForText:(id)text width:(float)width includeBuffers:(BOOL)buffers;
+(BOOL)showsSubject;
-(id)Îúíþ;
-(id)Îúíþ;
-(void)Îúíþ;
-(void)setMessagePart:(id)part;
-(void)setComposition:(id)composition;
-(void)Îúíþ;
-(void)Îúíþ;
-(void)Îúíþ;
-(CGRect)subjectBounds;
-(CGRect)textBounds;
-(void)Îúíþ;
@end

are you awareof it?


Sign in to add a comment
Hosted by Google Code