別のプログラムをトレースし、関数呼び出し (near 呼び出し、far 呼び出し、動的リンクなど) をリストする小さなプログラムを作成しています。
目標は、dotty フレームワークのおかげでコールグラフを生成することです。
現在、ptrace(PEEK_TEXT) によって指定されたオペコードのデコードに苦労しています。
インテルの公式ドキュメントを読みました( http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-instruction-set-reference -manual-325383.html )
そして、他の十数のマニュアル。
私が得られないポイントがあります:
1) ptrace(PEEK_TEXT) で指定された単語で 0xE8 オペコードを検索すると、多くのアイテムが見つかりました。たとえば、「objdump -d | grep call」と入力すると、次のようになります。
400450: e8 4b 00 00 00 callq 4004a0 <__gmon_start__@plt>
4004d4: e8 b7 ff ff ff callq 400490 <__libc_start_main@plt>
40055d: e8 7e ff ff ff callq 4004e0 <deregister_tm_clones>
40058d: ff d0 callq *%rax
4005ae: e8 cd fe ff ff callq 400480 <printf@plt>
4005b3: e8 b8 fe ff ff callq 400470 <strlen@plt>
4005b8: e8 c3 fe ff ff callq 400480 <printf@plt>
4005c9: 0f 05 syscall
4005fe: e8 3d fe ff ff callq 400440 <_init>
400619: 41 ff 14 dc callq *(%r12,%rbx,8)
それで、私のプログラムは同じ数の呼び出しをリストする必要がありますか? 右 ?しかし、代わりに何百もの呼び出しを見つけます...私は正しいもの、上にリストされたものだけでなく、他のものも見つけます。だから私は考えています、それらは実際には値 0xE8 のプレフィックスではありませんか? 彼らは ?その場合、オペコード 0xE8 を値 0xE8 を持つプレフィックスと区別するにはどうすればよいですか?
2) オペコード 0xE8 に続くオフセットが負の場合、私が見つけた唯一の解決策は、バッファーを 0xff で memset し、それをコピーしてビット符号を強制的に 1 にすることです。別の方法がありますか?
3) 誰かが Mod R/M とそれをデコードする方法をもう一度説明できますか?
4) また、値 0x41 の Rex プレフィックスを解釈する方法は? 0x41 0xE8 が、ランダムな値を持つ別のオペコードではなく、プレフィックスを持つ呼び出しであるかどうかを知るにはどうすればよいですか?
わかりにくかったらすいません、それらのトピックは興味深いものですが、ちょっと迷ってしまいました