Mar 28 2014

Making a cross-platform binary executable

iOS applications can run on multiple flavours of the ARM platform (armv7, armv7s, arm64). This is because they contain a fat binary, a file containing multiple binaries, one for each platform. There are plenty of tutorials explaining how to make (static) fat libraries, containing code for both the simulator (x86) and iOS (ARM).

Now, to what extend can we have different codes (as in: very different implementations) in a fat binary? Can we make the code aware of its target platform? And ultimately, would it be possible to make a fat binary executable (not a library), that runs on both iOS and on OSX?

I made Janus, a proof-of-concept of a “multiversal” fat binary.

Awareness of the target platform is simply done by exposing the CURRENT_ARCH Xcode environment variable as a macro definition.

To make the binary cross-platform, like fat libraries, the platform-specific binaries are merged together with lipo.

The resulting app contains a binary for both ARM and x86 code:

$ lipo -info ./Debug-iphoneos/
Architectures in the fat file: ./Debug-iphoneos/ are: x86_64 armv7 armv7s arm64

The app runs on iOS:

And its binary runs on OSX, from the console:

$ ./Debug-iphoneos/
2014-03-27 15:29:31.160 Janus-iOS[73947:507] hello world, I'm an OSX binary running on x86_64

See Janus for all the dirty details.

The next step is to investigate if it would be possible to merge not only the binaries, but the apps.

x86_64 arm fat binary macosx ios
Mar 17 2014

Visiting the Apple campus

2 notes

Mar 14 2014

Making a Xcode plugin

I recently made a Xcode plugin to synchronize code snippets with a git repository. Here’s what I learned.

Xcode supports plugins, but not officially. That means Apple does not provide any documentation. Fortunately, there’s documentation on the internet to figure out how to make one.

A plugin

A Xcode plugin is a bundle with the .xcplugin extension and a few specific settings. The best is to start with this highly recommended Xcode plugin template.

Plugins are installed under the ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins directory.

When Xcode starts, it loads the plugin bundle and calls pluginDidLoad: on your NSPrincipalClass:

