前言
Elf 可执行文件和共享目标文件都有的一个节是 .init_array(类似于PE文件格式的TLS),它先于JNI_OnLoad或者main函数执行,主要用于给编译器生成初始化C或者C++运行时库,为后续代码准备运行时环境。.init_array 节中包含指针,这些指针指向了一些初始化代码,在分析linker 源码中,可以知道节的执行顺序一般为.preinit_array-> .init -> .init_array,在共享目标文件so中.preinit_array中函数是不会执行的,这里我们只说.init_array,很多APK加固方案都在这里有文章。
编写
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
LOGD("%s" , __FUNCTION__);
return JNI_VERSION_1_6;
}
//init函数定义,必须为_init
extern "C" void _init(void){
LOGD("%s" , __FUNCTION__);
}
__attribute__((constructor,visibility("hidden"))) void init_array_0(void) {
LOGD("%s" , __FUNCTION__);
}
__attribute__((constructor,visibility("hidden"))) void init_array_1(void) {
LOGD("%s" , __FUNCTION__);
}
extern "C" void preinit(int argc, char **argv, char **envp) {
LOGD("preinit_array never be called in so");
}
__attribute__((section(".preinit_array"))) typeof(preinit) *__preinit = preinit;
调试
调试这部分腾讯扛把子泉哥的blog上已经有所介绍
http://riusksk.blogbus.com/logs/271566148.html ,这里不再重复讲解了。
网友评论