如何在 Android 中为原生库加载事件设置断点?
我假设在dlopen()上设置断点是一个很好的起点,但是,即使加载了libc.so和/system/bin/linker的符号,gdb 也找不到 dlopen 函数。
看起来 Android 正在使用一些特殊格式的 .so 文件,因为 nm 工具也不报告dlopen()位置。
是否有任何解决该问题的方法或特定于 Android 的 .so 转储工具可以帮助按名称定位函数地址,以便我可以手动设置断点?
编辑:
我要做的是设置一个断点,该断点应该在加载任何本机库时触发,即当任何代码(甚至在我的库中)调用dlopen()函数时。
问题是 Android GDB 不支持挂起的断点。我的场景是这样的:
- 我启动我的应用程序并停止它。
- 该应用程序已恢复并加载我的本机库。
- 我的函数是从库中调用的(仅在加载应用程序时调用一次)。
如果我在 #1 之后设置断点,它将无法工作,因为该库仍然不存在并且 android-gdb 将无法重新绑定它。如果我让程序运行,然后再次停止并设置断点,我已经过了#3,所以断点将无用。
我试图通过在#1 处为dlopen()设置断点来解决它,然后当它命中并加载库(即#2)时,我将设置实际的断点。
使用普通的 ARM nm 和 objdump 没有任何帮助。NM'ing libc.so 表明dlopen()未定义:
00016188 T dlmemalign
U dlopen
00016338 T dlpvalloc
/ system/bin/linker二进制文件物理上包含dlopen文本(.rodata部分的第一个字节),但是nm显示以下文本:
arm-linux-androideabi-nm.exe: linker: No symbols
用 objdump 反汇编它不会给出符号名称。
谷歌搜索 android 源发现了这个源文件:
http://dexandroid.googlecode.com/svn/trunk/bionic/linker/dlfcn.c
看起来 dlopen() 确实在 /system/bin/linker 中定义,但它使用了一些非标准的符号解析机制(至少,基于第一条评论):
/* This file hijacks the symbols stubbed out in libdl.so. */
那么,回到问题上来,如何在dlopen()中设置断点,以便在加载库时设置实际断点?