1
是否可以在運行時設置系統調用的鉤子?以便攜的方式,沒有asm,也許有一些動態連接器的功能? 我想攔截第三方庫的系統調用。不要想用LD_PRELOAD,它需要外部包裝,啓動腳本中設置的環境變量在沒有LD_PRELOAD的情況下替換符號
是否可以在運行時設置系統調用的鉤子?以便攜的方式,沒有asm,也許有一些動態連接器的功能? 我想攔截第三方庫的系統調用。不要想用LD_PRELOAD,它需要外部包裝,啓動腳本中設置的環境變量在沒有LD_PRELOAD的情況下替換符號
您可以通過重新定義函數重載庫調用:
#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函數,我們可能會在所有共享對象中找到所有符號,並將它們重新定位到合適的函數。
你不能鉤住真正的系統調用('SYS_open')或庫調用來包裝系統調用('open')嗎? – ysdx 2015-02-23 23:50:37
我想掛鉤庫調用,只是不知道如何。我是用LD_PRELOAD做的,但是如何從代碼本身做到這一點,而不是從shell啓動程序? – user1940679 2015-02-23 23:55:09