DISCLAIMER: All code written in this page is to be considered experimental and untested. The author shall not be held responsible or liable for any undesired consequences, including, but not limited to, data loss, property damage, time travel, the singularity, suffered by you as a result of any error in such code. You also agree that you will not use these code snippets for any purposes prohibited by United States law, including, without limitation, the development, design, manufacture, or production of nuclear, missile, or chemical or biological weapons.

"Interesting" links

Hooking everything

While previously it was possible to provide no filter or an empty one, this is no longer the case, both by Cydia Substrate requiring one and not it being empty. So the solution is based on another requirement that is not very documented: Cydia Substrate will only hook binaries that are linked with Security.framework. The following filter will suffice for this purpose but please reduce the hooking target of your tweak as much as possible.

Late hooking

UI usage

If you need to use UI elements, you have to wait until the application is ready.

Using callbacks

staticvoidnotificationCallback(CFNotificationCenterRefcenter,void*observer,CFStringRefname,constvoid*object,CFDictionaryRefuserInfo){// UI is available, use UIKit here#if BEFORE_IOS_8UIAlertView*alert=[[UIAlertViewalloc]initWithTitle:@"Alert"message:@"This is an alert."delegate:nilcancelButtonTitle:@"I'm ok with this"otherButtonTitles:nil];[alertshow];#elseUIAlertController*alert=[UIAlertControlleralertControllerWithTitle:@"Alert"message:@"This is an alert."preferredStyle:UIAlertControllerStyleAlert];[alertaddAction:[UIAlertActionactionWithTitle:@"I'm ok with this"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction*action){}]];[[UIWindowkeyWindow].rootViewControllerpresentViewController:alertanimated:YEScompletion:^{}];#endif}staticvoid*observer=NULL;%ctor{CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(),&observer,notificationCallback,(CFStringRef)UIApplicationDidFinishLaunchingNotification,NULL,CFNotificationSuspensionBehaviorCoalesce);}// Remove observer upon unloading the dylib%dtor{CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(),&observer,(CFStringRef)UIApplicationDidFinishLaunchingNotification,NULL);}

Using blocks

staticidobserver;%ctor{observer=[[NSNotificationCenterdefaultCenter]addObserverForName:UIApplicationDidFinishLaunchingNotificationobject:nilqueue:[NSOperationQueuemainQueue]usingBlock:^(NSNotification*notification){// UI is available, use UIKit here#if BEFORE_IOS_8UIAlertView*alert=[[UIAlertViewalloc]initWithTitle:@"Alert"message:@"This is an alert."delegate:nilcancelButtonTitle:@"I'm ok with this"otherButtonTitles:nil];[alertshow];#elseUIAlertController*alert=[UIAlertControlleralertControllerWithTitle:@"Alert"message:@"This is an alert."preferredStyle:UIAlertControllerStyleAlert];[alertaddAction:[UIAlertActionactionWithTitle:@"I'm ok with this"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction*action){}]];[[UIWindowkeyWindow].rootViewControllerpresentViewController:alertanimated:YEScompletion:^{}];#endif}];}// Remove observer upon unloading the dylib%dtor{[[NSNotificationCenterdefaultCenter]removeObserver:observer];}

Dynamic bundle loading

Same applies if a class you want to hook is dynamically loaded by a bundle.

Using callbacks

staticvoidnotificationCallback(CFNotificationCenterRefcenter,void*observer,CFStringRefname,constvoid*object,CFDictionaryRefuserInfo){if([((NSDictionary*)userInfo)[NSLoadedClasses]containsObject:@"targetClass"]){// Target class has been loaded}}%ctor{CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(),NULL,notificationCallback,(CFStringRef)NSBundleDidLoadNotification,NULL,CFNotificationSuspensionBehaviorCoalesce);}

Using blocks

staticidobserver;%ctor{observer=[[NSNotificationCenterdefaultCenter]addObserverForName:NSBundleDidLoadNotificationobject:nilqueue:[NSOperationQueuemainQueue]usingBlock:^(NSNotification*notification){if([notification.userInfo[NSLoadedClasses]containsObject:@"targetClass"]){// Target class has been loaded}}];}//if a destructor existed or you don't need to track the notification anymore%dtor{[[NSNotificationCenterdefaultCenter]removeObserver:observer];}