gpt4 book ai didi

c - 我如何覆盖加载了 dlopen 的库中的全局符号?

转载 作者:行者123 更新时间:2023-12-03 09:51:26 26 4
gpt4 key购买 nike

涉及3个组件

  • main:主程序,加载loader.so
  • loader.so:使用-Bsymbolic编译,覆盖puts并加载other.so
  • other.so:调用puts,不可修改

如何让 other.so 使用 loader.so 中覆盖的 puts

请注意,我希望 puts loader.so 开始(包括 other.so ), 主程序应该不受影响

示例代码如下

main.c

#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char *argv[]){
dlopen("./loader.so", RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND);
puts("Normal");
return 0;
}

loader.c

#include <stdio.h>
#include <dlfcn.h>

extern int puts(const char *s){
fputs("Hooked: ", stdout);
fputs(s, stdout);
fputc('\n', stdout);
return 0;
}

__attribute__((constructor))
void ctor(void) {
puts("Something");
void *other = dlopen("./other.so", RTLD_NOW);
}

other.c

#include <stdio.h>

__attribute__((constructor))
void ctor(void) {
puts("Hello!");
}

make.sh

#!/bin/bash
gcc main.c -o main -ldl
gcc loader.c -fPIC -shared -Wl,-Bsymbolic -o loader.so
gcc other.c -fPIC -shared -o other.so

Desired output

Hooked: Something
Hooked: Hello!
Normal

Actual output

Hooked: Something
Hello!
Normal

最佳答案

在进一步解决这个问题之后,我有一个解决方案需要来自 patchelf 的一些外部帮助,所以我会等着接受这个解决方案,以防有不同的方法来解决这个问题。

这个解决方案通过创建一个新的共享对象来工作,shared.so , 修改后的 puts ,如下

int puts(const char *s){
fputs("Hooked: ", stdout);
fputs(s, stdout);
fputc('\n', stdout);
return 0;
}

然后我们需要强制 other.so依赖这个新的共享对象,我们可以使用 patchelf --add-needed shared.so other.so 来做到这一点

确实涉及对 other.so 的修改, 但它不需要从源代码重新编译(这使得这种方法更可行)。

现在,当我们加载 other.so , 我们需要指定 RTLD_DEEPBIND里面loader.c像这样

void *other = dlopen("./libother.so", RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND);

这样搜索顺序就不会从全局上下文开始,而是从库本身开始。自 other.so没有定义 puts , 将查找直接依赖项,并且 puts将在 shared.so 中找到

RTLD_DEEPBIND 的属性确保即使最终LD_PRELOAD ed 对象被压倒了。

所以如果puts在预加载的共享对象中被禁用,我们可以解决这个问题并调用真实的、未修改的 puts来自 glibc(并且仅适用于来自 other.so 的调用)。

我们不需要任何 patchelfshared.so如果我们想要的只是恢复原来的行为

关于c - 我如何覆盖加载了 dlopen 的库中的全局符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62459383/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com