3

自分の ELF ファイルの実行可能コンテンツを変更して、これが可能かどうかを確認しようとしています。ELF ファイルを読み取って解析し、更新する必要があるコードを検索して変更し、セクション ヘッダーの sh_size フィールドを更新した後に書き戻すプログラムを作成しました。

ただし、これは機能しません。一部のバイトを他のバイトと交換するだけで機能します。ただし、サイズを変更すると失敗します。一部の sh_offset が互いに隣接していることは承知しています。ただし、実行可能コードのサイズを縮小している場合、これは問題になりません。

もちろん、私のプログラムには (または複数の) バグがあるかもしれませんが、私はすでに苦労してそれを調べてきました。

私のプログラムのデバッグで助けを求める代わりに、私はただ疑問に思っています.sh_sizeフィールド以外に、これを機能させるために更新する必要があるものはありますか(サイズを縮小する場合)? そのフィールド以外に長さの変更を失敗させるものはありますか?

編集:

アンディ・ロスは完全に正しかったようです。この非常に単純なプログラムでさえ、__libc_start_main でいくつかの間接アドレス指定に出くわしました。これは、到達するオフセットを更新するために単純に変更することはできません。

私は興味がありましたが、この問題を可能な限り解決しようとするための最良のアプローチは何でしょうか? すべてのケースでこれを解決できないことはわかっていますが、いくつかの単純なプログラムでは、実行に必要なものを更新できるはずですか? 独自の仮想マシンを作成してみるか、疑わしい問題の各命令を INT 3 に置き換える「デバッガー」を開発してみる必要がありますか? 何か案は?

4

2 に答える 2

5

テキストセグメントは、相対オフセットと内部的にリンクされている可能性があります。したがって、1つの関数が、たとえば「現在のアドレスに194バイトを加えたもの」にジャンプしようとしている可能性があります。ジャンプターゲットが190バイトになるように物事を移動すると、明らかに物事が壊れます。同じことが、一部のアーキテクチャ(たとえば、x86-64ではなくi686)の定数データにも当てはまります。内部参照がどこにあるかを知るための完全な逆アセンブル以外の簡単な方法はありません。実際、それらすべてを見つけることは計算上決定不可能です(つまり、ランタイムで計算されたブランチのすべての可能なジャンプターゲットを理解しようとすることは停止問題です)。

基本的に、これは一般的なケースでは解決できないため、パッチを適用しようとしている他の誰かからのELFバイナリがある場合は、他の手法を試す必要があります。しかし、(すばらしい!)注意を払えば、すべての内部参照がGOT / PLTを通過するライブラリを作成できます。このライブラリは、このようにスライスして再リンクできます。何を達成しようとしていますか?

于 2012-09-28T18:58:40.993 に答える
3

これを機能させるために更新する必要があるsh_sizeフィールド以外に何かありますか

完全にリンクされたバイナリ (ET_EXECまたはET_DYN) にパッチを適用しているようです。静的リンクが行われた後は何も使用され.sh_sizeないことに注意してください。セクション テーブル全体を削除しても、バイナリは引き続き正常に動作します。実行時に重要なのは、セクションではなく、ELFのセグメントです。

ELF は実行形式リンク形式を表し、実行形式とリンク形式は ELF の「二重性」を表します。セクションは、(静的)リンク時にセグメントに結合するために使用されます。実行時に使用されます(別名ランタイム、別名動的リンク時)。

もちろん、バイナリを圧縮するときのパッチ戦略と、結果がどのように壊れているかを正確に教えてくれませんでした。アンディ・ロスの答えがあなたの破損の本当の原因である可能性が非常に高い.

于 2012-10-01T05:22:56.977 に答える