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

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

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

参考代码:
//功能:调用dexPath文件中的className类的methodName方法。
//dexPath: dex/jar/apk 文件路径
//dexOptDir: 优化目录, 这个目录的owner必须是要被注入进程的user,否则dex优化会失败
//className: 目标类名,如“com.hook.Test”
//methodName: 目标方法名,如"main", 在Java代码里必须定义为public static void main(String[] args);
//argc,传给目标方法的参数个数
//argv,传给目标方法的参数
int invoke_dex_method(const char* dexPath, const char* dexOptDir, const char* className, const char* methodName, int argc, char *argv[]) {
    ALOGD("Invoke dex E");
    JNIEnv* env = android::AndroidRuntime::getJNIEnv();
    jclass stringClass, classLoaderClass, dexClassLoaderClass, targetClass;
    jmethodID getSystemClassLoaderMethod, dexClassLoaderContructor, loadClassMethod, targetMethod;
    jobject systemClassLoaderObject, dexClassLoaderObject;
    jstring dexPathString, dexOptDirString, classNameString, tmpString;    
    jobjectArray stringArray;

    /* Get SystemClasLoader */
    stringClass = env->FindClass("java/lang/String");
    classLoaderClass = env->FindClass("java/lang/ClassLoader");
    dexClassLoaderClass = env->FindClass("dalvik/system/DexClassLoader");
    getSystemClassLoaderMethod = env->GetStaticMethodID(classLoaderClass, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
    systemClassLoaderObject = env->CallStaticObjectMethod(classLoaderClass, getSystemClassLoaderMethod);

    /* Create DexClassLoader */
    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);

    /* Use DexClassLoader to load target class */
    loadClassMethod = env->GetMethodID(dexClassLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
    classNameString = env->NewStringUTF(className);
    targetClass = (jclass)env->CallObjectMethod(dexClassLoaderObject, loadClassMethod, classNameString);
    if (!targetClass) {
        ALOGE("Failed to load target class %s", className);
        return -1;
    }

    /* Invoke target method */
    targetMethod = env->GetStaticMethodID(targetClass, methodName, "([Ljava/lang/String;)V");
    if (!targetMethod) {
        ALOGE("Failed to load target method %s", methodName);
        return -1;
    }
    stringArray = env->NewObjectArray(argc, stringClass, NULL);
    for (int i = 0; i < argc; i++) {
        tmpString = env->NewStringUTF(argv[i]);
        env->SetObjectArrayElement(stringArray, i, tmpString);
    }
    env->CallStaticVoidMethod(targetClass, targetMethod, stringArray);
    ALOGD("Invoke dex X");
    return 0;
}


手机毒霸去广告功能分析一:总体分析
手机毒霸去广告功能分析二:广告View的识别
手机毒霸去广告功能分析三:java代码(dex)注入

@安卓安全小分队
http://weibo.com/androidsecurity

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞3
打赏
分享
最新回复 (13)
雪    币: 1052
活跃值: (1033)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
天涯一鸿 2013-3-22 20:22
2
0
顶一个……
学习技巧~
雪    币: 27
活跃值: (84)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
tihty 2 2013-3-22 21:44
3
0
我不太懂,但是我来围观
雪    币: 53
活跃值: (260)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
netsniffer 2013-3-23 09:42
4
0
不错,示例是以静态方法举例,如果目标类是单例模式设计的,一般会有静态获取实例的方法;
否则,需要构造新实例,但如果该类实例被保存在另一个类对象成员中,且没有方法获取该实例,要hook就有点麻烦了。
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
透明色 2 2013-3-23 10:05
5
0
到三了啊 果断收藏
雪    币: 80
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
weibeat 2013-3-25 09:08
6
0
各种支持楼主分享技术
雪    币: 298
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tedrick 2013-3-25 15:57
7
0
学习!不知山山为何想到这个方法。。。
雪    币: 84
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
janecd 2013-4-8 15:04
8
0
有的看不太懂,学习中。
雪    币: 202
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
无胜 2013-4-9 20:25
9
0
顶技术贴!谢谢~~~
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NISL 2014-5-6 11:32
10
0
“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么,怎么会获取不到实例呢?求指教~~
雪    币: 107
活跃值: (311)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Fido 2014-5-20 08:54
11
0
学习一下。近期要用到
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DeepNoite 2014-5-20 17:48
12
0
斯阔以!!
雪    币: 7
活跃值: (223)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bluth 2016-5-25 00:03
13
0
dexClassLoaderObject = env->NewObject(dexClassLoaderClass, dexClassLoaderContructor, dexPathString, dexOptDirString, NULL, systemClassLoaderObject);
  这里需要指定下SO路径不然只能加载不带SO的apk
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
聖blue 2017-2-16 20:38
14
0
支持下!!!!!
游客
登录 | 注册 方可回帖
返回