gettimeofday
のようなvDSOコールをキャプチャする(つまり、観測する)方法があるかどうかは、strace
です。straceのvDSOをキャプチャ
また、linux-vdso.so.1
(フラグまたはenv変数)をロードせずにバイナリを実行する方法はありますか?
最後に、linux-vdso.so.1
アドレスを補助ベクトルから削除してからexecve
私のプログラムを削除するプログラムを作成するとどうなりますか?誰もそれを試したことがありますか?
gettimeofday
のようなvDSOコールをキャプチャする(つまり、観測する)方法があるかどうかは、strace
です。straceのvDSOをキャプチャ
また、linux-vdso.so.1
(フラグまたはenv変数)をロードせずにバイナリを実行する方法はありますか?
最後に、linux-vdso.so.1
アドレスを補助ベクトルから削除してからexecve
私のプログラムを削除するプログラムを作成するとどうなりますか?誰もそれを試したことがありますか?
strace
の代わりにltrace
を使用して、vDSO経由で実装されたシステムコールのコールをキャプチャできます。これは、vDSOを介して実装されたシステムコールの呼び出しが「通常の」システムコールとは異なって動作し、strace
システムコールをトレースするためのメソッドがvDSO実装のシステムコールでは機能しないためです。 strace
の詳細については、this blog post I wrote about straceをご覧ください。 ltrace
の詳細については、this other blog post I wrote about ltraceをご覧ください。
いいえ、ロードしないでバイナリを実行することはできませんlinux-vdso.so.1
。少なくとも、Ubuntu上のlibcの私のバージョンは正確ではありません。 libc/eglibc/etcの新しいバージョンがこれを機能として追加している可能性は確かですが、それはほとんどありそうにありません。理由については、次の回答を参照してください。
補助ベクトルからアドレスを削除すると、バイナリがクラッシュする可能性があります。 libcにはpiece of codeがあり、最初にvDSO ELFオブジェクトを処理しようとしますが、失敗した場合は、ハードコードされたvsyscallアドレスに戻ります。これを避ける唯一の方法は、vDSOを無効にしてglibcをコンパイルした場合です。
しかし、本当に本当にvDSOを使いたくない場合は、別の回避策があります。 glibc's syscall
functionを使用し、gettimeofday
のシステムコール番号を渡すことができます。これによりglibcはvDSOの代わりにカーネル経由でgettimeofday
を呼び出します。
これを説明するサンプルプログラムが含まれています。私のsyscall blog postを読むことで、システムコールの仕組みについてもっと読むことができます。 strace -ttTf ./test 2>&1 | grep gettimeofday
とgcc -o test test.c
とstraceのと
#include <sys/time.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
int
main(int argc, char *argv[]) {
struct timeval tv;
syscall(SYS_gettimeofday, &tv);
return 0;
}
コンパイル:
09:57:32.651876 gettimeofday({1467305852, 651888}, {420, 140735905220705}) = 0 <0.000006>