6

今日、Mach-O バイナリでシンボルを動的に再バインドするために使用できるフィッシュフック ライブラリhttps://github.com/facebook/fishhookに初めて遭遇しました(iOS 用と書かれていますが、コードは OS X でも動作すると思います)。

これまでのところ、私は mach_override https://github.com/rentzsch/mach_overrideしか知りませんでした。これは、同様の目標 (つまり、関数の 1 つの実装を別の実装に置き換える) を目的としていますが、関数の先頭のアセンブラー ステートメントを次のように書き換えます。別の場所にジャンプします。

フィッシュフック アプローチははるかに単純に見えますが、シンボル テーブルを「のみ」書き換えるので、mach_override アプローチより一般的ではないという直感があります。

あるプロジェクトが他のプロジェクトよりも優先されるべき状況 (つまり、一方のアプローチが機能しないが、もう一方のアプローチが機能する状況) について、誰かが技術的な事実をいくつか教えてもらえますか?

4

2 に答える 2

12

2 つのアプローチでは、異なる方法が使用されます。

A)あなたが述べたように、シンボルテーブルのシンボルでフィッシュフックが機能します。これは、シンボルが dylib またはフレームワークによってエクスポートされ、インポート テーブルにパッチを適用できる場合、それを実装にリダイレクトできることを意味します。

B) mach_override は、OS X (および iOS) の Mach VM API を使用して、関数が既にロードされている場合、つまり既にメモリにある場合にパッチを適用します。これは、関数実装の先頭にバイナリ パッチを適用して、別のアドレス (実装) にジャンプしてから元に戻ることによって実現します。

フィッシュフックは、(i) 実装がより簡単な操作であり、(ii) プロセスが dyld によってロードされてシンボルがリンクされるとシームレスであるという意味で、より安定しています。ただし、実行可能ファイルによって直接読み込まれないシンボルでは機能しません。つまり、たとえば、printf(3) にパッチを適用する場合、実行可能ファイルからの printf の呼び出しに対してのみ機能し、libSystem やその他のライブラリからの呼び出しに対しては機能しません。ただし、Mach_override は、オーバーライドできる特定の関数プロローグに依存しているため、それほど安定しているとは言えません。

iOS ページが読み取り専用であることについては yiding は正しいですが、場合によってはそれを回避できる可能性があります (実行可能ファイルにパッチを適用する場合は、LC_SEGMENT およびセクション コマンドにもパッチを適用できます)。また、mach VM API を使用してページの保護を解除できます。 (デバイスがジェイルブレイクされている場合のみ)。

于 2013-08-01T21:10:50.267 に答える