0

プログラム内の命令のオフセットを見つける必要があります。プログラムcatでopen*system_call*の位置を見つけたいとしましょう。

objdumpを使用してbinファイル内の位置を見つけました。

objdump -T /bin/cat  | grep open : 
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 fdopen
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 open
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 iconv_ope

残念ながら、sibleテーブルを分析すると、open関数が動的にリンクされているため、その情報を取得できません。open関数はglibcに実装されています。

Glibcライブラリで同じアプローチを使用して、open関数のオフセットを取得しましたが、このオフセットは内部の位置を参照しているため、/lib/libc.so.6これは役に立ちません。

00000000000778d0 g    DF .text  00000000000004e3  GLIBC_2.2.5 _IO_file_fopen
000000000006be50 g    DF .text  000000000000000a  GLIBC_2.2.5 fopen
0000000000073540 g    DF .text  00000000000000f6  GLIBC_2.4   open_wmemstream
0000000000121cf0  w   DF .text  0000000000000107  GLIBC_2.2.5 posix_openpt
000000000006d480 g    DF .text  00000000000003bf  GLIBC_2.2.5 _IO_proc_open
00000000000e38b0 g    DF .text  0000000000000021  GLIBC_2.7   __open64_2
000000000006bfe0 g    DF .text  00000000000000fa  GLIBC_2.2.5 fopencookie
000000000006d840 g    DF .text  0000000000000098  GLIBC_2.2.5 popen
00000000000ddd30  w   DF .text  000000000000005e  GLIBC_2.2.5 __open64
000000000006be50 g    DF .text  000000000000000a  GLIBC_2.2.5 _IO_fopen
00000000000de020  w   DF .text  0000000000000020  GLIBC_2.7   __openat64_2
00000000000e84d0 g    DF .text  0000000000000066  GLIBC_2.2.5 openlog
00000000000ddd30  w   DF .text  000000000000005e  GLIBC_2.2.5 open64
00000000003aa630 g    DO .bss   0000000000000008  GLIBC_PRIVATE _dl_open_hook
00000000000ec840 g    DF .text  000000000000005e  GLIBC_2.14  open_by_handle_at
0000000000034250 g    DF .text  0000000000000254  GLIBC_2.2.5 catopen
000000000006d840 g    DF .text  0000000000000098  GLIBC_2.2.5 _IO_popen
0000000000075330 g    DF .text  0000000000000355  GLIBC_2.2.5 freopen64
0000000000075eb0 g    DF .text  00000000000001d8  GLIBC_2.2.5 fmemopen
00000000000b5b90  w   DF .text  000000000000008b  GLIBC_2.4   fdopendir
00000000000de020 g    DF .text  0000000000000020  GLIBC_2.7   __openat_2
00000000000b5640  w   DF .text  000000000000000d  GLIBC_2.2.5 opendir
00000000000e3880 g    DF .text  0000000000000021  GLIBC_2.7   __open_2
00000000000ddd30  w   DF .text  000000000000005e  GLIBC_2.2.5 __open
00000000000777f0 g    DF .text  00000000000000d2  GLIBC_2.2.5 _IO_file_open
0000000000074370 g    DF .text  00000000000000e6  GLIBC_2.2.5 open_memstream
0000000000073ab0 g    DF .text  000000000000035d  GLIBC_2.2.5 freopen
00000000000345a0 g    DF .text  0000000000000837  GLIBC_PRIVATE __open_catalog
00000000000ddd30  w   DF .text  000000000000005e  GLIBC_2.2.5 open
000000000006b540 g    DF .text  0000000000000249  GLIBC_2.2.5 fdopen
0000000000022b20 g    DF .text  000000000000020a  GLIBC_2.2.5 iconv_open
00000000000e2130 g    DF .text  0000000000000373  GLIBC_2.2.5 fts_open
00000000000ddf80  w   DF .text  0000000000000092  GLIBC_2.4   openat
000000000006be50  w   DF .text  000000000000000a  GLIBC_2.2.5 fopen64
00000000000ddf80  w   DF .text  0000000000000092  GLIBC_2.4   openat64
0000000000122f30 g    DF .text  0000000000000046  GLIBC_PRIVATE __libc_dlopen_mode
00000000000dc650 g    DF .text  00000000000000b8  GLIBC_2.2.5 posix_spawn_file_actions_addopen
000000000006b540 g    DF .text  0000000000000249  GLIBC_2.2.5 _IO_fdopen

catプログラムによってopen関数が呼び出されたときに、トレーサーを設定するためのオフセットが必要です。Glibc libにトレーサーを置くと、呼び出されるたびにそのsyscallをトレースします。

手伝って頂けますか?私は自分の問題を明確に説明しましたか?

ありがとう

4

3 に答える 3

3

まあ、それ自体はシステムコールcatを含んでいません。openに住んでいglibc.soます。cat関数を利用するためにライブラリを呼び出します。そのため、内部を見ると、その中に関数catはなくopen、「未定義」であり、を参照していglibc.soます。

catもちろん、どこに電話するかを見つけることができますopen

open@pltシンボルテーブルでシンボルを検索すると、そこからopenと呼ばれます。たとえば、objdump -dどの猫|grep open@pltが表示0000000000401910 <open@plt>:するか、これはglibc関数へのジャンプが行われる場所です。

これがお役に立てば幸いです。

于 2012-12-26T21:41:58.080 に答える
1

適切なダイナミックリンカー統合を備えたデバッガーがこれを処理し、ブレークポイントを設定するシンボリック名を解決する必要があります。ブレークポイントを設定しようとしたときにライブラリがまだロードされていない場合でも、これを行うことができます。

ただし、ユーザーモードデバッガーでトレースできるシステムコールはそれほど多くないことに注意してください。プラットフォームのC呼び出し規約とその多くの場合異なるsyscall規約の間でパラメーターを並べ替えるなどの小さなlibcスタブをトレースしたり、廃止されたsyscallを新しいもののラッパーとして実装したりできますが、実際のカーネルモードの実装カーネルデバッガーでのみトレースできます。

また、すべてのシステムコールのパラメーターと戻り値を出力するstraceプログラムにも興味があるかもしれません。場合によっては、LD_PRELOADを使用するなどの動的ライブラリインターセプトも役立ちます。

于 2012-12-26T23:16:29.067 に答える
1

/proc/$PID/maps共有オブジェクトライブラリのセグメントがプロセスメモリのどこにロードされているかを確認するために使用します。例えば:

# grep libc /proc/$$/maps
7f3243879000-7f3243a2e000 r-xp 00000000 08:01 270246                     /lib/x86_64-linux-gnu/libc-2.15.so
7f3243a2e000-7f3243c2d000 ---p 001b5000 08:01 270246                     /lib/x86_64-linux-gnu/libc-2.15.so
7f3243c2d000-7f3243c31000 r--p 001b4000 08:01 270246                     /lib/x86_64-linux-gnu/libc-2.15.so
7f3243c31000-7f3243c33000 rw-p 001b8000 08:01 270246                     /lib/x86_64-linux-gnu/libc-2.15.so

-したがってlibc.so、プロセスのアドレス空間にロードされる4つのセグメントがあるため、実行可能セグメントが必要です。これは、r-xp(「読み取り、書き込みなし、eXecute、プライベート」)とマークされ、開始は*0x7f3243879000です。シンボルの相対オフセットを取得する方法はすでに知っていfreopenます。たとえば、例から000000000000035dは実行可能セグメントの先頭からです。したがって、私の例では、シンボルはプロセスメモリの7f3243879000 + 35d=にあります。*0x7f324387935d

于 2012-12-26T21:49:12.950 に答える