classLoader动态加载技术

//加载器,apkPath为包含dex文件的.apk或jar路径,dexPath是优化后的dex文件路径,第三个表示libraryPath表示Native库的路径,最后是父类加载器
DexClassLoader classLoader= new DexClassLoader(apkPath, dexPath,null,getClassLoader());

try{
      //类,在加载类时,先检查父类是否已经加载过这个类?
     Class<?> mLoadClass=classLoader.loadClass("com.example.dexClassloaderslave.DexSlave");
      //构造器
     Constractor<?> constructor=mLoadClass.getConstructor(new Class[] {});
      //对象
     Object dexSlave=constructor.newInstance(new Object[]{});
      //方法
     Method sayHello=mLoadClass.getDeclareMethod("sayHello",new Class[]{});
      //方法属性
     sayHello.setAccessible(true);
      //调用方法
     sayHello.invoke(dexSlave,new Object[]{});
}catch...


ClassLoader localClassLoader=ClassLoader.getSystemClassLoader();
DexClassLoader localDexClassLoader=new DexClassLoader(dexpath,dexOutputPath,null,localClassLoader);
try{
     ...


//args代表传递给方法的参数,receiver表示哪个对象上调用该方法
public Object invoke (Object receiver, Object... args)


dalvik.system.DexFile也可以动态加载dex文件,但是它只能被VM调用。
因为:DexFile的构造器中,要在 /data/dalvik-cache目录下生成dex文件,但是普通应用程序没有对该目录的写权限。





对被调用的.apk .jar文件可以采取以下措施保护:
  1. 完整性校验,防止文件被篡改
  2. 加密处理,调用加载前解密
  3. 对需要调用的函数相关信息通过网络获取方式;该方式可以真正实现动态调用,提高静态分析难度
  4. 对网络服务器分发的方式,注意对网络服务器地址的保护,不要以字符串硬编码方式写入代码中,对下载请求也需要使用cookie等辅助技术


JNI方式动态加载:
      static void com_mtn_javainject_CopyFile_callHook(JNIEnv *env, jclass,jstring path1, jstring path2, jstring className, jstring methodName){
          //找到ClassLoader
               jclass  classLoaderClass=env->FindClass("java/lang/ ClassLoader");
               
               //找到ClassLoader的静态方法 getSystemClassLoader
               jMethodID getsysLoaderMethod=env->GetStaticMethodID(classLoaderClass,"getSystemClassLoader","()Ljava/lang/ClassLoader:");

               //调用getSystemClassLoader方法,返回 ClassLoader对象
               jobject loader=env->CallStaticObjectMethod(classLoaderClass,getsysLoaderMethod);

                //jar包存放位置
               jstring dexpath=path1;
               
                //优化后的jar包存放位置
               jstring dex_odex_path=path2;     

               

                //找到DexClassLoader类
               jclass dexLoaderClass=env->FindClass("dalvik/system/DexClassLoader");
                //获取DexClassLoader的构造函数ID
               jmethodID initDexLoaderMethod=env->GetMethodIDdexLoaderClass,"<init>",(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader:)V");
                //新建一个DexClassLoader对象
               jobject  dexLoader=env->NewObject(dexLoaderClass,initDexLoaderMethod,dexpath,dex_odex_path,NULL,loader);

                //找到DexClassLoader中的findClass()方法
               jmethodID findClassMethod=env->GetMethodID(dexLoaderClass,"findClass","(Ljava/lang/String;)Ljava/lang/Class;");
               //如果返回空,则找DexClassLoader的loadClass()方法--新版本SDK中
               if(NULL==findClassMethod){
                    findClassMethod=env->GetMethodID(dexClassLoader,"loadClass","(Ljava/lang/String;)Ljava/lang/Class;");
               }
               
                //存储需要调用的类,传入进来的
               jstring javaClassName=className;
                //调用DexClassLoader方法,加载需要调用的类
               jclass javaClientClass=(jclass)env->CallObjectMethod(dexLoader,findClassMethod,javaClassName);
               
                //将jstring类型的方法名转换为utf-8编码的字符串,methodName是传进来的
               const  char *func=env->GetStringUFTChars(methodName,NULL);
                //获取加载的类中的方法
               jmethodID inject_method=env->GetStaticMethodID(javaClientClass,func,"()V");
                //调用加载的类中的静态方法
               env->CallStaticVoidMethod(javaClientClass,inject_method);
}


转载于:https://www.cnblogs.com/littlefishxu/p/3969204.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值