转自:http://www.jianshu.com/p/03800b72a367
在逆向的时候,有些应用有一大堆的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 详解