首页
社区
课程
招聘
[原创]手机毒霸去广告功能分析三:java代码(dex)注入
发表于: 2013-3-22 19:26 20983

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

2013-3-22 19:26
20983

  首先简单介绍一下进程注入的概念:
  进程注入就是将一段代码拷贝到目标进程,然后让目标进程执行这段代码的技术。由于这样的代码构造起来比较复杂,所以实际情况下,只将很少的代码注入到目标进程,而将真正做事的代码放到一个共享库中,即.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对象,来加载目标类,然后反射目标类中的目标函数。最终调用之。

参考代码:


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 6
支持
分享
最新回复 (13)
雪    币: 1040
活跃值: (1293)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
顶一个……
学习技巧~
2013-3-22 20:22
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
我不太懂,但是我来围观
2013-3-22 21:44
0
雪    币: 53
活跃值: (280)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
不错,示例是以静态方法举例,如果目标类是单例模式设计的,一般会有静态获取实例的方法;
否则,需要构造新实例,但如果该类实例被保存在另一个类对象成员中,且没有方法获取该实例,要hook就有点麻烦了。
2013-3-23 09:42
0
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
5
到三了啊 果断收藏
2013-3-23 10:05
0
雪    币: 80
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
各种支持楼主分享技术
2013-3-25 09:08
0
雪    币: 298
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
学习!不知山山为何想到这个方法。。。
2013-3-25 15:57
0
雪    币: 84
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
有的看不太懂,学习中。
2013-4-8 15:04
0
雪    币: 202
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
顶技术贴!谢谢~~~
2013-4-9 20:25
0
雪    币: 30
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
“dexClassLoaderContructor = env->GetMethodID(dexClassLoaderClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");//创建构造器
    dexPathString = env->NewStringUTF(dexPath);
    dexOptDirString = env->NewStringUTF(dexOptDir);
    dexClassLoaderObject = env->NewObject(dexClassLoaderClass, dexClassLoaderContructor, dexPathString, dexOptDirString, NULL, systemClassLoaderObject);”
是否可以仿照这段代码构造新的实例,像4楼说的这种情况我不太能理解,因为不是在注入自己的dex么,怎么会获取不到实例呢?求指教~~
2014-5-6 11:32
0
雪    币: 107
活跃值: (404)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
学习一下。近期要用到
2014-5-20 08:54
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
斯阔以!!
2014-5-20 17:48
0
雪    币: 7
活跃值: (263)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
dexClassLoaderObject = env->NewObject(dexClassLoaderClass, dexClassLoaderContructor, dexPathString, dexOptDirString, NULL, systemClassLoaderObject);
  这里需要指定下SO路径不然只能加载不带SO的apk
2016-5-25 00:03
0
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
支持下!!!!!
2017-2-16 20:38
0
游客
登录 | 注册 方可回帖
返回
//