11

libcに静的にリンクされているelfバイナリがあります。私はそのCコードにアクセスできません。OpenOnloadライブラリを使用したいと思います。このライブラリは、ユーザースペースにソケットが実装されているため、標準のlibcバージョンと比較してレイテンシが低くなっています。OpenOnloadは、標準のソケットAPIを実装し、LD_PRELOADを使用してlibcバージョンをオーバーライドします。ただし、このelfバイナリは静的にリンクされているため、OpenOnloadバージョンのソケットAPIを使用することはできません。

次の手順で、このバイナリをOpenOnloadと動的にリンクするように変換できると思います。

  1. 新しいプログラムヘッダーを追加します:PT_INTERP、PT_DYNAMICおよびPT_LOAD。
  2. PT_DYNAMICにエントリを追加して、libcとの依存関係を一覧表示します。
  3. 新しいPT_LOADセクションに必要なlibc関数のPLTスタブを追加します。
  4. libc関数の既存のバイナリコードを変更して、対応するPLTスタブにジャンプします。

最初のカットとして、3つのPT_LOADセグメントを追加してみました。既存のPT_LOADセグメントヘッダーの後に、新しいセグメントヘッダーが追加されました。また、既存のセグメントのvm_addrは変更されませんでした。既存のセグメントのファイルオフセットは、p_alignに基づいて次に整列されたアドレスに下にシフトされました。新しいPT_LOADセグメントが、ファイルの最後のファイルに追加されました。

ファイルを書き直した後、実行すると、カーネルによって正しくロードされましたが、すぐにセグメント障害が発生しました。

私の質問は次のとおりです。

  1. vm_addressesを変更せずに、elfバイナリのファイルオフセットをシフトするだけで、バイナリの実行中にエラーが発生する可能性はありますか?
  2. 私が試みていることをすることは可能ですか?誰かがそれを試みましたか?
4

2 に答える 2

5

あなたが試みていることは、自動化された方法では不可能です。静的リンクの時点で、libcへの呼び出しをlibcへの呼び出しとして識別するすべての再配置情報が解決され、削除されました。デバッグシンボルがバイナリに存在する場合、「テキストセグメントのこのバイト範囲は、そのようなlibc関数に対応します」を識別することはできますが、関数への参照を識別する方法はありません。それらを識別するためのマークアップのない命令バイトストリーム。逆アセンブルに基づくヒューリスティックを使用することもできますが、それらは不完全で信頼性が低くなります(誤検知と誤検知の両方の可能性)。

オフセットをシフトする限り、静的にリンクされたバイナリのロードアドレスについては絶対に変更できません。ロードセグメントの前にヘッダーを挿入する必要がある場合は、ページ全体を挿入し、仮想アドレスのロードオフセットを同じままにして、プログラムヘッダーテーブルのファイルオフセットを更新する(1ページを追加する)必要があります。ただし、あなたがやろうとしていることは全体的に不可能であるため、オフセットシフトの問題はあなたの心配の最も少ないものです。

おそらく、プログラムが高性能を必要としない場合は、qemuがソケットエミュレーション/ラッパーを通過する状態で、qemuアプリレベルのエミュレーションで実行できます。

于 2012-12-20T18:59:18.990 に答える
0

OpenOnload ...は、LD_PRELOADを使用してlibcバージョンをオーバーライドします。しかし、このelfバイナリは静的にリンクされているため...

静的にリンクされた実行可能ファイルのインターセプトシステムコールでも回答

于 2021-10-13T05:44:42.340 に答える