1

ELF および DWARF 情報を使用してプログラムのすべてのデータを取得し、現在実行中のプロセスにピン ツールをフックする作業を行っています。これは、ピン ツールを使用する一種のデバッガです。

スタックからローカル変数を取得するために、ピンからアクセスできるレジスタ EIP、EBP、および ESP を使用しています。

奇妙に感じたのは、ピン ツールがプロセスに接続されたときに実行されていた現在の関数を EIP が指していると予想していたのに、代わりに EIP がセクション .PLT を指していることです。つまり、Foo() の実行中に pin ツールがプロセスにフックされていた場合、EIP が Foo 関数内のアドレスを指していると予想していました。ただし、.PLT セクションの先頭を指しています。

私が知る必要があるのは、プロセスが現在どの関数にあるかです.PLTセクションを使用して関数のアドレスを取得する方法はありますか? スタックから、または Pin を使用して関数のアドレスを取得する他の方法はありますか? 質問があれば教えてください。

4

1 に答える 1

0

ここで何が起こっているのか正確に理解していない可能性があります...命令ポインターは本当に .plt セクションにありますか、それとも Pin からガベージ値を取得しているだけですか?

EIP を読み取っている命令ポインターに名前を付けますが、64 ビット システムで実行している場合に問題になる可能性があります。命令ポインタ レジスタは、32 ビット システムでは 32 ビット値であり、64 ビット システムでは 64 ビット値であることがわかります。したがって、Pin は実際には、命令ポインターに 3 つの REG_* 名 (EIP、RIP、および GBP) を提供します。EIP は常にレジスタの下位 32 ビット半分、RIP は 64 ビット値、GBP はアーキテクチャに応じて 2 つのうちの 1 つです。64ビットシステムでEIPを要求すると、32ビットシステムでRIPを要求する場合と同じように、ゴミが発生します。

それ以外の場合は、Google で簡単に調べると、この. 少し引用:

デフォルトでは、.plt エントリはすべてリンカによって初期化され、正しいターゲット関数を指すのではなく、ダイナミック ローダー自体を指すようになります。したがって、特定の関数を初めて呼び出すと、ダイナミックローダーは関数を検索し、.plt のターゲットを修正して、次にこの .plt スロットが使用されるときに正しい関数を呼び出すようにします。

そして更に重要なことに:

アプリケーションに制御を移す前に、すべての .plt スロットにアドレスをバインドするよう動的ローダーに指示することができます。これは、プログラムを実行する前に環境変数LD_BIND_NOW=1を設定することによって行われます。これは、たとえばプログラムをデバッグしているときなど、場合によっては便利です。

それが役立つことを願っています。

于 2012-11-06T06:24:53.297 に答える