Sunday, October 4, 2009

How to compile mobilesubstrate extension in iPhone gcc for OS 3.0

(1) You need iphone gcc installed in your jailbroken iPhone / iPod Touch with firmware 3.0 or above

iPhone gcc is available in Cydia. To install it in you need to do these


# assume you have installed APT 0.6 Transitional and Aptitude and wget in Cydia, so that you can use the command apt-get
# if libgcc is broken in Cydia, you have to install it manually before iphone-gcc
wget http://apt.saurik.com/debs/libgcc_4.2-20080410-1-6_iphoneos-arm.deb
dpkg -i libgcc_4.2-20080410-1-6_iphoneos-arm.deb
# install iphone-gcc
apt-get install iphone-gcc


Moreover, you need these utilities as well


apt-get install make ldid zip unzip wget


for editor in iPhone you can use vim or nano

(2) You need the header files of toolchain and SDK 3.0, libsubstrate and classdump the SpringBoard and UIKit headers

The building of iPhone gcc in Linux and header files (updated for OS 3.0) is here in
http://www.saurik.com/id/4

The updated mobilesubtrate header files are here

The classdump procedure is here

But all these involved a lot of downloading and patching, so I put all the downloading/classdump/patching in one zipped tar file (sys30.tgz). You can download it (about 96M) here

(3) copy and untar the required headers and libraries (say copy to /var/mobile/sys30.tgz) and install it in iPhone / iPod Touch say

mkdir /var/toolchain/
cd /var/toolchain/
tar -xzvf /var/mobile/sys30.tgz


(4) Use this sample mobilesubstrate extension (ExampleHook.zip) and unzip it to test. You need to apt-get install mobilesubstrate in iPhone / iPod Touch first

http://apiexplorer.googlecode.com/files/ExampleHook.zip

apt-get install mobilesubstrate
wget http://apiexplorer.googlecode.com/files/ExampleHook.zip
unzip ExampleHook.zip
cd ExampleHook

make (to compile and codesign)
make install (to install), after install you need respring the device to test
make uninstall (to uninstall), after uninstall you need respring as well

respring utility is available from my cydia source http://cydia.iphone.org.hk/apt/

(5) You can also checkout a copy of the iphone backgrounder to test your iphone gcc and mobilesubstrate development environment
http://code.google.com/p/iphone-backgrounder/source/checkout

Install subversion before using svn in iPhone / iPod Touch

apt-get install subversion
svn checkout http://iphone-backgrounder.googlecode.com/svn/trunk/ iphone-backgrounder
cd iphone-backgrounder



I use this modified Makefile to compile iphone-backgrounder
MakefileSelect all

NAME = Backgrounder
APP_ID = jp.ashikase.backgrounder

# These paths must be changed to match the compilation environment
TOOLCHAIN = /var/toolchain/sys30/dump
SYS_PATH = /var/toolchain/sys30
MS_PATH = /var/toolchain/sys30/mobilesubstrate
INC_PATH = /var/toolchain/sys30/usr/include
LDID = /usr/bin/ldid

CXX = arm-apple-darwin9-g++
CXXFLAGS = -g0 -O2 -Wall -Werror -Wno-write-strings -include common.h -DAPP_ID=\"$(APP_ID)\"
LD = $(CXX)
LDFLAGS = -march=armv6 \
-mcpu=arm1176jzf-s \
-bind_at_load \
-multiply_defined suppress \
-framework CoreFoundation \
-framework Foundation \
-framework UIKit \
-framework GraphicsServices \
-framework CoreGraphics \
-F$(SYS_PATH)/System/Library/Frameworks \
-F$(SYS_PATH)/System/Library/PrivateFrameworks \
-L$(SYS_PATH)/usr/lib -lsubstrate \
-lobjc

INCLUDES = -I$(INC_PATH) -I$(MS_PATH) -I$(TOOLCHAIN) \
-I./Classes

SUBDIRS = . Classes

