Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android中的本机库加载断点_Android_C++_Android Ndk_Gdb - Fatal编程技术网

Android中的本机库加载断点

Android中的本机库加载断点,android,c++,android-ndk,gdb,Android,C++,Android Ndk,Gdb,如何在Android中为本机库加载事件设置断点 我假设在dlopen()上设置断点是一个很好的起点,但是,即使在libc.的符号被加载时,gdb也找不到dlopen函数 看起来Android也在使用一些特殊格式的.so文件,因为nm工具也不报告dlopen()位置 有没有解决这个问题的方法,或者是一个特定于Android的.so转储工具,它可以通过名称来帮助定位函数地址,这样我就可以手动设置断点了 编辑: 我试图做的是设置一个断点,当加载任何本机库时,即当任何代码(甚至不在我的库中)调用dlop

如何在Android中为本机库加载事件设置断点

我假设在dlopen()上设置断点是一个很好的起点,但是,即使在libc.的符号被加载时,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源代码,发现了以下源文件:

    看起来dlopen()确实是在/system/bin/linker中定义的,但它使用了一些非标准的符号解析机制(至少根据第一条注释):


    那么,回到问题上来,如何在加载库时将断点设置为dlopen(),以设置实际断点?

    通常任何arm objdump都应该工作,但ndk目录中会有一个。 即使是非arm readelf也可以工作

    我不知道为什么您希望在库中找到dlopen(),除非它显式地使用它来打开另一个库-通常,人们会认为它将从libdvm调用。因此,无论如何,我相信实现是在libdl.so中(为android构建一个版本的grep是一件非常有用的事情——你可以在lib目录中找到字符串,不过如果你想知道它们是导入还是导出,你可能需要对感兴趣的文件进行adb提取和objdump)

    如果您试图对正在加载的库文件设置断点,您可以尝试实现一个静态初始值设定项函数(C-level或加载时的jni)并在那里设置断点

    编辑:

    事实证明,用于arm的objdump不会通过用于从共享库导入的符号的plt对链接进行解码,尽管它对其他一些平台(如x86)进行了解码。这可能会使您很难理解去除调试符号的二进制文件,正如您从设备上的系统库中所期望的那样。我能够tch的binutils源代码为arm做这件事。最终我希望能在某处提交,但在此期间,补丁版本的源代码可以在


    我将一个objdump二进制文件放在一个预构建的linux-x86/目录中,尽管我不知道它的可移植性如何。

    不幸的是,objdump没有。更新了这个问题。正如我之前所说,它在libdl.so中,如果使用正确,objdump工作得很好(从android设备发布,因此现在无法为您计算语法)它确实在libdl.so中,但是libdl.so不在库列表中(信息共享)当应用程序运行时。是的,libdl.so会被链接器劫持。您可能希望尝试中断libdvm中dlopen的使用。因此,诀窍在于它可能是通过.plt中的一些arm代码间接调用的,该代码跳转到链接器实际解析的内容,但objdump无法解决,因此您将看不到dlopen()作为dissasembly中的一个符号,它将隐藏为文件中第一个函数名减去一些偏移量的引用,即指向.plt。一年前,我在一个项目中有一个解码它的方法,试图找出它的位置。我想你能做的最实际的想法是放一个_init()本机库中的函数,它记录一些内容,然后进入无限循环。这将给您一个机会,使用gdb手动中断程序并继续执行(或者可能引发未处理的信号)。
    /* This file hijacks the symbols stubbed out in libdl.so. */