2016-06-29 24 views
3

Ich frage mich, ob es eine Möglichkeit gibt zu erfassen (mit anderen Worten zu beobachten) vDSO Anrufe wie gettimeofday in strace.Capture vDSO in strace

Gibt es auch eine Möglichkeit, eine Binärdatei ohne Laden linux-vdso.so.1 (eine Flag oder env-Variable) auszuführen?

Und was ist, wenn ich ein Programm schreibe, das die linux-vdso.so.1 Adresse aus dem Hilfsvektor und dann execve mein Programm lösche? Hat das jemals jemand probiert?

Antwort

4

Sie können Aufrufe von Systemaufrufen, die über vDSO implementiert wurden, mithilfe von ltrace anstelle von strace erfassen. Dies liegt daran, dass Aufrufe von Systemaufrufen, die über vDSO implementiert werden, anders als "normale" Systemaufrufe funktionieren und die Methode strace zum Verfolgen von Systemaufrufen nicht mit vDSO-implementierten Systemaufrufen funktioniert. Um mehr darüber zu erfahren, wie strace funktioniert, überprüfen Sie this blog post I wrote about strace. Und um mehr darüber zu erfahren, wie ltrace funktioniert, sehen Sie sich this other blog post I wrote about ltrace an.

Nein, es ist nicht möglich, eine Binärdatei ohne Laden linux-vdso.so.1 auszuführen. Zumindest nicht auf meiner Version von libc auf Ubuntu genau. Es ist sicherlich möglich, dass neuere Versionen von libc/eglibc/etc dies als Feature hinzugefügt haben, aber es scheint sehr unwahrscheinlich. Siehe die nächste Antwort für warum.

Wenn Sie die Adresse aus dem Hilfsvektor löschen, stürzt Ihre Binärdatei wahrscheinlich ab. libc hat eine , die zuerst versuchen wird, das vDSO-ELF-Objekt laufen zu lassen, und falls dies fehlschlägt, wird auf eine fest codierte vsyscall-Adresse zurückgegriffen. Die einzige Möglichkeit, dies zu vermeiden, ist, wenn Sie glibc mit deaktiviertem vDSO kompiliert haben.

Es gibt jedoch eine andere Problemumgehung, wenn Sie wirklich, wirklich nicht den vDSO verwenden möchten. Sie können versuchen, glibc's syscall function zu verwenden und die syscall-Nummer für gettimeofday übergeben. Dadurch wird glibc gezwungen, gettimeofday über den Kernel anstelle von vDSO aufzurufen.

Ich habe ein Beispielprogramm darunter dargestellt, das dies veranschaulicht. Sie können mehr darüber lesen, wie Systemaufrufe funktionieren, indem Sie meine syscall blog post lesen.

#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 mit gcc -o test test.c und strace mit strace -ttTf ./test 2>&1 | grep gettimeofday:

09:57:32.651876 gettimeofday({1467305852, 651888}, {420, 140735905220705}) = 0 <0.000006>