是否可以使用LD_PRELOAD覆盖主要方法?

是否可以使用LD_PRELOAD覆盖主要方法?

问题描述:

这主要是出于好奇。我知道如果我用我自己定义的库函数LD_PRELOAD我自己的库,可以替换库函数的定义(?)。我可以为可执行文件的主要方法执行相同的操作吗?是否可以使用LD_PRELOAD覆盖主要方法?

也就是说,没有重建可执行文件,我可以对运行时做些什么,以便调用不同的main()方法吗?

不,您不能使用LD_PRELOAD来覆盖二进制的main函数。

LD_PRELOAD 
      A whitespace-separated list of additional, user-specified, ELF 
      shared libraries to be loaded before all others. This can be 
      used to selectively override functions in other shared 
      libraries. For setuid/setgid ELF binaries, only libraries in 
      the standard search directories that are also setgid will be 
      loaded. 

什么LD_PRELOAD给你是来注入动态链接,这样,当运行时链接程序去解决这些问题,找到您的替换,而不是它的一个通常会找到符号的能力。让我们以这个例子:

的main.c:

#include <stdio.h> 

int main (void) 
{ 
    puts("Hello, world!"); 
    return 0; 
} 

puts.c

#include <stdio.h> 

int puts (const char *s) 
{ 
    return printf("Hijacked puts: %s\n", s); 
} 

如果编译main.c中,检查出其符号:

$ gcc -o main main.c 
$ objdump -t main | grep 'main\|puts' 
main:  file format elf64-x86-64 
0000000000000000 l df *ABS* 0000000000000000    main.c 
0000000000000000  F *UND* 0000000000000000    [email protected]@GLIBC_2.2.5 
0000000000000000  F *UND* 0000000000000000    [email protected]@GLIBC_2.2.5 
00000000004004f4 g  F .text 0000000000000015    main 

请注意,main()功能在这里列出了一个已知的地址,而puts(),它将从glibc中拉出,是未知的。

因此,我们可以强制运行时链接使用我们的看跌期权来代替:

$ gcc -o puts.so -shared -fPIC puts.c 
$ LD_PRELOAD=./puts.so ./main 
Hijacked puts: Hello, world! 

相反,如果我们静态链接我们的原始二进制:

$ gcc -o main -static main.c 
$ objdump -t main | grep 'main\|puts' 
main:  file format elf64-x86-64 
00000000006c27c0 l  O .data 0000000000000888 main_arena 
0000000000000000 l df *ABS* 0000000000000000 main.c 
00000000006c5580 l  O .bss 0000000000000008 _nl_loaded_domains 
00000000004957d0 g  F __libc_freeres_fn 00000000000000d6 _nl_unload_domain 
000000000041bcb0 g  F .text 000000000000170c _nl_load_domain 
00000000006c60e0 g  O .bss 0000000000000008 _nl_domain_bindings 
0000000000402050 w F .text 0000000000000189 puts 
... 

$ LD_PRELOAD=./puts.so ./main 
Hello, world! 

我们覆盖不再工作,因为puts()是静态链接的,导致符号在(静态)链接时被解析。

+0

那么有没有办法做到这一点?必须有*我可以做的事情,也许在初始化一个预加载的库,使__libc_start_main调用一些其他的main而不是在可执行文件中定义的main?有没有可以雇用的技巧? (也许我需要相应地更改我的问题的标题)。感谢您的优秀解释 – AnkurVj 2014-09-12 16:26:10

+0

关注钩子精灵:http://www.codeproject.com/Articles/70302/Redirecting-functions-in-shared-ELF-libraries – Brandon 2014-09-12 16:30:01

+1

我想你*应该*能够覆盖' __libc_main_start',如果你能弄清楚该放什么。 – FatalError 2014-09-12 16:36:52