この記事は iOS Jailbreaking Advent Calendar 2015 の5日目の記事です。
なんのことかというとtheosを使った際にtweakのキモであるMethod swizzleをする手法をどちらにするかという話。
internal
ObjC黒魔術の源 objc/runtime.h
よりmethod_getImplementation()
とmethod_setImplementation()
を使ったswizzle
メソッドの追加にはclass_addMethod()
が使用されます。
MobileSubstrate
substrate.hよりMSHookMessageEx()
を使用したswizzle
メソッドの追加にはinternalと同様にclass_addMethod()
が使用されます。
Theos generator
swizzleやaddMethodをするこの2種類を設定によって簡単に変更出来ます。
ファイル毎に変更が可能で、これがsubstrate。
%config(generator=MobileSubstrate)
これでinternalで生成されます。
%config(generator=internal)
またMakefileで記述する事も可能です。
XXXX_LOGOSFLAGS = -c generator=internal
とか
ADDITIONAL_LOGOSFLAGS = -c generator=internal
このFLAGSは最終的にlogos.plの引数として渡されconfigに設定されます。
GetOptions("config|c=s" => \%main::CONFIG);
上記の通り、long value --config generator=internal
形式でも可。
デフォルトはMobileSubstrateで、その後にFLAGSの設定があれば上書きされます。
ちなみにこのデフォルトは様々なtheos forkでは変わっていたりします。
で、どっちがいいの
その昔、saurik氏は有名なforkにおいてデフォルトがgenerator=internal
になっている話の流れで「tweak側でアップデートをしなくともsubstrate側のアップデートでバグの修正等を得られる」(たしか)と言っていました。
それはそれで真実ですが、iOS 9から最近のアップデートがなされるまでsubstrateはなかなかバギーな状況で
- generatorをinternalにしたらバグがなおる
- substrate.dylibへのリンクをやめるとバグがなおる
私が経験しただけでこの2種類程の症状がありました。
どっちが正解という事もないと思いますが、これまでの開発のなかで「internalだとバグるけどMobileSubstrateにするとなおる」という事態には遭遇したことがないので、最近はinternalの方が良いのではないかなと感じています。