User:Uroboro

From iPhone Development Wiki
Revision as of 04:28, 7 October 2015 by Uroboro (talk | contribs) (Dynamic bundle loading: To do: read dyld image loading.)
Jump to: navigation, search

Find me on saurik's IRC server, Twitter, Reddit, Github, StackOverflow or send me an email.

Made UnlockEvents and FlipNC.

If you are looking for notifications within a process, give NotificationExplorer a look.

Some NIC templates here.

And a repository there: uroboro.github.io/repo.

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

Late hooking

UI usage

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

Using callbacks:

static void notificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
	// UI is available, use UIKit here
}
 
%ctor {
	CFNotificationCenterAddObserver(
		CFNotificationCenterGetLocalCenter(), NULL,
		notificationCallback,
		(CFStringRef)UIApplicationDidFinishLaunchingNotification,
		NULL, CFNotificationSuspensionBehaviorCoalesce);
}

Using blocks:

static id observer;
%ctor {
	observer = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification
		object:nil queue:[NSOperationQueue mainQueue]
		usingBlock:^(NSNotification *notification) {
			// UI is available, use UIKit here
		}
	];
}

//if a destructor existed or you don't need to track the notification anymore
%dtor {
	[[NSNotificationCenter defaultCenter] removeObserver:observer];
}

Dynamic bundle loading

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

To do: read this and make this procedure more robust.

Using callbacks:

static void notificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
	if ([((NSDictionary *)userInfo)[NSLoadedClasses] containsObject:@"targetClass"]) {
		// Target class has been loaded
	}
}
 
%ctor {
	CFNotificationCenterAddObserver(
		CFNotificationCenterGetLocalCenter(), NULL,
		notificationCallback,
		(CFStringRef)NSBundleDidLoadNotification,
		NULL, CFNotificationSuspensionBehaviorCoalesce);
}

Using blocks:

