[How To] Hook SpringBoard
Sunday, May 30, 2010 4:53 AM
Basic Concept
Ok, hooking into SpringBoard is actually very easy. What you do is have SpringBoard open a dynamic library that you create, which calls the initializing function within your dylib(specified when linking). From here you take whatever Class from SpringBoard you wish to override a method from that is in memory, and you "redirect" the method to another that you create.
YES, this is the EXACT SAME WAY that WinterBoard works, meaning you can do just about anything with and / or to SpringBoard, or any objective-c class in memory for that matter.
So, how do I load it?
Well, saurik, creator of WinterBoard and Cydia, has whipped up a magical piece of code called MobileSubstrate. MobileSubstrate loads any dylibs that you place in /Library/MobileSubstrate/DynamicLibraries, and provides you with a method for redirecting the methods in memory, almost automatically. Note that the way in which i will be using here, requires at least a basic understanding of C.
Setting up your cross-compiler
If you have not already, you will need to build the iPhone Toolchain, as the Apple iPhone SDK doesn't allow (at least not without extensive modification of XCode) you to build dynamic libraries for the iPhone platform.
Instructions on how to do so are posted here (at least until somebody takes the time to build an automatic toolchain installer):
http://www.saurik.com/id/4
Getting the SpringBoard info.
So you may (and should) be asking yourself, how the hell should I know what classes SpringBoard has, and what their methods are? Well, this knowledge can easily be gained by doing the following, depending on your current operating system.
Mac OS X :
1. Download "class-dump" from the internet.
2. With the iPhone 2.1 SDK final installed on your machine, run this command:
class-dump -H /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.1.sdk/System/Library/CoreServices/SpringBoard.app/SpringBoard -o ~/Desktop/SpringBoard
Example (Using MobileSubstrate)
You will need to get the header for using substrate as well as the mobilesubstrate dynamic library as well. I've uploaded them and you may download them at the bottom of the thread. Place that in the /usr/lib directory of your compilers sysroot
This example does nothing but override the "launch" method of SBApplicationIcon, so when the user clicks an icon, it does not allow them to open it, it simply shows an alert.
ExampleHookProtocol.h
/* * ExampleHookProtocol.h * * * Created by John on 10/4/08. * Copyright 2008 Gojohnnyboi. All rights reserved. * */ #import#import #import #import #import "substrate.h" // We import our headers, "SpringBoard" being the dumped headers placed in your include directory. @protocol ExampleHook // When we redirect the "launch" method, we will specify this prefix, which // will allow us to call the original method if desired. - (void)__OriginalMethodPrefix_launch; @end
/* * ExampleHookLibrary.h * * * Created by John on 10/4/08. * Copyright 2008 Gojohnnyboi. All rights reserved. * */ #import "ExampleHookProtocol.h" // Our method to override the launch of the icon static void __$ExampleHook_AppIcon_Launch(SBApplicationIcon*_SBApplicationIcon); // Our intiialization point that will be called when the dylib is loaded extern "C" void ExampleHookInitialize();
/* * ExampleHookLibrary.mm * * * Created by John on 10/4/08. * Copyright 2008 Gojohnnyboi. All rights reserved. * */ #import "ExampleHookLibrary.h" static void __$ExampleHook_AppIcon_Launch(SBApplicationIcon*_SBApplicationIcon) { UIAlertView* __launchView = [[UIAlertView alloc] init]; __launchView.title = @"No way muchacho"; __launchView.message = @"You can't touch dis!"; [__launchView addButtonWithTitle:@"Dismiss"]; [__launchView show]; // If at any point we wanted to have it actually launch we should do: // [_SBApplicationIcon __OriginalMethodPrefix_launch]; } extern "C" void ExampleHookInitialize() { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // Get the SBApplicationIcon class Class _$SBAppIcon = objc_getClass("SBApplicationIcon"); // MSHookMessage is what we use to redirect the methods to our own MSHookMessage(_$SBAppIcon, @selector(launch), (IMP) &__$ExampleHook_AppIcon_Launch, "__OriginalMethodPrefix_"); // We just redirected SBApplicationIcon's "launch" to our custom method, and now we are done. [pool release]; }
Compiler=arm-apple-darwin9-g++ IP=root@192.168.1.102 Sysroot=/Users/John/Desktop/Toolchain/sys LDFLAGS= -lobjc \ -framework Foundation \ -framework UIKit \ -framework CoreFoundation \ -multiply_defined suppress \ -L$(Sysroot)/usr/lib \ -F$(Sysroot)/System/Library/Frameworks \ -F$(Sysroot)/System/Library/PrivateFrameworks \ -dynamiclib \ -init _ExampleHookInitialize \ -Wall \ -Werror \ -lsubstrate \ -lobjc \ -ObjC++ \ -fobjc-exceptions \ -march=armv6 \ -mcpu=arm1176jzf-s \ -fobjc-call-cxx-cdtors CFLAGS= -dynamiclib Objects= ExampleHookLibrary.o Target=ExampleHook.dylib all: $(Target) install install: scp $(Target) $(IP):/var/root ssh $(IP) chmod 755 $(Target) ssh $(IP) mv $(Target) /Library/MobileSubstrate/DynamicLibraries ssh $(IP) killall SpringBoard $(Target): $(Objects) $(Compiler) $(LDFLAGS) -o $@ $^ ldid -S $(Target) %.o: %.mm $(Compiler) -c $(CFLAGS) $< -o $@ clean: rm -f *.o $(Target)
If you do not have ldid for your compiling platform, i suggest getting it from cydia or via apt itself
apt-get install ldid -y
This compiles perfectly, as shown here:
johns-imac:ExampleHook John$ make arm-apple-darwin9-g++ -c -dynamiclib ExampleHookLibrary.mm -o ExampleHookLibrary.o arm-apple-darwin9-g++ -lobjc -framework Foundation -framework UIKit -framework CoreFoundation -framework GraphicsServices -framework CoreGraphics -framework TelephonyUI -multiply_defined suppress -L/Users/John/Desktop/Toolchain/sys/usr/lib -F/Users/John/Desktop/Toolchain/sys/System/Library/Frameworks -F/Users/John/Desktop/Toolchain/sys/System/Library/PrivateFrameworks -dynamiclib -init _ExampleHookInitialize -Wall -Werror -lsubstrate -lobjc -ObjC++ -fobjc-exceptions -march=armv6 -mcpu=arm1176jzf-s -fobjc-call-cxx-cdtors -o ExampleHook.dylib ExampleHookLibrary.o ldid -S ExampleHook.dylib
And here's a screenshot of what happens when you press the icon.