简体   繁体   English

在strace中捕获vDSO

[英]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像调用gettimeofdaystrace

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM