My favorites | Sign in
Project Home Downloads Wiki Issues Source
READ-ONLY: This project has been archived. For more information see this post.
Search
for
class_dump_z  
class-dump-z — Extracting class interface for Objective-C version 2 ABI.
Phase-Support
Updated Dec 25, 2009 by kennytm@gmail.com

Download:

Usage: class-dump-z [<options>] <filename>

where options are:

  Analysis:
    -p         Convert undeclared getters and setters into properties (propertize).
    -h proto   Hide methods which already appears in an adopted protocol.
    -h super   Hide inherited methods.
    -y <root>  Choose the sysroot. Default to the path of latest iPhoneOS SDK, or /.
    -u <arch>  Choose a specific architecture in a fat binary (e.g. armv6, armv7, etc.)

  Formatting:
    -a         Print ivar offsets
    -A         Print implementation VM addresses.
    -k         Show additional comments.
    -k -k      Show even more comments.
    -R         Show pointer declarations as int *a instead of int* a.
    -N         Keep the raw struct names (e.g. do no replace __CFArray* with CFArrayRef).
    -b         Put a space after the +/- sign (i.e. + (void)... instead of +(void)...).
    -i <file>  Read and update signature hints file.

  Filtering:
    -C <regex> Only display types with (original) name matching the RegExp (in PCRE syntax).
    -f <regex> Only display methods with (original) name matching the RegExp.
    -g         Display exported classes only.
    -X <list>  Ignore all types (except categories) with a prefix in the comma-separated list.
    -h cats    Hide categories.
    -h dogs    Hide protocols.

  Sorting:
    -S         Sort types in alphabetical order.
    -s         Sort methods in alphabetical order.
    -z         Sort methods alphabetically but put class methods and -init... first.

  Output:
    -H         Separate into header files
    -o <dir>   Put header files into this directory instead of current directory.

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:

  • 64-bit support. (Unless there is a 4 GiB RAM iPhone.)
  • Objective-C 1.0 ABI.
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

  • time class-dump-? -a -A UIKit > /dev/null

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-? -C UIScrollView -f hitTest UIKit

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;

  • class-dump-? -C UIThreePartImageView UIKit

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-? -C UIScrollView UIKit

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;

  • class-dump-? -C UIImageDeprecated UIKit

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.

Hints file

When an Objective-C source is compiled, the class name in a method will be stripped, so in the dump you'll get

-(void)touchesBegan:(id)began withEvent:(id)event;

instead of

-(void)touchesBegan:(NSSet*)began withEvent:(UIEvent*)event;

Hints file is created to address this problem. When you pass the -i flag, a tab-delimited file will be created, which contains the type signature e.g.

-[UIGestureRecognizer touchesBegan:withEvent:]	void	id	id

You can edit this file and change to the more precise signature, i.e.

-[UIGestureRecognizer touchesBegan:withEvent:]	void	NSSet*	UIEvent*

then feed the same file with the -i flag. The updated signature will be reflected in the dump.

Miscellaneous features

  • Class attributes, e.g. __attribute__((visibility("hidden"))).
  • Supports obscure type encodings, e.g. the C99 _Complex types, Objective-C class ivars with ≥2 protocols, GC-invisible pointers, etc.
  • Put that star on the left or right, I like int* x more, some people like int *x more. With the -R switch one can switch between the two styles easily.
  • Put a space or not after the +/-. With the -b switch one can choose to use - (void)hello or -(void)hello.

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 mxw...@gmail.com, Jul 13, 2009

This is FANTASTIC!

Much Appreciated. Keep up the good work.

-Max

Comment by karl%sko...@gtempaccount.com, Aug 26, 2009

Great tool. Thanks for your work!

Skomski

Comment by dsnede...@gmail.com, Oct 12, 2009

I love it!

Comment by francois.guilleme@gmail.com, 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?

Comment by d.prat...@gmail.com, Mar 10, 2010

Well done Kenny. I'll definitely prefer class-dummp-z than class-dumm-x or other.

Comment by antonin....@gmail.com, Mar 28, 2010

Great work!

Comment by cc%witel...@gtempaccount.com, Apr 1, 2010

lovely work

Comment by neca...@gmail.com, Jan 16, 2011

Perfect work

Comment by daniel.c...@gmail.com, Jul 1, 2011

Awesome.

Comment by samb...@nd.edu, Sep 16, 2011

Many thanks.

Running under OS X 10.6.8 on 32-bit intel core duo, /System/Library/Frameworks/CoreData?.framework/Versions/Current/CoreData? produces very little output, just the comment that would come at the start, saying Source: (null); whereas class-dump produces reasonable looking and fairly large output. Same also with Foundation. This is with no command line arguments, just the executable class-dump-z and the name of the Mach-O file. With either 0.2-0 or 0.2a, mac_x86. ?? Probably something obvious but I don't see it. I downloaded the source and presumably can figure it out if there's time. Thanks.

Comment by aaron.br...@gmail.com, May 2, 2012

I am also getting the same error on both Windows 7 64-bit, and Mac OS X Lion 10.6.8. I am not sure how to fix this problem. I was simply trying to run "class-dump-z my.app", I also tried it with various command line arguments, but the result it always the same. Any ideas?

Comment by lor...@musixmatch.com, Jun 27, 2012

Here are you a script to automitize the recursive dump with class-dump-z Just change the path of the framework in the var FPATH, to make it more elegant you can pass it as a input parameter

Authors

@loretoparisi @christian_zanin

clear FPATH=/Applications/Xcode45-DP2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/ ROOTFOLDER=iPhoneOS6.0.sdk if -d $ROOTFOLDER

then
rm $ROOTFOLDER
fi mkdir $ROOTFOLDER COUNTEXT="$(ls -l $FPATH | wc -l)" echo "All frameworks are $COUNTEXT"

COUNT=0 for r in $(find $FPATH -maxdepth 1 -type d -exec ls -l "{}" \;| grep '\-rwxr\-xr\-x' | awk '{ print $9 }')

do
FILE=$FPATH$r.framework/$r if -a $FILE
then
echo "Framework is $FILE" let COUNT=COUNT+1 echo "Processing $r..." ./class-dump-z -H -k -k -S -z -o $ROOTFOLDER/$r $FPATH/$r.framework/$r echo "...DONE"
fi
done
echo "Frameworks are $COUNT"

Comment by devayanb...@gmail.com, Aug 19, 2015

Hi I am getting this error in my ipad dyld: Library not loaded: /usr/lib/libpcre.0.dylib

Referenced from: /usr/bin/class-dump-z Reason: image not found
Trace/BPT trap: 5

Powered by Google Project Hosting