+ (void)pluginDidLoad:(NSBundle*)plugin {
	NSLog(@"Xcode plugin did load");

Now let’s see how to add functionality.

Knowing Xcode internals

The first thing is to analyze Xcode, and to know its objects and their behavior.

Xcode is located at /Applications/ Xcode’s architecture is actually… made out of more than 50 plugins! (XCode 5.0.1)
The Xcode plugins (prefixed with IDE) are located under /Applications/

Now, two tools come handy to analyze the binary and plugins: class-dump and a disassembler.

Class-dump outputs the headers (interface, struct definitions, …) from the binary code (executable or library):

class-dump IDECodeSnippetLibrary.ideplugin/Contents/MacOS/IDECodeSnippetLibrary 
//     Generated by class-dump 3.5 (64 bit).
//     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
@interface IDECodeSnippetLibrary : DVTLibraryController
	DVTObservingToken *_kvoSnippetRepositoryToken;
	NSMapTable *_strongSnippetToAssetMap;
	NSArray *_orderedPlatformFamilies;
	BOOL _isAddingUserCodeSnippet;
	NSSet *_lastSnippets;
- (id)codeDetailController:(id)arg1 contentsForAsset:(id)arg2 representedObject:(id)arg3;
- (id)codeDetailController:(id)arg1 languageForAsset:(id)arg2 representedObject:(id)arg3;
- (id)editorViewControllerForAsset:(id)arg1;
- (BOOL)canRemoveAsset:(id)arg1;

The class-dumped header can be included in your project after some cleanup, probably involving some @class or by commenting out a few parts. I do, however, recommend doing it the clean way: making a IDE directory with .h header files only for the classes you are really interested in.

Sometimes you need to know more about the exact behavior of a method and that’s where the disassembler comes into play. Popular disassemblers include IDA pro (5.0 freeware) and the more user-friendly Hopper. I already covered some Intel assembly before and if you know how the Objective-C runtime works, you can read assembly code and figure what a method does.

The most important to understand are the objc_msgSend references:

call       qword [ds:imp___got__objc_msgSend]

Parameters are passed through registers %rdi, %rsi, %rdx, %rcx, %r8, %r9 (in that order) and return value is in %rax.

Adding functionality to Xcode

The second thing to do, after analyzing Xcode, is to add functionality.

To access an object, you can get a singleton from its class method, like NSApplication:

[NSApplication sharedApplication];

You can then access its related objects and go down the object hierarchy, to add your functionality.

Another technique is to modify Xcode objects’ behavior. Unfortunately, you cannot subclass, because Xcode will not know about, nor use, your subclass. You cannot use a category either because it makes original implementations unaccessible. And in both cases, the compiler will complain anyways because it cannot find the binary object, only its class-dumped header.

The solution to this is swizzling. Swizzling consists of changing a method implementation with another:

class_addMethod(__unsafe_unretained Class cls, SEL name, IMP imp, const char *types);
class_replaceMethod(__unsafe_unretained Class cls, SEL name, IMP imp, const char *types);

Sometimes you need to get access to a class. This can be done at runtime, thus fooling the compiler, with NSClassFromString:

IDECodeSnippet *codeSnippet = [[NSClassFromString(@"IDECodeSnippet") alloc] init];

Debugging Xcode plugins

The simplest (but limited and cumbersome) technique is using NSLog. Messages are then forwarded to syslog. You see the messages with the or in a terminal with:

tail -f /var/log/system.log

Another way is to attach lldb to Xcode when it is running.

Distributing plugins

Alcatraz is a package manager for plugins, templates and color schemes for Xcode. Dispite being somewhat buggy, it is a good tool to not only manage your plugins but also to distribute your own.

To distribute your plugin, fork the Alcatraz package list and make a pull request. Hopefully, soon the world will have access to your newly made plugin.

Maintaining your plugin

(Un)fortunately, the fun doesn’t stop here. As I said in the beginning, Apple does not officially support Xcode plugins. This also means that they may break compatibility any time. In practice, we’ve seen plugins being broken mostly at major XCode releases.

I hope this helps to understand how to make a plugin for Xcode. Don’t forget to check the source of ACCodeSnippetRepositoryPlugin for a complete example of plugin.

2 notes

xcode plugin
Mar 07 2014

C Pre-processor macro Stringification

Convert a macro argument into a string constant:

source: GCC Stringification

macro preprocessor
Mar 06 2014


Let me explain some basics on assembly. Note that the following is about x86 Mac assembly; it differs ARM assembly used for iOS app.

On the x86 family, assembly can access both the processor registers and memory. 32 bits general registers are rax, rbx, rcx, rdx; index registers are rdi (destination) and rsi (source); and pointer registers are rbp (base) and rsp (stack). The registers can also be addressed as 8 bit (ah and al), 16 bit (ax) and 64 bits (eax — x86_64). There are also flags like CF (carry) and ZF (zero) to hold the state of the processor.

The function is declared with a label


The function usually starts with a standard entry sequence, setting up a new stack frame:

	push       rbp		; save the value of rbp
	mov        rbp, rsp	; rbp now points to the top of the stack
	push       r14 		; saving some variable
	sub        rsp, 0x30	; space allocated on the stack for the local variables

A function call is done with the call opcode. In Objective-C, method calls are done through the runtime's objc_msgSend function. Parameters are passed in the rdi, rsi, rdx, rcx, r8, r9 registers (in that order). In Objective-C, rdi points to the receiver, rsi to the selector, rdx to the first argument, and so on.

	mov        rsi, qword [ds:objc_sel_containsValueForKey_] 	; @selector(containsValueForKey:)
	lea        rdx, qword [ds:cfstring_UIFrame] 			; @"UIFrame"
	mov        rdi, rbx
	call       qword [ds:imp___got__objc_msgSend]

Jump instructions go straight to a memory address. Unlike call, they do not save the program counter. Jump opcodes are usually associated with a test opcode to make a if or a loop statement. Testing a register with itself is a trick to check if the register is equal to zero, like when checking if a pointer is nil.

	test       al, al
	je         0x5831c

Another trick is to xor a register with itself to make it zero

	xor	rax, rax

Note that sometimes, you’ll notice a set of instructions whose net result is noop (no operation — nothing is really achieved). It might be the compiler messing up, or, as some speculate, a form of optimization taking advantage of the pipelining of the processor. I haven’t investigated so I’m not really sure why this is happening. Either case, don’t be surprised if you encounter this.

	mov rdx, rax
	mov rax, rdx

Returning from a function usually happens with a standard exit sequence, removing the stack frame. Return values are passed through rax.

	add        rsp, 0x20		; remove space for local variables 
	pop        rbp			; restore rbp to its old value
	ret				; return to the calling function

This certainly not a comprehensive tutorial on assembly but I hope it helps getting started.

1 note

Mar 04 2014

Reversing Frameworks

A while ago, in a project I inherited, I wanted to get rid of its storyboard. Being able to programmatically create segues would really have helped me. Unfortunately, the UIKit storyboard runtime does not allow that. So I re-implemented the storyboard segue logic and made a library.

Let me explain how we can analyze a framework in order to re-implement it. Frameworks for the the iOS 7.0 simulator are located under

Being the simulator’s frameworks, they are Intel x86 32bits and 64bits binaries.

Now there are different tools to extract information from the binary.


Class-dump comes in many different flavours: the original class-dump (also available on homebrew), class-dump-x, class-dump-z. While they offer minor different level of details and performance, they all output the headers extracted from the binary code (executable or library). Those headers contain the interfaces, protocols, categories, structs, typedefs, and unions.

cd /Applications/
class-dump UIKit.framework/UIKit
//     Generated by class-dump 3.5 (64 bit).
//     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.

#pragma mark Function Pointers and Blocks

typedef void (*CDUnknownFunctionPointerType)(void); // return type and parameters are unknown
typedef void (^CDUnknownBlockType)(void); // return type and parameters are unknown

#pragma mark Named Structures

struct CATransform3D {
	double m11;
	double m12;
	double m13;
	double m14;
	double m21;
	double m22;
	double m23;
	double m24;
	double m31;
	double m32;
	double m33;
	double m34;
	double m41;
	double m42;
	double m43;
	double m44;


#pragma mark Named Unions

union _GLKQuaternion {
	struct {
		union _GLKVector3 v;
		float s;
	} ;
	struct {
		float x;
		float y;
		float z;
		float w;
	} ;
	float q[4];


@interface UIView : UIResponder <_uiscrollnotification uitexteffectsordering nsisvariabledelegate nslayoutitem nsisenginedelegate nscoding uiappearance uiappearancecontainer uidynamicitem>
	CALayer *_layer;
	id _gestureInfo;
	NSMutableArray *_gestureRecognizers;
	NSArray *_subviewCache;
	float _charge;
	long long _tag;
	UIViewController *_viewDelegate;
	NSISEngine *_layoutEngine;
	NSISVariable *_boundsWidthVariable;
	NSISVariable *_boundsHeightVariable;
	NSISVariable *_minXVariable;
	NSISVariable *_minYVariable;
	NSMutableArray *_internalConstraints;
	NSArray *_constraintsExceptingSubviewAutoresizingConstraints;

+ (void)_setShouldEnableUIKitParallaxEffects:(_Bool)arg1;
+ (_Bool)_shouldEnableUIKitDefaultParallaxEffects;
+ (void)_recenterMotionEffects;
+ (_Bool)_motionEffectsEnabled;
+ (_Bool)_motionEffectsSupported;
+ (void)_endSuspendingMotionEffectsForReason:(id)arg1;
+ (void)_beginSuspendingMotionEffectsForReason:(id)arg1;
+ (id)_motionEffectEngine;
+ (Class)layerClass;
+ (_Bool)_preventsAppearanceProxyCustomization;
+ (void)_performCustomizableAppearanceModifications:(CDUnknownBlockType)arg1;
+ (id)appearanceMatchingProperties:(id)arg1 whenContainedIn:(Class)arg2;
+ (id)_appearanceRecorderWhenContainedIn:(Class)arg1;
+ (id)appearanceWhenContainedIn:(Class)arg1;
+ (id)_appearanceWhenContainedIn:(id)arg1;
+ (id)_appearanceRecorder;
+ (id)appearance;
+ (void)throttledFlush;
+ (void)flush;

Private classes are decorated with the visibility attribute set to hidden:

and private methods are usually prefixed with and underscore _ :
 + (_Bool)_motionEffectsEnabled;

If you intend to publish on the app store any code accessing those private methods, your app may be rejected. Per the App store review guidelines (needs login in the ADC):

2.5 Apps that use non-public APIs will be rejected

There are some ways to circumvent Apple’s (static) code check for private APIs, but I really recommend against doing that. Accessing private classes/methods is not only forbidden by Apple’s guidelines, but is also a bad practice.

On the other hand, if you are developing for yourself or if you distribute your binary on the web only (like an mac app or xcode plugin), you should probably be fine. However, be warned those private classes and methods may change any time without any warning from Apple.

You can import the class-dumped headers in your project, probably involving the use of some @class or by commenting out a few parts.


otool, the object file displaying tool, comes with MacOSX. It retrieves different informations from a binary, including Mach headers, load commands, segments, relocation entries and symbols table. It can also disassemble a binary with symbolic operands:

otool -tV UIKit
-[UIView initWithFrame:]:
	pushq   %rbp
	movq    %rsp, %rbp
	pushq   %r14
	pushq   %rbx
	subq    $0x30, %rsp
	movq    %rdi, 0xffffffffffffffe0(%rbp)
	movq    0xabb92d(%rip), %rax
	movq    %rax, 0xffffffffffffffe8(%rbp)
	movq    0xa9561a(%rip), %rsi
	leaq    0xffffffffffffffe0(%rbp), %rdi
	callq   0x68aa72 ## symbol stub for: _objc_msgSendSuper2
	movq    %rax, %rbx
	testq   %rbx, %rbx
	je      0x57f8d
	leaq    0x10(%rbp), %rax

One of the limitations of otool is that does not derefence all adresses, making the assembly code hard to follow.


Hex-rays’ IDA pro is probably the most popular multi-platform assembler and debugger. There are a commercial, evaluation and freeware version. It is a really powerful tool, but unfortunately, its power is tarnished by its lack of user-friendliness. Explaining how to use IDA would require a whole article in itself.


Hopper is another, more user-friendly, multi-platform disassembler, decompiler and debugger. Compared to otool, it as a better support for cross-references (XREFs) when disassembling.

Hopper can also decompile the code but I have found that in practice, it sometimes “misses” some parts and isn’t accurate. I usually only use the decompiler to get a general sense of what a method is doing, then resort to assembly for the exact instructions.

Those are the tools I use for reversing. In a next article, I’ll explain how to read the disassembled code.

reverse engineering
Mar 03 2014

Why mobile web apps are slow

Here is an article I read but apparently forgot to mention when it was released in summer 2013. Why mobile web apps are slow explains how hardware limitations, performance issues with garbage collection, and javascript are keeping html app behind native code.

To be fair, here is also Sencha’s answer: 5 Myths About Mobile Web Performance.

performance html5 native
Mar 01 2014
xcode plugin
Feb 27 2014

Unicode and UTF-8

Here’s a nice video explaining how UTF-8 works and its backwards compatibility with ASCII:

Don’t forget to check Joel’s Spolsky’s excellent article "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets".

Feb 12 2014
Feb 10 2014

Weak Symbol attribute

Make a symbol weak so that it can be replaced by a stronger symbol if one becomes available when linking.

For example, this can be used in a library that defines and uses a MethodSwizzle function, and there is a chance that function might be redefined somewhere else (in the final app or in another library). The function then becomes:

Feb 08 2014
storyboard reverse engineering
Feb 07 2014

x86_64 Assembly references

Following my post on ARM Assembly references, here are references for x86 64 bits (IA-64) assembly.

The most complete reference is Intel 64 and IA-32 Architectures Software Developer’s Manual. Appl’s documentation of the OSX ABI (Function Calling Conventions) points to the System V ABI for AMD64 specifications.

If you don’t want to read the whole document, you can instead refer to x86-64 Instructions and ABI from a CS course at university of Chicago or Wikipedia’s x86 instruction listings.

The most important is to remember the Intel x64 registers are used for:

  • function calling: %rdi, %rsi, %rdx, %rcx, %r8, %r9
  • and return: %rax

asm assembly x86_64 reverse engineering
Page 1 of 11