[英]Capture vDSO in strace
I was wondering if there is a way to capture (in other words observe) vDSO calls like gettimeofday
in strace
. 我在想,如果有一种方法来捕获(即观察)VDSO像调用
gettimeofday
在strace
。
Also, is there a way to execute a binary without loading linux-vdso.so.1
(a flag or env variable)? 还有,有没有办法在不加载
linux-vdso.so.1
(一个标志或env变量)的情况下执行二进制文件?
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? 最后,如果我写一个程序,删除
linux-vdso.so.1
从辅助向量地址,然后execve
我的程序? Has anyone ever tried that? 有人试过吗?
You can capture calls to system calls which have been implemented via the vDSO by using ltrace
instead of strace
. 您可以使用
ltrace
而不是strace
来捕获已通过vDSO实现的系统调用的调用。 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. 这是因为通过vDSO实现的对系统调用的调用与“普通”系统调用的工作方式不同,并且
strace
用于跟踪系统调用的方法不适用于vDSO实现的系统调用。 To learn more about how strace
works, check out this blog post I wrote about strace . 要了解有关
strace
如何工作的更多信息,请查看我撰写的有关strace的博客文章 。 And, to learn more about how ltrace
works, check out this other blog post I wrote about ltrace . 而且,要了解有关
ltrace
如何工作的更多信息,请查看我写的关于ltrace的其他博客文章 。
No, it is not possible to execute a binary without loading linux-vdso.so.1
. 不,如果不加载
linux-vdso.so.1
,就不可能执行二进制文件。 At least, not on my version of libc on Ubuntu precise. 至少,不是我在Ubuntu上的libc版本精确。 It is certainly possible that newer versions of libc/eglibc/etc have added this as a feature but it seems very unlikely.
当然,较新版本的libc / eglibc / etc已将此作为功能添加,但似乎不太可能。 See the next answer for why.
请参阅下一个答案。
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.
libc有一段代码首先尝试遍历vDSO ELF对象,如果失败,将返回到硬编码的vsyscall地址。 The only way it will avoid this is if you've compiled glibc with the vDSO disabled.
避免这种情况的唯一方法是,如果你已经禁用vDSO编译了glibc。
There is another workaround, though, if you really, really don't want to use the vDSO. 但是,还有另一种解决方法,如果你真的,真的不想使用vDSO。 You can try using glibc's
syscall
function and pass in the syscall number for gettimeofday
. 您可以尝试使用glibc的
syscall
函数并传入gettimeofday
的系统调用号。 This will force glibc to call gettimeofday
via the kernel instead of the vDSO. 这将强制glibc通过内核而不是vDSO调用
gettimeofday
。
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;
}
Compile with gcc -o test test.c
and strace with strace -ttTf ./test 2>&1 | grep gettimeofday
使用
gcc -o test test.c
编译并使用strace -ttTf ./test 2>&1 | grep gettimeofday
进行strace -ttTf ./test 2>&1 | grep gettimeofday
strace -ttTf ./test 2>&1 | grep gettimeofday
: strace -ttTf ./test 2>&1 | grep gettimeofday
:
09:57:32.651876 gettimeofday({1467305852, 651888}, {420, 140735905220705}) = 0 <0.000006>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.