Android loaded the dynamic library code in dalvik/vm/Native. c. The load method is to call the dlopen and dlsym functions in libdl.
You can do some operations in these functions. Replace dlsym with my_dlsym so that you can call your own functions.
The following is an example. Generally, dlopen and dlsym use the following
#include
void* handle = dlopen("./hello.so", RTLD_LAZY);typedef void (*hello_t)();hello_t hello = (hello_t) dlsym(handle, "hello"); hello();dlclose(handle);
We provide hello1 () in another hello1.so ()
#include
void* handle = dlopen("./hello1.so", RTLD_LAZY);typedef void (*hello_t)();hello_t hello = (hello_t) dlsym(handle, "hello1"); hello();dlclose(handle);
The user can still get the hello pointer he wants.
Similarly, it is defined in 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);
Adding the prefix my _ to Native. c functions completely changes the VM load dynamic library mode.
This method can be applied in multiple ways. The following is an example:
For example, if you want to do profiling, for example, func ()
my_func() { // instrument code func()}
Then replace the call to symbol "func" with my_func () in my_dlsym.
Maybe you can directly change func (). However, when there are many functions, You can construct arrays in my_dlsym to facilitate the solution.
Maybe you can replace all the calls to bionic with glibc, but note the differences in data struct definitions, inline and macro definitions.