DIRLIST := $(SUBDIRS:%=%)
SRCS := $(foreach dir,$(DIRLIST), $(wildcard $(dir)/*.mm))
HDRS := $(foreach dir,$(DIRLIST), $(wildcard $(dir)/*.h))
OBJS := $(SRCS:.mm=.o)

all: $(NAME).dylib

config:
ln -snf $(TOOLCHAIN) $(SYS_PATH)

# Replace 'iphone' with the IP or hostname of your device
install: config $(NAME).dylib
ssh root@iphone rm -f /Library/MobileSubstrate/DynamicLibraries/$(NAME).dylib
scp $(NAME).dylib root@iphone:/Library/MobileSubstrate/DynamicLibraries/
ssh root@iphone restart

$(NAME).dylib: $(OBJS) $(HDRS)
$(LD) -dynamiclib $(LDFLAGS) $(OBJS) -init _$(NAME)Initialize -o $@
$(LDID) -S $@

%.o: %.mm
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

clean:
rm -f $(OBJS) $(NAME).dylib


P.S. This is how to compile a standard c++ program in iPhone gcc
test.cppSelect all

arm-apple-darwin9-g++ -I"/var/toolchain/sys30/usr/include" -I"/var/toolchain/sys30/usr/include/c++/4.2.1" -I"/var/toolchain/sys30/usr/include/c++/4.2.1/armv6-apple-darwin9" -g0 -O2 -Wall -L"/var/toolchain/sys30/usr/lib" -march=armv6 -mcpu=arm1176jzf-s test.cpp -o test






15 comments:

cwe7976 said...

I am unable to get a working class-dump of 3.1, could you please dump and post like you did w/ 3.0? Thanks,

Casey

Charybdis said...

When I try to make the ExampleHook I get the following:

ld: library not found for -lstdc++
collect2: ld returned 1 exit status
make: *** [ExampleHook.dylib] Error 1

Any idea on what I'm doing wrong?

Thanks!

javacom said...

Obviously, you need to install the package called C++ Standard Library in Cydia.

Charybdis said...

Wow, duh. My bad.

Good reference though. I used your packaged setup and it works great.

Etienne said...

Hi all, i've followed this guide using a toolchain in linux, i think i've gone so far..

Now i'm getting this error:

ld: can't locate file for: -lsubstrate

Any idea where can i get this and where should i put this?

Etienne said...

Excuse me, i've managed this copying libsubstrate.dylib from the iphone to the iphone root system in the desktop computer, compiled again, transfered the example and worked like a charm!

Thanks Javacom.

Wade said...

Would this information work on 3.1?

Charybdis said...

Wade: Yes it does, and I'm using it now. That sys30 folder is super handy.

Vol7ron said...

Please disregard, I tried again a few minutes later and it worked.

Note to readers:
if download doesn't work on first load, wait some time and then retry. Retrying right away may still come back with an error.

vol7ron

Vol7ron said...

Nice hook! Worked perfectly :)
Is the only way to uninstall by going to safemode?

Phil said...

You can uninstall the ExampleHookLibrary.dylib by using the make file: make uninstall

I have a problem with this ExampleHook project though, if you decide to use it as a template and make modifications you obviously need to create a new object file (.o) for linking..

In the make file is a clean routine to remove the old object file but from what I can tell there is no routine to create one, and using command line with g++ spews errors due to missing dependencies. More than likely because of the ExampleHooks folder placement, and I can not seem to resolve this problem regardless of what I try.

Anyone know how to create a new object file using the setup stated in the guide:

Project location: /var/root/ExampleHook/
Toolchain location: /var/toolchain/sys30/

Regards...

Mes said...

Thanks a bunch. Great stuff :)
After I figured out it was wise to:
1> move the contents of dump to ~sys30/usr/include directories .... and ...
2> merge the existing UIKit and dump/UIKit contents, it worked like a charm. All my test programs compile, link, and run. A very happy iPhone-want-to-be-programmer (Haha)

abc said...

Can you also package up the headers (like sys30) for iOS4?

Thanks!

Nicolas Bros said...

Hi,
Very useful tutorial!

I am trying to use SBStatusBarController, and I get this error from the linker:
Undefined symbols:
"_OBJC_CLASS_$_SBStatusBarController", referenced from:
__objc_classrefs__DATA@0 in ExampleHook.o

I believe that's because the framework changed between 3.0 and 4.1.

I spent the whole day trying to dump the headers, copy the frameworks, etc. but I still can't make it work.

Could you please make an updated sys41.tgz for iOS 4.1? Or a detailed tutorial on how to make it?

Anonymous said...

yea id like one for 4.0 too..... ive tried myself but i keep getting build errors and junk :(