Frida Playground
から実戦経験が積めます。
インストール用のIPAも配布されているのでSideloadlyでちゃちゃっとインストールしてしまいましょう。
Challenges
早速簡単な方から解いていきます。
適当にインストールしたせいでBundle IDがわからないので調べます。
$ frida-ps -Ua PID Name Identifier---- ---------------------- ------------------------2069 AppStore com.apple.AppStore2060 Nintendo Switch Online com.nintendo.znca3130 Playground eu.nviso.fridaplayground2033 Search com.apple.Spotlight1993 Settings com.apple.Preferences2039 Sileo org.coolstar.SileoStore2068 palera1nLoader com.samiiau.loaderというわけでeu.nviso.fridaplaygroundという値であることがわかりました。
2.1 Switch implementation (ObjC.implement)
ObjC.implementを使ってボタンを押したときに本来呼ばれるlose()に代えてwin()を実行するというものです。
Objc.chooseSync
正解手ではないですがいろいろ解法を載せておきます。
function solve201() { const method = VulnerableVault['- lose']; Interceptor.attach(method.implementation, { onEnter: function (args) { const object = ObjC.chooseSync(VulnerableVault)[0]; object.win(); }, })}Vulnerable
method.implmentationがそのメソッドの処理を持っているのでメソッドの処理自体を置き換えます。
なのでイメージとしては以下のような感じです。
function solve201() { VulnerableVault['- lose'].implementation = VulnerableVault['- win'].implementation;}で、実際にこれは正しく動作します。
function solve201() { const method = VulnerableVault['- lose']; method.implementation = VulnerableVault['- win'].implementation;}値渡しではなく参照渡しになっているのでこちらの書き方でも大丈夫です。
Objc.implement
正攻法で解きます。
function solve201() { const method = VulnerableVault['- lose']; method.implementation = ObjC.implement(method, function (handle, selector) { ObjC.Object(handle).win(); })}こちらであれば長いコードを書くことができます。
2.2 Switch implementation (Interceptor.replace)
使い方がいまいちわからないです。
さっぱりわからないので答えを見ました。
function solve202() { const method = VulnerableVault["- lose"]; Interceptor.replace(method.implementation, new NativeCallback(function(instance, selector) { ObjC.Object(instance).win(); }, 'void', ['pointer', 'pointer']));}NativeCallbackの使い方がいまいち分かりません。特に後半のポインターを指定しているのはなんですかこれ。
2.3 Hook exported function
isSecureがTrueを返すように変更しろとのこと。
で、Hopper Disassemblerで調べてもisSecureというメソッドはありません。
調べてみるとisSecureはiOS 2.0から実装されている標準ライブラリらしいです。
メソッドを読み込むには以下のコードを書きます。
const method = Module.findExportByName(null, "isSecure");このメソッドが実行されたときの処理を書き換えたいので、
Interceptor.attach(method.implementation, { onEnter: function (args) { const object = ObjC.chooseSync(VulnerableVault)[0]; object.win(); }, })