Pages

Monday, 28 November 2011

MobileSubstrate Tweak Tutorial with Theos


This is an updated (well, completely rewritten) version of my MobileSubstrate Tweak tutorial with Theos. After publishing that tutorial, I heard that a lot of people didn’t have certain things clear in mind, so in this tutorial I’ll make some points more clear..

Pre-requisites:
  • C / Objective-C knowledge: this tutorial’s aim is not to teach you a programming language, but some of the basic concepts related to Jailbreak tweak developing.
  • Knowing how to type commands in a shell: 
  • How to google and solve basic errors you may encounter: yes, “dpkg: command not found” is an example you may run into.
Setting up the environment.
For Theos, the awesome platform by DHowett, everything is explainedhere
Follow the instructions for your operative system, and you should end up with a working development environment. If you encounter errors during that process, google in order to solve them.
Now, you need to download the private headers (such as SpringBoard headers) and place them in $THEOS/include/ (with $THEOS being the directory where you installed theos).
At this point you should have everything set up and ready to start developing a tweak.
Tweak Tutorial.
Theos provides a tool called “New Instance Creator” that allows you to quickly set up a new project based on the type of thing you want to make (command line tool, preference bundle, mobilesubstrate tweak, others). We’re going to use that tool in order to setup our project.
  1. First off, cd to the Desktop.
  2. Then, launch the New Instance Creator (located in /opt/theos/bin/nic.pl).
  3. Template: Choose 5, for a mobilesubstrate tweak.
    Project Name: For the name, we’re going to call this project “Tutorial”.
    Package Name: The package name is  the package id your package will be installed with. The mine is “com.filippobiga.tutorial”.
    Author: Your name.
    Bundle: the bundle identifier you want your dylib to be loaded for. For a SpringBoard tweak (like this tutorial), it’s com.apple.springboard.
  4. cd to the new folder created by Theos.
You should see now 5 elements inside that folder: a makefile, a property list with your bundle filter, a “Tweak.xm” file (where your code will be put in), a control file (for the debian package) and a symbolic link to the theos folder.
You can use your favorite text editor to write the code in the Tweak.xm. If you care about syntax highlighting and you use Xcode, rename the “Tweak.xm” file into “Tweak.mm” and create a symbolic link to it named “Tweak.xm” (mv Tweak.xm Tweak.mm; ln -s Tweak.mm Tweak.xm).
The (really) basic concept of a tweak, is to change the behavior of certain methods in order to achieve different results when they are called. (Be aware that that’s is a really really basic definition, google objective runtime, method swizzling for more).
So first of all, you need to know the class and the method you want to modify, and to know that you have to look in the headers you downloaded before. Those headers may or may not be updated, so you’d better learn how to dump headers on your own.
Most of the sources you see online, are written using Logos: Logos is a kind of pre-processor that allows you to write hooks with a nice syntax, similar to the class implementation one.
For this tweak, we’re going to display a “flash” (like the screenshot one) when the user unlock his device. (I know, it’s not the best idea of the world :P, but it gives the concept).
First off, we need to find the method called when the user unlocks the device: that method is the -(void)unlock in the SBAwayLockBar class. (hint, if it’s not in the SpringBoard header, it could be in the header of the SBAwayLockBar superclass).
So we write these lines in our Tweak.xm file:
%hook SBAwayLockBar // the class you’re hooking
-(void)unlock // the method you’re hooking
{
 %orig; // this calls the original behavior of the method, in order not
}
%end // ends of the hook.
(Read the comments to understand every single line).
Now we need to find the method used by the SpringBoard to flash the screen when a screenshot is taken: the method we’re looking for, is the -(void)flash method in the SBScreenFlash class. We’re also lucky, because that class provides a singleton we can use. So, to flash the screen, we need this line of code:
[[%c(SBScreenFlash) sharedInstance] flash]; // %c is a Logos directive, you can use objc_getClass or NSClassFromString alternatively.
The final code will look like this:
#import <SpringBoard/SpringBoard.h> // for SBScreenFlash
%hook SBAwayLockBar
-(void)unlock // the method you’re hooking
{
 %orig;
[[%c(SBScreenFlash) sharedInstance] flash];
}
%end
We need to link it to the UIKit framework by adding this line to the Makefile:
Tutorial_FRAMEWORKS = UIKit
.. which will look like:
include theos/makefiles/common.mk
TWEAK_NAME = Tutorial
Tutorial_FILES = Tweak.xm
Tutorial_FRAMEWORKS = UIKit
include $(THEOS_MAKE_PATH)/tweak.mk
We’re now ready to compile and install it! :) We can just type “make” and copy the dylib to the /Library/MobileSubstrate/DynamicLibraries/ folder along with the plist, or we can type “make package install” and let Theos take care of everything. After installing, we’ll see the screen of our device flashing when we unlock the slider!
Settings.
What about if the user would like to disable our tweak? We can give him the ability to enable or disable it from a preference bundle. (We could use just a plist for something simple like this, but we’ll use a preference bundle project in order to try it out).  I’m going to skip a few steps with this, since you can figure them out yourself, looking at the source code you can download below.
  • Launch the new instance creator, and initiate a “PreferenceBundle” project. 
  • Add that project as a “subproject” in your main tweak project, by adding the SUBPROJECTS = tutorialsettings key in the Makefile.
  • The structure of the preference bundle is given by a plist containing a collection os PSSpecifiers, used by the standard Preferences app. 
  • Create a switch controlling the “Enabled” key. 
  • For its “defaults” key set it to the package id you used before (com.filippobiga.tutorial). This means it’ll write to a plist with that name in the Preferences folder of the user.
  • Now you need to modify the code in the Tweak.xm to read the user’s Settings and determine if it should flash the screen or not. 
That’s it!
Conclusions.
I hope this tutorial can help all those of you who would like to start developing tweak. You can download the code used in this tutorial from here: Download Source Code.

1 comment:

  1. This tutorial is quite unclear. I couldn't get anything to work. I'm sorry but this helped me a bit.

    ReplyDelete