手机毒霸去广告功能分析三:java代码(dex)注入

首先简单介绍一下进程注入的概念:进程注入就是将一段代码拷贝到目标进程,然后让目标进程执行这段代码的技术。由于这样的代码构造起来比较复杂,所以实际情况下,只将很少的代码注入到目标进程,而将真正做事的代码放到一个共享库中,即.so文件。被注入的那段代码只负责加载这个.so,并执行里面的函数。

 

由于.so中的函数是在目标进程中执行的,所以在.so中的函数可以修改目标进程空间的任何内存,当然也可以加钩子,从而达到改变目标进程工作机制的目的。

 

当然不是任何进程都有权限执行注入操作的。Android平台上的进程注入是基于ptrace()的,要调用ptrace()需要有root权限。目前市面上的主流安全软件也都是基于进程注入来管理和控制其他应用进程的。这也就是为什么这些安全软件需要获得root权限的原因。

关于如何.so注入的实现,有兴趣的朋友可以参考看雪论坛的上的一个注入库LibInject

和洗大师的一个开源项目Android Injector Library

    .so注入以后已经可以干很多事情了,但毕竟是在native层。想要在native层直接修改Java层的变量和逻辑还是很不方便的。况且Android平台的绝大多数应用都是用Java代码写的。因此自然而然就会想到,有没有什么方式可以将dex文件注入目标进程,然后执行dex文件中的Java代码?

 

经过一段时间的研究,笔者找到了一个切实可行的方法。这里分享给大家:首先,所有的Java类都是由类加载器(ClassLoader)加载的,我们要从特定的路径下加载一个我们自己的dex文件,就必须要有一个自己类加载器才行。有了这个类加载器我们就可以加载我们自己的类,并用反射调用这个类里面的方法。其次,要构造生成这样一个类加载器必须要获得现有的类加载器,因为类加载器是双亲委派模式的。现有的类加载器可以通过反射获得。只是这些都需要用native代码实现。

下面简述一下dex注入的过程:

1.       .so注入目标进程,执行.so文件中的某个函数。

2.       在这个函数里先获得一个JNIEnv指针,通过这个指针就可以调JNI函数了。

3.       反射得到当前应用进程的PathClassLoader,用这个ClassLoader来构造一个DexClassLoader对象。Dex文件路径作为一个参数传入DexClassLoader的构造函数,另一个重要的参数是,一个具有可写权限的文件夹路径。因为在做dex优化时,需要生成优化过的dex文件,这跟生成/data/dalvik-cache/下的dex文件是一个道理。

4.       通过这个DexClassLoader对象,来加载目标类,然后反射目标类中的目标函数。最终调用之。

 

 

更多内容请关注 http://blog.sina.com.cn/u/3194858670 以及 sina微博@ 安卓安全小分队

猜你喜欢

转载自android-squad.iteye.com/blog/1837223
今日推荐