美文网首页Android安全-逆向
如何快速定位native方法在对应so中的位置

如何快速定位native方法在对应so中的位置

作者: difcareer | 来源:发表于2016-12-28 11:49 被阅读628次

前言

在逆向的时候,有些应用有一大堆的so,而且都是提前加载好,有的so甚至做了处理,很难看出函数名。本文讲述的方法可以快速定位:

  • native方法的实现在哪个so中
  • 在so中的哪个位置

原理

我们知道,在使用native方法之前,需要先load对应的so。 在load so的时候,其实就是dlopen该so。 不管你是否主动注册了方法映射,系统都是通过dlsys来获取对应的实现函数,并将其和java层的method关联起来,具体参见Dalvik虚拟机原理及Xposed hook原理

在调用native方法时,通过桥接的方式来调用:

DalvikBridgeFunc bridge = gDvmJni.useCheckJni ? dvmCheckCallJNIMethod : dvmCallJNIMethod;

其实就是dvmCallJNIMethod

ok,在这个函数中,我们可以将方法名和对应的底层函数地址打印出来即可:

ALOGI("invoke native method %s, addr:%p", method->name, method->insns);

日志如下:

就这么简单。

但是还有几个地方得说一下:

  • 这个addr是运行时候的虚拟地址,如何知道是哪个so呢?

这就需要使用ida调试一下,当断点断下来时,按G跳转到这个地址,你将会在左侧看出是加载了哪个so,将这个地址减去这个so的加载基地址,就可以获取到函数在so中的地址了。

还有另外一种获取基址且不需要调试的方法,直接查看/proc/$pid/maps映射

  • 如何添加打印的代码?

两种选择:编译源码和native hook。
编译源码见ubuntu14.04编译Android4.4源码
native hook见Android Inline Hook 详解

如果觉得我的文章对你有帮助,想要打赏我,请扫下面的微信(吐槽下简书的打赏提现略坑)

Paste_Image.png

相关文章

网友评论

  • a260ce8396bf:请问DalvikBridgeFunc bridge = gDvmJni.useCheckJni ? dvmCheckCallJNIMethod : dvmCallJNIMethod;这个代码在源码的什么位置啊
    difcareer:@ChenMoGe2 看看源码吧 类似吧
    a260ce8396bf:@difcareer 我想在5.1的源码里打印有什么方法呢
    difcareer:@ChenMoGe2 看看4.4的源码 搜索一下
  • 熊皮皮:我在用FFmpeg 32位动态库里,调用代码写在C++源文件,最后编译成一个动态库A。实际使用时,我发现用System.loadLibrary加载动态库A就够了,不需要我自己编写System.loadLibrary加载FFmpeg那几个动态库,这是什么原因呢?
    difcareer:@熊皮皮

    特意翻了elf文档,动态链接器在链接时,会加载依赖项,具体如下:

    3.8.3.4 共享目标的依赖关系
    在链接编辑器处理某个归档库时,它会从库中提取成员并将它们复制到输出目标文 件中。这些静态链接的服务都是在执行中可用的,不需要动态链接器的参与。共享目标
    © 北京大学信息科学技术学院操作系统实验室 第 26 页 共 38 页
    PKU/SSDB-03-TR-005 20 03 年 5 月
    所提供的服务则必须由动态链接器附加到进程映像中。因此可执行文件和共享目标文件 描述了它们的特定的依赖关系。 在动态链接器为某个目标文件创建内存段时,依赖关系(记录于动态结构的 DT_NEEDED 表项中)能够提供需要哪些目标来提供程序服务的信息。通过不断地将 被引用的共享目标与他们的依赖之间建立连接,动态链接器构造出完整的进程映像。在 解析符号引用时,动态链接程序使用宽度优先算法检查符号表。 就是说首先检查可执行程序自身的符号表,然后检查 DT_NEEDED 条目(按顺序) 的符号表,接着在第二级 DT_NEEDED 条目上搜索。共享目标文件必须对进程而言可 读,不需要其他权限。 即使某个共享目标在依赖表中出现多次,动态链接器也仅会对其连接一次。 存在于依赖表中的名称或者是 DT_SONAME 字符串的副本,或者是用来构造目标 文件的共享目标的路径名称。例如,如果连接编辑器在构造某个可执行文件时使用的一 个共享目标中包含 lib1 的 DT_SONAME 项,并且使用了路径名为 /usr/llib/lib2 的共 享目标库,那么可执行文件将在其依赖表中包含 lib1 和 /usr/lib/lib2。 如
    熊皮皮:@difcareer 可能是是依赖加载,因为动态库A链接里需要FFmpeg几个库的符号,具体我先看看你发的链接,谢谢了
    difcareer:@熊皮皮 得具体看下, 1 有静态编译么? 2. 是不是被别的地方给load了。3. 貌似是存在so的依赖加载的,参见:https://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/

本文标题:如何快速定位native方法在对应so中的位置

本文链接:https://www.haomeiwen.com/subject/ugryvttx.html