文章目录

  • Android APK加固-安全人员角度
  • 关于类加载器
    • 类加载器
    • 类加载器的种类和个数
    • 创建类加载实例
    • 类加载器DexClassLoader和PathClassLoader
  • 使用类加载器动态加载dex文件
    • 制作dex文件
    • 动态加载dex文件
    • 完整步骤回顾

Android APK加固-安全人员角度

Android安全人员对APK加固采取的角度大概分为以下几个方面:

  1. 将可执行代码dex文件加密,能够动态解密并执行
  2. 能够检测当前状态是被调试,想尽一切办法反调试

那如果继续再细分一下,实现一个初级的APK加固:

  1. 使用类加载器动态加载dex文件
  2. 设计傀儡dex替换原dex,动态加载dex
  3. 在傀儡dex中的各种地方增加反调试代码

接下来就是从类加载器开始一步步完成APK加固

关于类加载器

类加载器

在JAVA开发中动态加载的技术主要用于加载jar包,使软件具备动态添加插件的功能,Java代码都是写在Class里的,程序运行在虚拟机上时,虚拟机需要把需要的Class加载进来才能创建实例对象并工作,而完成这一加载工作的角色就是ClassLoader。

Android的Dalvik/ART虚拟机如同标准JAVA的JVM虚拟机一样,在运行程序时首先需要将对应的类加载到内存中。因此我们可以利用这一点,在程序运行时手动加载Class,从而达到代码动态加载可执行文件的目的。

Android的Dalvik/ART虚拟机虽然与标准Java的JVM虚拟机不一样,ClassLoader具体的加载细节不一样,但是工作机制是类似的,也就是说在Android中同样可以采取类似的动态加载jar或者dex的功能,只是在Android应用中动态加载一个jar或者dex的工作要比Eclipse加载一个插件复杂许多

类加载器的种类和个数

动态加载的基础是ClassLoader,从名字可以看出ClassLoader就是专门用来处理类加载工作的,所以这个类也叫类加载器,而且一个运行中的APP不仅有一个类加载器。

其实在Android系统启动的时候会创建一个Boot类型的ClassLoader实例,用于加载一些系统Framework层级需要的类,我们的Android应用里也需要用到一些系统的类,所以APP启动的时候也会把Boot类型的ClassLoader传进来。此外,APP也有自己的类。

