私はuprobe tracerのドキュメントを読んでおり、メモリ内の関数のオフセットを計算する方法があります。私はここでそれを引用しています。メモリ内の関数のオフセットを計算する
次の例は、プロービングされたテキストアドレスに命令ポインタと%ax レジスタをダンプする方法を示しています。/binに/のzshでプローブzfree機能:
# cd /sys/kernel/debug/tracing/ # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp 00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh # objdump -T /bin/zsh | grep -w zfree 0000000000446420 g DF .text 0000000000000012 Base zfree
0x46420は 0x00400000にロードされたオブジェクト/ビン/ zshの中zfreeのオフセットされています。
私は理由はわかりませんが、出力は0x446420で、0x46420を得るには0x400000を引いたものです。それは私に誤りとして縫い目をつけた。なぜ0x400000ですか?
4.5.6-200のカーネルでFedora 23でも同じことを試みました。
まず私は、メモリアドレスのランダム化
echo 0 > /proc/sys/kernel/randomize_va_space
は、その後、私はバイナリがメモリ内にある場合
$ cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
555555554000-55555560f000 r-xp 00000000 fd:00 2387155 /usr/bin/zsh
オフセット
[email protected]:~ $ objdump -T /bin/zsh | grep -w zfree
000000000005dc90 g DF .text 0000000000000012 Base zfree
を取り、zfreeがどこにあるかを考え出し考え出しオフgdb経由
$ gdb -p 21067 --batch -ex 'p zfree'
$1 = {<text variable, no debug info>} 0x5555555b1c90 <zfree>
[email protected]:~ $ python
Python 2.7.11 (default, Mar 31 2016, 20:46:51)
[GCC 5.3.1 20151207 (Red Hat 5.3.1-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hex(0x5555555b1c90-0x555555554000)
'0x5dc90'
私はobjdumpと同じ結果を得ています。
しかし、私は別のマシンでSLESを試してみました。そこには、アップローブのドキュメントと同じです。
なぜこのような違いがありますか?正しいオフセットを計算するにはどうすればよいですか?
doc:0x00400000にロードされているobject/bin/zshにあります。オフセットはおそらくプログラムのロードアドレスに相対的であると考えられるので、プログラムのロードアドレスを関数の絶対アドレスから引く必要があります。 – dbrank0
多くのシステムのベースアドレスが0x400000である理由については、「なぜLinuxバイナリの仮想メモリアドレスは0x8048000から始まるのですか」(http://stackoverflow.com/questions/2966426)を参照してください。 Fedora 23は '-fPIC -shared'でパッケージをビルドするので、ロードオフセットは0で、ベースアドレスはランダム(ASLR付き)または0x555555554000です。 –