static id observer;
%ctor {
	observer = [[NSNotificationCenter defaultCenter] addObserverForName:NSBundleDidLoadNotification
		object:nil queue:[NSOperationQueue mainQueue]
		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 {
	[[NSNotificationCenter defaultCenter] removeObserver:observer];
}

Collaboration and cross-platform compilation

When doing group projects you might find that each contributor has a different platform and possibly a different Theos installation path. To prevent make errors caused by the theos symlink, some may consider blacklisting it from the revision control software (git or svn). It doesn't matter if you do or not, the threat of a missing or incorrect symlink still exists.

Having worked with other developers with an Apple computer, while myself working with my iPhone5,1, I found myself "fighting" this annoyance. After a couple iterations I've made this snippet to fix this "problem":

__SYMLINK := /$(if $(filter $(shell uname -s)-$(shell uname -p),Darwin-arm Darwin-arm64),var,opt)/theos
T := $(shell [[ "$(__SYMLINK)" != `readlink theos` ]] && { rm -f theos; ln -s $(__SYMLINK) theos; })

To use it, place it anywhere before all includes, be it at the top of the Makefile or just before include theos/makefiles/common.mk.

Previous iterations.

Alternatively, add this instead, only in the main Makefile:

T := $(shell sh symlinkfixer.sh)

And save this as symlinkfixer.sh:

find . -name Makefile -exec dirname {} \; | sed 's_$_/theos_' | xargs -I SL bash -c 'platform=$(uname -s)-$(uname -p); _THEOS=/`[[ $platform == Darwin-arm || $platform == Darwin-arm64 ]] && echo var || echo opt`/theos; [[ $(readlink SL) != $_THEOS ]] && { rm -f SL; ln -s $_THEOS SL; }'

Simulator

This should have a page eventually but here are a couple related links for now:

Other Stuff

Similar Wanted Pages:

Inheritance hierarchy‏‎ MIG Subsystems
ApplicationScripting.framework/Inheritance hierarchy‏‎ ApplicationScripting.framework/MIG subsystem‏
AppSupport.framework/Inheritance hierarchy‏‎ AppSupport.framework/MIG subsystem
AudioToolbox.framework/Inheritance hierarchy ‏AudioToolbox.framework/MIG subsystem
AVFoundation.framework/Inheritance hierarchy‏ AVFoundation.framework/MIG subsystem
BackBoardServices.framework/Inheritance hierarchy‏ BackBoardServices.framework/MIG subsystem‏‎
‏BulletinBoard.framework/Inheritance hierarchy‏ ‏BulletinBoard.framework/MIG subsystem
ChatKit.framework/Inheritance hierarchy‏‎ ChatKit.framework/MIG subsystem‏
CoreFoundation.framework/Inheritance hierarchy‏‎ CoreFoundation.framework/MIG subsystem
CoreTelephony.framework/Inheritance hierarchy‏‎ CoreTelephony.framework/MIG subsystem
‏Foundation.frameworkInheritance hierarchy‏‎ ‏Foundation.framework/MIG subsystem
GraphicsServices.framework/Inheritance hierarchy‏‎ GraphicsServices.framework/MIG subsystem
IH boilerplate/Inheritance hierarchy‏‎ IH boilerplate/MIG subsystem‏‎
IOKit.framework/Inheritance hierarchy‏‎ IOKit.framework/MIG subsystem
IOSurface.framework/Inheritance hierarchy ‏IOSurface.framework/MIG subsystem
MapKit.framework/Inheritance hierarchy MapKit.framework/MIG subsystem
Message.framework/Inheritance hierarchy ‏Message.framework/MIG subsystem
QuartzCore.framework/Inheritance hierarchy QuartzCore.framework/MIG subsystem
Preferences.app/Inheritance hierarchy‏ ‏Preferences.app/MIG subsystem
Preferences.framework/Inheritance hierarchy Preferences.framework/MIG subsystem
SpringBoard.app/Inheritance hierarchy SpringBoard.app/MIG subsystem
SpringBoardServices.framework/Inheritance hierarchy‏ SpringBoardServices.framework/MIG subsystem
TelephonyUI.framework/Inheritance hierarchy TelephonyUI.framework/MIG subsystem
UIKit.framework/Inheritance hierarchy UIKit.framework/MIG subsystem
WiFiPicker.servicebundle/Inheritance hierarchy ‏WiFiPicker.servicebundle/MIG subsystem‏

Test Zone

Wondering what looks better:

To "wikitable"...

com.your.tweak.plist
NeXTSTEP style XML style
{
	entry = {
		cell = PSSwitchCell;
		defaults = "com.your.tweak";
		label = "Your Tweak";
		key = enabled;
		default = 1;
		icon = "/Applications/Preferences.app/icon-table@2x.png";
		PostNotification = "com.your.tweak/preferences.changed";
	};
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>entry</key>
	<dict>
		<key>cell</key>
		<string>PSSwitchCell</string>
		<key>defaults</key>
		<string>com.your.tweak</string>
		<key>label</key>
		<string>Your Tweak</string>
		<key>key</key>
		<string>enabled</string>
		<key>default</key>
		<true/>
		<key>icon</key>
		<string>/Applications/Preferences.app/icon-table@2x.png</string>
		<key>PostNotification</key>
		<string>com.your.tweak/preferences.changed</string>
	</dict>
</dict>
</plist>

or not to "wikitable"...

com.your.tweak.plist
NeXTSTEP style XML style
{
	entry = {
		cell = PSSwitchCell;
		defaults = "com.your.tweak";
		label = "Your Tweak";
		key = enabled;
		default = 1;
		icon = "/Applications/Preferences.app/icon-table@2x.png";
		PostNotification = "com.your.tweak/preferences.changed";
	};
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>entry</key>
	<dict>
		<key>cell</key>
		<string>PSSwitchCell</string>
		<key>defaults</key>
		<string>com.your.tweak</string>
		<key>label</key>
		<string>Your Tweak</string>
		<key>key</key>
		<string>enabled</string>
		<key>default</key>
		<true/>
		<key>icon</key>
		<string>/Applications/Preferences.app/icon-table@2x.png</string>
		<key>PostNotification</key>
		<string>com.your.tweak/preferences.changed</string>
	</dict>
</dict>
</plist>

Maybe collapsing?

com.your.tweak.plist