この記事は iOS Jailbreaking Advent Calendar 2015 の2日目の記事です。
1日目はHistory of software for jailbroken env.でした。
jailbreak的なtweakとは何か知らない人向けの前説明
Jailbreak界におけるtweakとはOS XにおけるSIMBLのようにダイナミックライブラリ(dylib)を作成しローダー(SIMBL)所定のパスに配置しておく事で特定のプロセスがたちあがったタイミングでローダーがそのライブラリをdlopenして読み込ませる事でそのプロセスの挙動を変更するソフトウェアを指します。
iOSにおいてはSIMBLではなくCydiaSubstrateがその役割を担っています。
ObjC
究極的にはdylibが作成出来れば良いため、Objective-Cでの作成を追ってみましょう。
こんなコードを用意しました。mainの引数は省略しました。
#include <stdio.h>
int main()
{
printf("test");
return 0;
}
ここから直でdylibを作成するならこう
clang -dynamiclib -ObjC main.m -o main.dylib
一旦オブジェクトファイルを経由する場合は
clang -c -ObjC main.m -o main.o
のようにした後
libtool -dynamic main.o -lSystem.B -o main.dylib
これでmain.dylibが出来ます。
Swift
さてSwiftです。こんなコードから
print("test")
swiftファイルのコンパイラであるswiftc
を使ってオブジェクトファイルを作ってみます。(直で作る方法はよくわからなかった)
swiftc -c swift.swift -o swift.o
オブジェクトファイルが出来ました。同様にlibtoolしましょう。
$ libtool -dynamic swift.o -lSystem.B -o swift.dylib
ld: warning: -macosx_version_min not specified, assuming 10.9
ld: warning: object file (swift.o) was built for newer OSX version (10.11) than being linked (10.9)
ld: library not found for -lswiftCore for architecture x86_64
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: internal link edit command failed
おっとlibswiftCore.dylibがないと怒られました。適当なdylibを持ってきてみましょう。
$ cp /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/libswiftCore.dylib .
$ libtool -dynamic -L. swift.o -lSystem.B -o swift.dylib
ld: warning: -macosx_version_min not specified, assuming 10.9
ld: warning: object file (swift.o) was built for newer OSX version (10.11) than being linked (10.9)
ld: warning: ObjC dylib (./libswiftCore.dylib) was compiled for iOS Simulator, but dylibs others were compiled for MacOSX
いくつか警告は出てますが無事dylibが出来ました。リンクは・・・
$ otool -L swift.dylib
swift.dylib:
swift.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
@rpath/libswiftCore.dylib (compatibility version 0.0.0, current version 0.0.0)
というわけでlibswiftCore.dylibが必要です。このswiftランタイムはiOSにデフォルトで入っていないので持っていく必要がありますが、Appleの著作物ですので再配布(redistribute)となると勝手には出来ません。
光明はSwiftをオープンソース化する事をAppleが宣言している事。OSI承認ライセンスと採用するようなので、パッケージ化して再配布が出来る。そのパッケージを依存パッケージとして設定すればユーザに自前でランタイムを持って行ってもらうような苦痛はない。
現実的には
Swiftのバージョンが変わるとコンパイル出来なくなるような変更がまだ入っているのでなかなか厳しそうです。枯れる頃にはiOSにデフォルトで入りそうだし。
加えて、どこまでOSSになるのかという問題もあります。Swiftでまともに書こうと思ったらlibswiftUIKit.dylibとかlibswiftFoundation.dylibとかが欠かせません。このあたりのモジュールまでOSSになるかといえば・・・ならないでしょう。
OSS Swiftで使えるのがlibswiftCore.dylibだけという事になるとサーバサイド用途であれば問題なさそうですがiOSで使っていくには力不足です。
そんなわけで
いまのところのは今後もtweakはObjective-C/C++の方向だと思ってます。
・・・Appleさん、iOSにデフォルトではやくのせないかなぁ。