Linux
我可以跳過 strace 中的動態載入程序進行的系統呼叫嗎?
當我
strace
過去檢查一個程序時,我經常很難找到來自動態載入程序的系統呼叫在哪裡結束,而來自程序的系統呼叫從哪裡開始。一個簡單的 hello world C 程序的輸出
strace ./hello
是36 行。hello
這是一個範例:execve("./hello", ["./hello"], 0x7fffb38f4a30 /* 73 vars */) = 0 brk(NULL) = 0x1304000 arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe6715fe60) = -1 EINVAL (Invalid argument) access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=92340, ...}, AT_EMPTY_PATH) = 0 mmap(NULL, 92340, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f78d9fbd000 close(3) = 0 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260|\2\0\0\0\0\0"..., 832) = 832 pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784 pread64(3, "\4\0\0\0 \0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0"..., 48, 848) = 48
有沒有辦法忽略動態載入器系統呼叫?
在 x86_64 上,主程序在
arch_prctl(ARCH_SET_FS)
幾個mprotect()
s 之後啟動,因此您可以sed 1,/ARCH_SET_FS/d
在strace
’s 輸出。您可以在所有平台上使用的一個技巧是
LD_PRELOAD
一個小型庫,它覆蓋__libc_start_main()
並執行無意義的系統呼叫,就像write(-1, "IT_STARTS_HERE", 14)
在呼叫原始__libc_start_main()
.cat >hack.c <<'EOT' #define _GNU_SOURCE #include <dlfcn.h> #include <unistd.h> #include <errno.h> #include <err.h> int __libc_start_main( int (*main)(int,char**,char**), int ac, char **av, int (*init)(int,char**,char**), void (*fini)(void), void (*rtld_fini)(void), void *stack_end) { typeof(__libc_start_main) *next = dlsym(RTLD_NEXT, "__libc_start_main"); write(-1, "IT_STARTS_HERE", 14); errno = 0; return next(main, ac, av, init, fini, rtld_fini, stack_end); } EOT cc -shared -ldl hack.c -o hack.so hack_strace(){ strace -E LD_PRELOAD=./hack.so "$@" 2>&1 >&3 3>&- | sed 1,/IT_STARTS_HERE/d >&2; } 3>&1 # usage hack_strace sh -c 'echo LOL' getuid() = 2000 getgid() = 2000 getpid() = 11443 rt_sigaction(SIGCHLD, {sa_handler=0x55eba5c19380, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER, sa_restorer=0x7fae5c55f840}, NULL, 8) = 0 geteuid() = 2000