替换Android中VM 加载动态库方式

Android   加载动态库的代码在  dalvik/vm/Native.cpp ( froyo 中是 Native.c),加载的方式就是调用 libdl 中 dlopen, dlsym 这些函数

应该可以在这些函数中做些手脚,dlsym 替换为 my_dlsym 这样就可以调用自己的函数

下面举一个例子,通常 dlopen, dlsym 使用如下

#include <dlfcn.h>
void* handle = dlopen("./hello.so", RTLD_LAZY);
typedef void (*hello_t)();
hello_t hello = (hello_t) dlsym(handle, "hello");

 hello();
dlclose(handle);

我们把在另外一个 hello1.so  提供 hello1()

#include <dlfcn.h>
void* handle = dlopen("./hello1.so", RTLD_LAZY);
typedef void (*hello_t)();
hello_t hello = (hello_t) dlsym(handle, "hello1");

 hello();
dlclose(handle);

用户依然可以得到他想要 hello 指针


同理 在 Native.c 中定义

extern void *my_dlopen(const char *filename, int flag);
extern char *my_dlerror(void);
extern void *my_dlsym(void *handle, const char *symbol);
extern int my_dlclose(void *handle);

并把 Native.c 相关函数,加上前缀 my_, 就完全改变了 VM load 动态库的方式


这种方式可以有多种应用方式,下面举个栗子

比如你想做 profiling, 比如 func()

my_func() {
      // instrument code
       func()
}

而后在 my_dlsym 把对 symbol "func" 的调用替换为 my_func(), 就可以了

也许你说可以直接改 func(); 但当函数多的时候,可以在 my_dlsym中构造数组更方便解决


也许你可以把对 bionic 调用,全部替换为 glibc 的,但要注意传递参数的 data struct 定义略有不同,还有 inline 和 宏定义 的处理

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。