Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在Ubuntu和CentOS上通过LD_预加载挂接库函数时的行为差异_Linux_Ubuntu_Centos_Hook_Ld Preload - Fatal编程技术网

Linux 在Ubuntu和CentOS上通过LD_预加载挂接库函数时的行为差异

Linux 在Ubuntu和CentOS上通过LD_预加载挂接库函数时的行为差异,linux,ubuntu,centos,hook,ld-preload,Linux,Ubuntu,Centos,Hook,Ld Preload,有一个钩子函数socketHook.c用于拦截socket()调用: 在Ubuntu上: $ strace -e trace=socket ./getpwuid socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5 (gdb) catch syscall socket Catchpoint

有一个钩子函数socketHook.c用于拦截socket()调用:

在Ubuntu上:

$ strace -e trace=socket ./getpwuid
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
(gdb) catch syscall socket    
Catchpoint 1 (syscall 'socket' [41])
(gdb) run 
Starting program: /tmp/a.out 

Catchpoint 1 (call to syscall socket), 0x00007ffff7ed3477 in socket () at ../sysdeps/unix/syscall-template.S:120
120     ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) bt
#0  0x00007ffff7ed3477 in socket () at ../sysdeps/unix/syscall-template.S:120
#1  0x00007ffff7f08010 in open_socket (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", keylen=keylen@entry=7) at nscd_helper.c:171
#2  0x00007ffff7f084fa in __nscd_get_mapping (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", mappedp=mappedp@entry=0x7ffff7f980c8 <map_handle+8>) at nscd_helper.c:269
#3  0x00007ffff7f0894f in __nscd_get_map_ref (type=type@entry=GETFDPW, name=name@entry=0x7ffff7f612ca "passwd", mapptr=mapptr@entry=0x7ffff7f980c0 <map_handle>, 
    gc_cyclep=gc_cyclep@entry=0x7fffffffda0c) at nscd_helper.c:419
#4  0x00007ffff7f04fb7 in nscd_getpw_r (key=0x7fffffffdaa6 "0", keylen=2, type=type@entry=GETPWBYUID, resultbuf=resultbuf@entry=0x7ffff7f96520 <resbuf>, 
    buffer=buffer@entry=0x5555555592a0 "", buflen=buflen@entry=1024, result=0x7fffffffdb60) at nscd_getpw_r.c:93
#5  0x00007ffff7f05412 in __nscd_getpwuid_r (uid=uid@entry=0, resultbuf=resultbuf@entry=0x7ffff7f96520 <resbuf>, buffer=buffer@entry=0x5555555592a0 "", buflen=buflen@entry=1024, 
    result=result@entry=0x7fffffffdb60) at nscd_getpw_r.c:62
#6  0x00007ffff7e9e95d in __getpwuid_r (uid=uid@entry=0, resbuf=resbuf@entry=0x7ffff7f96520 <resbuf>, buffer=0x5555555592a0 "", buflen=buflen@entry=1024, 
    result=result@entry=0x7fffffffdb60) at ../nss/getXXbyYY_r.c:255
#7  0x00007ffff7e9dfd3 in getpwuid (uid=0) at ../nss/getXXbyYY.c:134
#8  0x0000555555555143 in main () at t.c:5

(gdb) info sym $pc
socket + 7 in section .text of /lib/x86_64-linux-gnu/libc.so.6
(gdb) up
#1  0x00007ffff7f08010 in open_socket (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", keylen=keylen@entry=7) at nscd_helper.c:171
171     nscd_helper.c: No such file or directory.
(gdb) x/i $pc-5
   0x7ffff7f0800b <open_socket+59>:     callq  0x7ffff7ed3470 <socket>
在运行(1)时,套接字()在CentOS上被截获,但在Ubuntu上不被截获

CentOS.socketHook.c中的printf()存在:

$ uname -a
Linux centos-stream 4.18.0-301.1.el8.x86_64 #1 SMP Tue Apr 13 16:24:22 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

$ LD_PRELOAD=$(pwd)/socketHook.so ./getpwuid
socket() has been intercepted!
Ubuntu(Xubuntu 20.04)。socketHook.c中的printf()不存在:

$ uname -a
Linux ibse-VirtualBox 5.8.0-50-generic #56~20.04.1-Ubuntu SMP Mon Apr 12 21:46:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

$ LD_PRELOAD=$(pwd)/socketHook.so ./getpwuid
$
所以我的问题是:

  • 这取决于什么?我认为这是因为socket()不是直接从可执行文件调用的,而是从getpwuid()调用的,如果我理解正确的话,getpwuid()又是从libc.so调用的
  • 如何在CentOS中实现与Ubuntu相同的行为?我不想拦截来自libc的间接呼叫
  • 这取决于什么

    有两个问题要问:

  • 哪个函数实际调用
    套接字
    系统调用
  • 如何调用该函数
  • 您可以通过在GDB下运行程序并使用
    catch syscall socket
    命令来查看如何调用
    socket
    系统调用。在Ubuntu上:

    $ strace -e trace=socket ./getpwuid
    socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
    socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
    
    (gdb) catch syscall socket    
    Catchpoint 1 (syscall 'socket' [41])
    (gdb) run 
    Starting program: /tmp/a.out 
    
    Catchpoint 1 (call to syscall socket), 0x00007ffff7ed3477 in socket () at ../sysdeps/unix/syscall-template.S:120
    120     ../sysdeps/unix/syscall-template.S: No such file or directory.
    (gdb) bt
    #0  0x00007ffff7ed3477 in socket () at ../sysdeps/unix/syscall-template.S:120
    #1  0x00007ffff7f08010 in open_socket (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", keylen=keylen@entry=7) at nscd_helper.c:171
    #2  0x00007ffff7f084fa in __nscd_get_mapping (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", mappedp=mappedp@entry=0x7ffff7f980c8 <map_handle+8>) at nscd_helper.c:269
    #3  0x00007ffff7f0894f in __nscd_get_map_ref (type=type@entry=GETFDPW, name=name@entry=0x7ffff7f612ca "passwd", mapptr=mapptr@entry=0x7ffff7f980c0 <map_handle>, 
        gc_cyclep=gc_cyclep@entry=0x7fffffffda0c) at nscd_helper.c:419
    #4  0x00007ffff7f04fb7 in nscd_getpw_r (key=0x7fffffffdaa6 "0", keylen=2, type=type@entry=GETPWBYUID, resultbuf=resultbuf@entry=0x7ffff7f96520 <resbuf>, 
        buffer=buffer@entry=0x5555555592a0 "", buflen=buflen@entry=1024, result=0x7fffffffdb60) at nscd_getpw_r.c:93
    #5  0x00007ffff7f05412 in __nscd_getpwuid_r (uid=uid@entry=0, resultbuf=resultbuf@entry=0x7ffff7f96520 <resbuf>, buffer=buffer@entry=0x5555555592a0 "", buflen=buflen@entry=1024, 
        result=result@entry=0x7fffffffdb60) at nscd_getpw_r.c:62
    #6  0x00007ffff7e9e95d in __getpwuid_r (uid=uid@entry=0, resbuf=resbuf@entry=0x7ffff7f96520 <resbuf>, buffer=0x5555555592a0 "", buflen=buflen@entry=1024, 
        result=result@entry=0x7fffffffdb60) at ../nss/getXXbyYY_r.c:255
    #7  0x00007ffff7e9dfd3 in getpwuid (uid=0) at ../nss/getXXbyYY.c:134
    #8  0x0000555555555143 in main () at t.c:5
    
    (gdb) info sym $pc
    socket + 7 in section .text of /lib/x86_64-linux-gnu/libc.so.6
    (gdb) up
    #1  0x00007ffff7f08010 in open_socket (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", keylen=keylen@entry=7) at nscd_helper.c:171
    171     nscd_helper.c: No such file or directory.
    (gdb) x/i $pc-5
       0x7ffff7f0800b <open_socket+59>:     callq  0x7ffff7ed3470 <socket>
    
    到所有文件,或在编译时使用
    -Dsocket=mysocket
    参数


    或者,使用链接器
    --wrap=socket
    将执行重定向,而无需重新编译。

    “调用者不调用socket@plt,因此LD_预载将不会产生任何影响。“什么是@plt?”?LD_预加载拦截是否需要工作?我在哪里可以找到更多关于这个的信息?@ibse我已经更新了答案。你可以在这里阅读关于PLT的内容:并点击链接。
    (gdb) catch syscall socket    
    Catchpoint 1 (syscall 'socket' [41])
    (gdb) run 
    Starting program: /tmp/a.out 
    
    Catchpoint 1 (call to syscall socket), 0x00007ffff7ed3477 in socket () at ../sysdeps/unix/syscall-template.S:120
    120     ../sysdeps/unix/syscall-template.S: No such file or directory.
    (gdb) bt
    #0  0x00007ffff7ed3477 in socket () at ../sysdeps/unix/syscall-template.S:120
    #1  0x00007ffff7f08010 in open_socket (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", keylen=keylen@entry=7) at nscd_helper.c:171
    #2  0x00007ffff7f084fa in __nscd_get_mapping (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", mappedp=mappedp@entry=0x7ffff7f980c8 <map_handle+8>) at nscd_helper.c:269
    #3  0x00007ffff7f0894f in __nscd_get_map_ref (type=type@entry=GETFDPW, name=name@entry=0x7ffff7f612ca "passwd", mapptr=mapptr@entry=0x7ffff7f980c0 <map_handle>, 
        gc_cyclep=gc_cyclep@entry=0x7fffffffda0c) at nscd_helper.c:419
    #4  0x00007ffff7f04fb7 in nscd_getpw_r (key=0x7fffffffdaa6 "0", keylen=2, type=type@entry=GETPWBYUID, resultbuf=resultbuf@entry=0x7ffff7f96520 <resbuf>, 
        buffer=buffer@entry=0x5555555592a0 "", buflen=buflen@entry=1024, result=0x7fffffffdb60) at nscd_getpw_r.c:93
    #5  0x00007ffff7f05412 in __nscd_getpwuid_r (uid=uid@entry=0, resultbuf=resultbuf@entry=0x7ffff7f96520 <resbuf>, buffer=buffer@entry=0x5555555592a0 "", buflen=buflen@entry=1024, 
        result=result@entry=0x7fffffffdb60) at nscd_getpw_r.c:62
    #6  0x00007ffff7e9e95d in __getpwuid_r (uid=uid@entry=0, resbuf=resbuf@entry=0x7ffff7f96520 <resbuf>, buffer=0x5555555592a0 "", buflen=buflen@entry=1024, 
        result=result@entry=0x7fffffffdb60) at ../nss/getXXbyYY_r.c:255
    #7  0x00007ffff7e9dfd3 in getpwuid (uid=0) at ../nss/getXXbyYY.c:134
    #8  0x0000555555555143 in main () at t.c:5
    
    (gdb) info sym $pc
    socket + 7 in section .text of /lib/x86_64-linux-gnu/libc.so.6
    (gdb) up
    #1  0x00007ffff7f08010 in open_socket (type=type@entry=GETFDPW, key=key@entry=0x7ffff7f612ca "passwd", keylen=keylen@entry=7) at nscd_helper.c:171
    171     nscd_helper.c: No such file or directory.
    (gdb) x/i $pc-5
       0x7ffff7f0800b <open_socket+59>:     callq  0x7ffff7ed3470 <socket>
    
    #define socket mysocket