这些类保存在APK的dex文件里面,所以APP启动的时候,也会创建一个自己的ClassLoader实例,用于加载自己dex文件中的类。下面我们在项目里验证看看。

 public void enmuClassLoader(){int count=0;//获取当前包的ClassLoaderClassLoader classLoader=getClassLoader();if (classLoader!=null){Log.d("GuiShou","[onCreate] classLoader"+count++ +":"+classLoader.toString());}while (classLoader.getParent()!=null){classLoader=classLoader.getParent();Log.d("GuiShou","[onCreate] classLoader"+count++ +":"+classLoader.toString());}}

可以看见有两个ClassLoader实例,一个是BootClassLoader,系统启动时候创建的,一个是PathClassLoader,应用启动时创建的。由此也可以看出,一个运行的Android应用至少有两个ClassLoader。

创建类加载实例

动态加载外部Dex文件的时候,我们也可以使用自己创建的ClassLoader实例来加载dex里面的class,不过ClassLoader的创建方式有点特殊,我们先来看看它的构造方法

private ClassLoader(Void unused,ClassLoader parent){this.parent=parent;
}

创建一个ClassLoader的时候,需要使用一个现有的ClassLoader的实例作为新创建的实例的Parent。这样一来,一个Android应用,甚至整个Android系统里所有的ClassLoader实例都会被一棵树关联起来,这也是ClassLoader的双亲代理模型(Parent-Delegation Model)的特点

类加载器DexClassLoader和PathClassLoader

在Android中,ClassLoader是一个抽象类,在实际开发过程中,我们一般是使用其子类DexClassLoader和PathClassLoader来加载类的。

它们的不同之处是:

  • DexClassLoader可以加载jar/dex/apk,可以从SD卡中加载未安装的APK
  • PathClassLoader只能加载系统中已经安装过的APK

根据功能,我们更加倾向于使用DexClassLoader,所以接下来先使用DexClassLoader来加载一个简单的dex文件

使用类加载器动态加载dex文件

制作dex文件

为了能与Android的类有互动,先写这样一段代码

public class TestActivity {public void CreateVew(Activity ac){//创建一个TextViewTextView tv=new TextView(ac);//创建布局 设置参数FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);//设置控件到顶端的距离params.topMargin=0;//设置控件的位置params.gravity= Gravity.TOP|Gravity.CENTER_HORIZONTAL;tv.setText("TestActivity View");//添加TextView到Avtivity中ac.addContentView(tv,params);}
}

这段代码的效果就是显示一段TextView到Activity中

这次代码直接在Android项目中编译,然后在app的目录中查找class文件复制到自己的目录中即可。类所在的目录是app/build/intermediates/classes/debug/包名

接下来把当前的这个Activity进行反编译得到的smali文件转成一个dex文件放到这个工程的资源文件里

将apk用AndroidKiller打开,分析完成后打开smali文件路径,复制出一份副本

删除其余的smali文件,只保留我们自己写的TestActivity类的smali,然后通过smali.jar将其转成dex文件

然后在main文件夹下新建一个assets文件夹,将dex文件复制到里面,并且删除TestActivity类

动态加载dex文件

现在我们已经有了一个制作好的dex文件,接着就需要将这个dex文件动态加载进来。想要动态加载dex,需要下面几个步骤。

  1. 将dex文件从自定义资源文件夹拷贝到程序目录下
  2. 创建一个DexClassLoader,加载dex
  3. 调用加载的dex中的class方法

首先拷贝dex文件

public String CopyDex(String dexName){//获取Asserts目录管理器AssetManager as=getAssets();//合成路径 data/data/包名/files/dex名称String path=getFilesDir()+ File.separator+dexName;Log.d("GuiShou",path);//创建文件流try {FileOutputStream out=new FileOutputStream(path);//打开文件InputStream is=as.open(dexName);//循环读取文件,拷贝到目标路径byte[] buffer=new byte[1024];int len=0;while ((len=is.read(buffer))!=-1){out.write(buffer,0,len);}//关闭文件out.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return path;}

接着创建DexClassLoader

 public DexClassLoader GetLoader(String path){//创建dex的类加载器,返回DexClassLoader对象DexClassLoader dexClassLoader=new DexClassLoader(path,  //dex文件路径getCacheDir().toString(),          //优化后的dex文件路径null,       //原生库路径getClassLoader()    //父类加载器);return dexClassLoader;}

最后调用加载的dex中的class方法

public void  execClassMethod(DexClassLoader dex,String ClassName, String MethodName){try {//获取加载的类信息Class TestDex=dex.loadClass(ClassName);//获取构造方法 无参构造Constructor localConstructor=TestDex.getConstructor(new Class[]{});//调用构造方法 创建对象Object instance=localConstructor.newInstance(new Object[]{});//获取成员方法Method methodTest=TestDex.getDeclaredMethod(MethodName,new Class[]{Activity.class});//取消java访问检查,提高反射速度methodTest.setAccessible(true);//调用方法 this指针传进去methodTest.invoke(instance,new Object[]{this});} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}

最后调用以上三个函数

    //加载dexpublic void loadDex(){//拷贝自定义资源中的dex到程序目录下String dexPath=CopyDex("test.dex");//创建一个DexClassLoader,加载dexDexClassLoader dexClassLoader=GetLoader(dexPath);//调用加载dex中的class方法execClassMethod(dexClassLoader,"com.example.classloaderdemo.TestActivity","CreateVew");}

到这里,代码就已经全部完成了。

接着运行程序,

效果和之前写的dex文件代码一致,那么就说明我们已经完成了动态加载dex文件的过程。

完整步骤回顾

  1. 新建一个工程,创建TestActivity类,实现一个创建view的方法
  2. 编译生成apk,使用AndroidKiller反编译,将除了TestActivity.smali代码外的全部smali文件删除,编译生成dex文件
  3. 在项目main文件夹创建asserts文件夹,将生成的dex拷贝到这个目录下
  4. 在代码中完成以下步骤
    1. 拷贝自定义资源中的dex到程序目录下
    2. 创建一个dexClassLoader加载dex
    3. 调用加载dex中的class方法

018 Android加固之实现dex加载器相关推荐

  1. 【Android 安全】DEX 加密 ( 不同 Android 版本的 DEX 加载 | Android 8.0 版本 DEX 加载分析 | Android 5.0 版本 DEX 加载分析 )

    文章目录 一.不同版本的 DEX 加载 1.Android 8.0 版本 DEX 加载分析 2.Android 6.0 版本 DEX 加载分析 3.Android 5.0 版本 DEX 加载分析 一. ...

  2. Android 中LayoutInflater(布局加载器)之介绍篇

    本文出自博客Vander丶CSDN博客,如需转载请标明出处,尊重原创谢谢 博客地址:http://blog.csdn.net/l540675759/article/details/78099358 前 ...

  3. Android自定义简单的图片加载器(ImageLoader)

    废话不多述,首先来说明下 为什么要用图片加载器 呢,就是为了避免图片重复从网络加载.也就是在第一次从网络加载之后就把图片缓存在本地,下次用的时候直接从本地查找,有的话就直接用,没有再从网络加载. 加载 ...

  4. android dex加载过程,8.1版本dex加载流程笔记--第二篇:DexFile::Open流程与简单脱壳原理...

    在看雪发了,52再发一下,共同学习 菜鸟刚刚学完了dex_file.cc这个源码,大致搞明白了大佬们hook脱整体加固的原理了,原理在帖子最后 学习了大佬angelToms的帖子https://bbs ...

  5. 【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )

    文章目录 一.65535 方法数限制和 MultiDex 配置 二.多 DEX 加载引入 三.PathClassLoader 类加载源码分析 四.BaseDexClassLoader 类加载源码分析 ...

  6. class加载原理和Dex加载的原理-----android插件化技术

    2019独角兽企业重金招聘Python工程师标准>>> class加载原理和Dex加载的原理 转载于:https://my.oschina.net/quguangle/blog/15 ...

  7. 安卓加固方案从落地加载到类指令抽取编写报告

    一.前言以及环境配置     PS:突然想起来好久没在看雪发过啦,这次就同步一下吧!!!     PS:该文已经首发于某公众号,介意者勿喷!!!     安卓的加固方案是从19年底开始写的,到现在为止 ...

  8. android 加载器loader详解

     Loaders loader在android 3.0之后才被引入,它简化了在activity和fragment中异步加载数据的步骤(个人认为简化是次要的,更重要的是优雅的实现了异步加载),loa ...

  9. android多种方式实现异步加载图片

    记得之前做安卓应用时都是在2.2以下的版本,如果在UI线程中进行耗时操作,比如http,socket等 会产生android.os.NetworkOnMainThreadException 如果异步加 ...

最新文章

  1. Android模仿京东登录注册,Android:布局实例之模仿京东登录界面
  2. id int primary key auto_increment是什么意思
  3. 为了搞懂什么是区块链,我都快抑郁了(转)
  4. 猫连接路由器路由下连七台电脑,为啥每台电脑手动设ip才有网?
  5. 撤销Excel文件工作表保护的两种方法
  6. 分布式订单流水号生成器SequenceNoUtils
  7. QString 转toLatin1 toUtf8 toLocal8Bit区别
  8. 一个程序员的真实故事上
  9. 机器学习(线性回归实训)------波士顿房价
  10. 全球及中国游戏耳机行业销售模式与动态盈利分析报告2022版
  11. 爱学术,让论文写作不再难!
  12. MOOS程序解析记录(7)pMarinePID解析
  13. img标签图片404异常捕获返回默认图片
  14. Fortran进行t检验后使用GrADS画打点图
  15. php行业八卦,Phpwind肖睿哲:与网站主合作信任最重要
  16. 关于我是如何自学Java,一个自学网站推荐How2j
  17. 两位数码管动态显示c语言程序,四位数码管动态显示c语言程序
  18. 【Excel】将内容粘贴到合并的单元格中
  19. NLP系列(5)_从朴素贝叶斯到N-gram语言模型
  20. 【深度】剖析微金云宝适合新手的几点优势

热门文章

  1. 成功解决Exception unhandled AttributeError 'MainWindow' object has no attribute 'setDaemon'
  2. Pytorch之CNN:基于Pytorch框架实现经典卷积神经网络的算法(LeNet、AlexNet、VGG、NIN、GoogleNet、ResNet)——从代码认知CNN经典架构
  3. DL之ResNeXt:ResNeXt算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
  4. System之Ubuntu:VMware虚拟机 Ubuntu安装详细过程(图文教程,最强攻略,步骤详细,建议收藏)
  5. 成功解决 bs4\__init__.py:219: UserWarning: b'.' looks like a filename, not markup. You should probably
  6. 任意1-10中的4个数字,使用加减乘除计算得出24结果的可能组合(java版),很多人小时候都玩过...
  7. Gluon.vision的几类数据集
  8. C#中RichEdit控件,保存文本和图片到mysql数据库
  9. ios开发-系统架构
  10. template_1