Android中的本机库加载断点
作者:互联网
如何在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()中设置断点以设置实际断点?
解决方法:
通常,任何arm objdump都可以工作,但是ndk目录中将有一个.
即使是非武装的自述文件也可能起作用.
我不确定为什么要在库中找到dlopen(),除非它明确地使用它来打开另一个库-通常,人们会认为它将以libdvm.so的方式调用,无论我相信实现在哪儿libdl.so(拥有为Android构建的grep版本是非常有用的事情-您可以在lib目录中找到字符串,尽管如果要查找它们是导入还是导出,则可能需要adb pull和objdump的文件利益).
如果要断点正在加载的库文件,则可以尝试实现静态初始化函数之一(C级或jni加载时),然后在此放置断点.
编辑:
事实证明,arm的objdump不会通过共享库中导入的符号所使用的plt解码链接,尽管它适用于x86等其他平台.就像您从设备上的系统库中所期望的那样,这会使很难理解没有调试符号的二进制文件.我能够修补binutils源代码来完成这项工作.最终,我希望将其提交到某个地方,但与此同时,已修补版本的源代码为https://github.com/cstratton/binutils-android-decodeplt.
我将objdump二进制文件放到了prebuilt-linux-x86 /目录中,尽管我不知道它的可移植性.
标签:gdb,android-ndk,c-4,android 来源: https://codeday.me/bug/20191201/2078641.html