21

バイナリ アプリケーション (サード パーティ、クローズド ソース) に機能を挿入する最良の方法は何でしょうか。

ターゲット アプリケーションは OSX 上にあり、gcc 3+ を使用してコンパイルされているようです。バイナリに実装されている関数のリストを確認でき、リモートで呼び出したい特定の関数をデバッグして分離しました。

zoomByFactor(x,y)具体的には、複雑な HIDevice から特定のデータを受信したときに、この関数を呼び出したいと思います (void と呼びましょう)。

バイナリ ファイル自体を簡単に変更したり、命令を挿入したりできます (つまり、パッチ適用は RAM だけで行う必要はありません)。

これを「うまく」行う方法として何をお勧めしますか?

編集:

私は確かにアプリケーション全体を必要としています。だから私はそれを捨ててライブラリを使うことはできません。(倫理的な説明が必要な人のために: これは、2006 年以来、会社の Web サイトが更新されていないプロプライエタリな CAD ソフトウェアです。データの移行が簡単にできない. この製品はこのままでも十分に私には合っているが、最近入手した新しい HID を使用したい. アプリケーションの内部を調べたので、かなりの自信があります.関連するデータを使用して正しい関数を呼び出して、適切に機能させることができます)。

これが私がこれまでに行ったことです。

このプロセスを通じて、アプリケーションの一部を既に変更しています。

xxd -g 0 バイナリ > バイナリ.hex
猫バイナリ.hex | awk '代用作業' > modified.hex
xxd -r modified.hex > newbinary
chmod 777 ニューバイナリ

バイナリはほぼ 100 メガバイトの大きさであるため、この種のフープをジャンプしています。

私が考えていることの要点は、メイン アプリケーション ループのどこかで jmp を実行し、スレッドを起動して、メイン関数に戻るということです。

さて、質問は次のとおりです。新しいコードをどこに挿入できますか? シンボル テーブルを変更する必要がありますか? または、dylib を自動的にロードして、通常ロードされている dylib への呼び出しをメイン関数に挿入するだけの「ハッキング」を行うにはどうすればよいですか?

4

6 に答える 6

11

私がやったことに興味がある人のために、ここに要約があります:

私はいくつかの可能性を見てきました。これらは、ランタイム パッチと静的バイナリ ファイル パッチに分類されます。

ファイルのパッチに関する限り、私は基本的に 2 つのアプローチを試みました。

  1. バイナリのコード セグメント (__TEXT) のアセンブリを変更します。

  2. mach ヘッダーのロード コマンドを変更します。

最初の方法では、空き領域または上書き可能な方法が必要です。また、保守性が非常に悪いことにも悩まされています。新しいバイナリには、特にソース コードが少しでも変更されている場合は、もう一度手動でパッチを適用する必要があります。

2 番目の方法は、LC_LOAD_DYLIB エントリを mach ヘッダーに追加しようとするものでした。マッチョな編集者はあまりいないので毛むくじゃらですが、実際に自分のエントリが で見えるように構造を変更しましたotool -ldyld: bad external relocation lengthただし、実行時に があったため、これは実際には機能しませんでした。インポートテーブルなどをいじる必要があると思います。これは、エディターなしでうまくいくにはあまりにも多くの努力です。

2 つ目の方法は、実行時にコードを挿入することでした。これを行うための場所はあまりありません。あなたが制御できるアプリ(つまり、あなたが起動する子アプリケーション)であっても。初期化プロセスを起動する方法があるかもしれfork()ませんが、私は決してそれを行いません。

SIMBL はありますが、SIMBL はシステム全体の InputManager として機能し、バンドルを選択的にロードするため、アプリが Cocoa である必要があります。私のアプリはCocoaではなかったので、これを却下しました。さらに、システム全体のものが嫌いです。

次は、mach_inject と mach_star プロジェクトです。google でホストされている PlugSuit と呼ばれる新しいプロジェクトもありますが、これは mach_inject の薄いラッパーにすぎないようです。

Mach_inject は、名前が意味することを行うための API を提供します。ただし、コードに問題が見つかりました。10.5.4 では、mach_inject.c ファイルの mmap メソッドでは、MAP_SHARED または MAP_READ が存在する必要があり、そうでない場合、mmap は失敗します。

それを除けば、すべてが実際に宣伝どおりに機能します。DYLIB を mach ヘッダーに静的に追加することで意図していたことを実行するために、最終的に mach_inject_bundle を使用することになりました。

とにかく、私はこれをwikiにしました。情報を追加、修正、または更新してください。OSX でのこの種の作業に関する情報は事実上ありません。情報が多ければ多いほどよい。

于 2008-11-08T21:17:15.963 に答える
4

10.5 より前の MacOS X リリースでは、Input Manager 拡張機能を使用してこれを行います。Input Manager は、ローマ字以外の言語の入力などを処理することを目的としており、拡張機能がウィンドウをポップアップして適切なグリフを入力し、完成したテキストをアプリに渡すことができます。アプリケーションは、Unicode に対応していることを確認するだけでよく、すべての言語と地域の正確な詳細について心配する必要はありませんでした。

Input Manager は、あらゆる種類の無関係な機能をアプリケーションにパッチするために乱用され、多くの場合、アプリケーションを不安定にしました。また、「Oompa-Loompa」などのトロイの木馬の攻撃ベクトルにもなりました。MacOS 10.5 では、入力マネージャーの制限が厳しくなりました。root または wheel が所有するプロセスや、uid を変更したプロセスでは実行されません。最も重要なことは、10.5 が Input Manager を 64 ビット プロセスにロードせず、32 ビットの使用でさえサポートされておらず、将来のリリースで削除されることが示されていることです。

したがって、制限を受け入れることができれば、Input Manager はやりたいことを実行できます。将来の MacOS リリースでは、これを行うための別の (より安全で、より制限された) 方法がほぼ確実に導入されます。これは、この機能が言語入力のサポートに実際に必要であるためです。

于 2008-11-04T17:36:12.463 に答える
3

DYLD_INSERT_LIBRARIES メソッドも使用できると思います。

この投稿は、あなたがしようとしていたことにも関連しています。

于 2010-09-18T22:59:11.300 に答える
0

Windows では、これは簡単に実行でき、実際には非常に広く行われており、DLL/コード インジェクションとして知られています。

これを可能にする OSX 用の商用 SDK があります: Application Enhancer (非商用の場合は無料)。

于 2009-10-11T16:07:36.467 に答える
0

興味深い問題です。私の理解が正しければ、実行中の実行可能ファイルで関数をリモートで呼び出す機能を追加したいと考えています。

アプリケーション全体が本当に必要ない場合は、メイン関数を取り除いて、リンクできるライブラリ ファイルに変換できる場合があります。必要なすべての初期化が確実に行われるようにする方法を理解するのはあなた次第です。

もう 1 つのアプローチは、ウイルスのように振る舞うことです。おそらく別のスレッドで、リモート呼び出しを処理する関数を挿入します。メイン関数にコードを挿入するか、他の適切な場所にコードを挿入して、このスレッドを起動する必要があります。ほとんどの場合、初期化、スレッド セーフ、および/または適切なプログラム状態の維持に関する重大な問題に遭遇するでしょう。

可能な場合、最善の選択肢は、アプリケーションのベンダーにプラグイン API を公開してもらい、サポートされている方法でこれをクリーンかつ確実に実行できるようにすることです。

いずれかのハック・ザ・バイナリー・ルートを使用すると、時間がかかり、もろくなりますが、その過程で多くのことを学ぶことができます。

于 2008-11-04T17:19:07.083 に答える