在strace中捕获vDSO [英] Capture vDSO in strace
问题描述
我想知道是否有一种方法可以捕获(换句话说,观察)vDSO调用,例如strace
中的gettimeofday
.
I was wondering if there is a way to capture (in other words observe) vDSO calls like gettimeofday
in strace
.
还可以在不加载linux-vdso.so.1
(标志或环境变量)的情况下执行二进制文件吗?
Also, is there a way to execute a binary without loading linux-vdso.so.1
(a flag or env variable)?
最后,如果我编写了一个程序,该程序从辅助向量中删除linux-vdso.so.1
地址,然后从我的程序中删除execve
,该怎么办?有没有人尝试过?
And lastly, what if I write a program that delete the linux-vdso.so.1
address from the auxiliary vector and then execve
my program? Has anyone ever tried that?
推荐答案
您可以使用ltrace
而不是strace
捕获通过vDSO实现的系统调用.这是因为通过vDSO实现的系统调用的调用与常规"系统调用的工作方式不同,并且strace
用来跟踪系统调用的方法不适用于vDSO实现的系统调用.要了解有关strace
工作原理的更多信息,请查看我写的有关strace的博客文章.而且,要了解有关ltrace
工作原理的更多信息,请查看
You can capture calls to system calls which have been implemented via the vDSO by using ltrace
instead of strace
. This is because calls to system calls implemented via the vDSO work differently than "normal" system calls and the method strace
uses to trace system calls does not work with vDSO-implemented system calls. To learn more about how strace
works, check out this blog post I wrote about strace. And, to learn more about how ltrace
works, check out this other blog post I wrote about ltrace.
否,在不加载linux-vdso.so.1
的情况下无法执行二进制文件.至少,不是在我的Ubuntu精确版libc上.当然,较新版本的libc/eglibc/etc可能已将此功能添加为功能,但似乎不太可能.有关原因,请参见下一个答案.
No, it is not possible to execute a binary without loading linux-vdso.so.1
. At least, not on my version of libc on Ubuntu precise. It is certainly possible that newer versions of libc/eglibc/etc have added this as a feature but it seems very unlikely. See the next answer for why.
如果从辅助向量中删除地址,则二进制文件可能会崩溃. libc具有
If you delete the address from the auxillary vector, your binary will probably crash. libc has a piece of code which will first attempt to walk the vDSO ELF object, and if this fails, will fall back to a hardcoded vsyscall address. The only way it will avoid this is if you've compiled glibc with the vDSO disabled.
但是,还有另一种解决方法,如果您确实不想使用vDSO.您可以尝试使用
There is another workaround, though, if you really, really don't want to use the vDSO. You can try using glibc's syscall
function and pass in the syscall number for gettimeofday
. This will force glibc to call gettimeofday
via the kernel instead of the vDSO.
我在下面包括了一个示例程序来说明这一点.您可以阅读我的系统调用博客文章.
I've included a sample program below illustrating this. You can read more about how system calls work by reading my syscall blog post.
#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;
}
使用gcc -o test test.c
进行编译,并使用strace -ttTf ./test 2>&1 | grep gettimeofday
进行strace:
Compile with gcc -o test test.c
and strace with strace -ttTf ./test 2>&1 | grep gettimeofday
:
09:57:32.651876 gettimeofday({1467305852, 651888}, {420, 140735905220705}) = 0 <0.000006>
这篇关于在strace中捕获vDSO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!