代码之家  ›  专栏  ›  技术社区  ›  R.. GitHub STOP HELPING ICE

将代码/符号修补到动态链接ELF二进制文件中

  •  9
  • R.. GitHub STOP HELPING ICE  · 技术社区  · 14 年前

    假设我有一个动态链接的ELF二进制文件,我想覆盖/重定向某些库调用。我知道我可以这样做 LD_PRELOAD LD U预加载 可以实现。

    请不要用“你不想这样做”来回答我或者“那不是便携式的!”我正在研究的是一种将二进制文件与稍微不兼容的备用共享库实现接口的方法。如果重要的话,所讨论的平台是i386 linux(即32位)。除非我弄错了什么是可能的,否则我可以编写一些工具来解析ELF文件并执行我的黑客操作,但我怀疑有一种奇特的方法可以使用GNU链接器和其他工具来实现这一点,而无需编写新的代码。

    4 回复  |  直到 14 年前
        1
  •  5
  •   Michael F    14 年前

    我建议 elfsh ERESI 项目,如果你想检测精灵文件本身。与i386 linux的兼容性不是问题,因为我自己也曾使用过它。

    相关的操作方法 here .

        2
  •  2
  •   Jens Gustedt    14 年前

    ld 有选择权 --wrap 它允许您替换给定的符号,如 malloc 用一个你会叫的符号 __wrap_malloc . 有了它,您可以为感兴趣的函数编写一些存根,并将其链接到所讨论的库。

        3
  •  1
  •   Community CDub    7 年前

    所以,我似乎有类似的用例,但我明确地发现对现有二进制文件的任何修改都是不可接受的(对我来说),所以我正在寻找独立的代理方法: Proxy shared library (sharedlib, shlib, so) for ELF?

        4
  •  0
  •   Jander    14 年前

    你可以处理程序本身的一些动态链接。请特别阅读dlsym(3)的手册页,并阅读动态链接接口其余部分的dlopen(3)、dlerror(3)和dlclose(3)。

    一个简单的例子——比如我想重写libc中的dup2(2)。我可以使用以下代码(我们称之为“dltest.c”):

    #define _GNU_SOURCE
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <dlfcn.h>
    
    int (*prev_dup2)(int oldfd, int newfd);
    
    int dup2(int oldfd, int newfd) {
        printf("DUP2: %d --> %d\n", oldfd, newfd);
        return prev_dup2(oldfd, newfd);
    }
    
    int main(void) {
        int i;
    
        prev_dup2 = dlsym(RTLD_NEXT, "dup2");
        if (!prev_dup2) {
            printf("dlsym failed to find 'dup2' function!\n");
            return 1;
        }
        if (prev_dup2 == dup2) {
            printf("dlsym found our own 'dup2' function!\n");
            return 1;
        }
    
        i = dup2(1,3);
        if (i == -1) {
            perror("dup2() failed");
        }
    
        return 0;
    }
    

    gcc -o dltest dltest.c -ldl
    

    静态链接的dup2()函数重写库中的dup2()。即使该函数位于另一个.c文件中(并作为单独的.o编译),也可以执行此操作。

    如果重写函数本身是动态链接的,则可能希望使用dlopen()而不是信任链接器以正确的顺序获取库。

    编辑 :我怀疑,如果重写库中的其他函数调用重写函数,则会调用原始函数,而不是重写。我不知道如果一个动态库调用另一个动态库会发生什么。