如何解决是否可以以编程方式预加载共享库?
我正在构建一个项目,该项目需要修改一些仿生方法(例如 getaddrinfo、__android_print)的行为。我已经能够使用独立编译器或使用 Cmake 将其直接包含在 Apk 中创建挂钩库。我已经能够使用 setprop wrap.com.foo.bar 和 LD_PRELOAD 预加载共享库,并且它正在工作并且我得到了我想要的结果。但是,我想以编程方式预加载挂钩库,因此我不需要每次在重新启动设备后都执行 LD_PRELOAD 的具体步骤(即禁用 SELinux、根设备、setprop)。
我尝试使用
// MainActivity
companion object {
System.load("/data/data/com.foo.bar/lib/libhookedmethod.so")
}
但我没有看到方法被替换。
int __android_print(varargs a) {
int realmethod(...);
realmethod = dlsym("__android_print");
doStuff();
int res = realmethod(a) ;
return res;
}
同样,编译和使用 LD_PRELOAD 是有效的,但我想在不使用 LD_PRELOAD 的情况下实现它... 什么都有帮助!提前致谢
解决方法
LD_PRELOAD
的工作原理是要求动态加载器在之前加载引用的库。加载器通过按加载顺序搜索加载的库来解析对给定符号的引用。
一旦一个符号被解析到一个特定的库,它就不会在这个过程中被重新绑定到其他库。
以上解释应该清楚为什么在程序已经运行后加载 libhookedmethod.so
没有效果。
关于实现您想要的唯一方法是setenv()
(如果尚未设置)并重新exec()
当前进程。像这样:
int main(int argc,char *argv[])
{
char *e = getenv("LD_PRELOAD");
if (e == NULL || /* any other checks that show LD_PRELOAD to not be as we want it */) {
setenv("LD_PRELOAD",...,1);
execvp(argv[0],argv);
}
// LD_PRELOAD is to our liking. Run the actual program.
...
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。