2015-02-23 49 views
1

是否可以在运行时设置系统调用的钩子?以便携的方式,没有asm,也许有一些动态连接器的功能? 我想拦截第三方库的系统调用。不要想用LD_PRELOAD,它需要外部包装,启动脚本中设置的环境变量在没有LD_PRELOAD的情况下替换符号

+0

你不能钩住真正的系统调用('SYS_open')或库调用来包装系统调用('open')吗? – ysdx 2015-02-23 23:50:37

+0

我想挂钩库调用,只是不知道如何。我是用LD_PRELOAD做的,但是如何从代码本身做到这一点,而不是从shell启动程序? – user1940679 2015-02-23 23:55:09

回答

3

您可以通过重新定义函数重载库调用:

#define _GNU_SOURCE 
#include <stdlib.h> 
#include <stdio.h> 
#include <dlfcn.h> 

void abort(void) 
{ 
    // If necessary, get a instance to the "real" function: 
    void (*real_abort)(void) = dlsym(RTLD_NEXT, "abort"); 
    if(!abort) { 
    fpritnf(stderr, "Could not find real abort\n"); 
    exit(1); 
    } 
    fprintf(stderr, "Calling abort\n"); 
    real_abort(); 
} 

与主

#include <stdlib.h> 

int main(int argc, char** argv) { 
    abort(); 
} 

所得在:

$ ./a.out 
Calling abort 
Aborted 

如果你想在运行时做一个abitrary函数(无需编译您自己的函数版本),您可以尝试使用ELF对象(可执行文件和共享对象)的重定位信息,并在运行时更新重定位。

让我们编译一个简单的地狱世界,看看它的新址:

$ LANG=C readelf -r ./a.out 

Relocation section '.rela.dyn' at offset 0x348 contains 1 entries: 
    Offset   Info   Type   Sym. Value Sym. Name + Addend 
0000006008d8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0 

Relocation section '.rela.plt' at offset 0x360 contains 3 entries: 
    Offset   Info   Type   Sym. Value Sym. Name + Addend 
0000006008f8 000100000007 R_X86_64_JUMP_SLO 0000000000000000 puts + 0 
000000600900 000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0 
000000600908 000300000007 R_X86_64_JUMP_SLO 0000000000000000 __gmon_start__ + 0 

这些都是由动态链接程序进行重定位:在.rela.plt的第一行告诉它需要安装一个PLT条目中的动态链接在0x0000006008f8处为puts符号。为了覆盖put函数,我们可能会在所有共享对象中找到所有符号,并将它们重新定位到合适的函数。

相关问题