调试android so的.init_array数组
目录
在init_array中下断
下面是网上的一般做法,感觉可能比较适合老一些的android版本,不过也应该都差不多
- 从手机中pull出来linker
- 搜索字符串"[ Calling %s @ %p for ‘%s’ ]"(可能并不是一模一样,没找到的话部分搜索试试)
- 查找引用这个字符串的地址,如果是直接pull出来的linker的话是保留符号信息的,找
call_array/call_function
相关的函数 - 找字符串下方
BLX R4
的地方
init_array下断原理
android源码网站:androidxref.com
loadlibrary的主要步骤
- 调用linker的dlopen完成加载
- 调用dlsym获取目标so的JniOnload地址并调用
- 初始化SharedLibrary对象并添加到表中, 下次加载相同的so则不在重复加载
查看dlopen
源码
调用find_library
转载链接so文件,加载成功后返回soinfo对象指针,同时调用call_constructors
函数来调用so中的init_array
。
call_constructors
先完成其他模块的加载,然后调用call_array
来调用init_array数组中的函数。
call_array
循环调用call_funtion
来进行加载,最后call_function只是简单的调用传进来的函数指针, 可以看到我们上面的下断点的字符串就来自于这里。
所以网上的一般做法可能适用情况有限,可以直接通过对照linker中的源码实现来最终定位,一般来说先找到call_array
中的字符串找对应位置即可。
对于64位so的情况相似,不过是BLX R4
这条指令不同,但是肯定也是找到字符串以后定位寄存器直接调用的地方就行。