当前位置: 首页 > news >正文

【AOSP专题】07. FART脱壳-02

抽取型:

加固:将app某些方法抽取出来,进行加密和保护。加载app时,默认不会还原到内存,只有执行此功能时才会临时还原并解密到内存(执行完毕后,可能会再次被抽取)。
脱壳:找到所有类主动调用执行类中的所有方法,实现主动加载至内存然后再导出。

1.前置必备

主动调用的本质是:

  • 在APP中寻找所有的ClassLoader
  • 在根据ClassLoader寻找所有的dex
  • 在dex中找到的类
  • 利用反射机制,找到类中所有的成员,在内存中dump导出(dex和CodeItem)

1.1 双亲委派

在安卓底层,类其实都是由各种ClassLoader来进行加载至内存的。例如:

Log.e("测试",String.class.getClassLoader().getClass().toString());       // BootClassLoader
Log.e("测试", Context.class.getClassLoader().getClass().toString());     // BootClassLoader
Log.e("测试",MainActivity.class.getClassLoader().getClass().toString()); // PathClassLoaderLog.e("测试",MainActivity.class.getClassLoader().getParent().getClass().toString()); // BootClassLoader
BootClassLoader,用于加载系统相关的类和方法。
PathClassLoader,用于加载当前APP和安卓相关的类和方法。
DexClassLoader、BaseDexClassLoader,一般用于用户自定义加载dex文件,然后调用其类和方法。注意:有些壳,就是将app自身的dex文件修改或者放在其他的目录,当程序启动时,先运行壳的ClassLoader加载壳的代码,然后再壳的代码中使用DexClassLoader再加载真正的业务先关的dex(代码)。

在这里插入图片描述

类在由ClassLoader加载时,遵循双亲委派机制。本质流程:

  • 读取类对应的ClassLoader,然后根据继承关系找到其所有父级的ClassLoader。
  • 优先由顶层的ClassLoader去加载,
    • 加载成功,则直接返回。
    • 加载失败,则再交给子ClassLoader去加载,依次类推,直到找到最后底层的ClassLoader。

注意: 父级ClassLoader不是指的父类,而是指的内部parent属性对应的值。

1.2 动态加载dex

Android中的ClassLoader于Java中的稍微有些不同,虽然两者都是满足双亲委派,但是直接findClass()会抛异常,所以我们不能直接继承classloader来自定义classLoader。要使用BaseDexClassLoader并重写了findClass(),要注意的是这里的classloader加载的是dex,不是class字节码。

ClassLoader比较常用的分为两种,PathClassLoader和DexClassLoader,虽然两者继承于BaseDexClassLoader,BaseDexClassLoader继承于ClassLoader,但是前者只能加载已安装的Apk里面的dex文件,后者则支持加载apk、dex以及jar,也可以从SD卡里面加载。

接下来:

  • 编译生成一个jar或dex文件(也可以去其他app中拿一个编译好的dex)
  • 将dex文件上传至手机,例如:/data/local/tmp/demo.dex
  • 自定义ClassLoader去加载并调用demo.dex并寻找其中的类进行调用

在这里插入图片描述

1.2.1 外部dex

例如:油联合伙人,解压apk,找到他的classes.dex文件(含所有代码)

在这里插入图片描述

上传至手机:

adb push demo.dex  /data/local/tmp/demo.dex

注意:如果无法运行,可以给 demo.dex 赋一个可读的权限。

1.2.2 自己编译dex

在这里插入图片描述

package com.yltx.oil.partner.utils;import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class Md5 {public static String md5(String str) {try {byte[] digest = MessageDigest.getInstance("MD5").digest(str.getBytes("UTF-8"));StringBuilder sb = new StringBuilder(digest.length * 2);for (byte b : digest) {int i = b & 255;if (i < 16) {sb.append("0");}sb.append(Integer.toHexString(i));}return sb.toString();} catch (NoSuchAlgorithmException e) {throw new RuntimeException("MD5 should not be supported!", e);} catch (UnsupportedEncodingException e2) {throw new RuntimeException("UTF-8 should not be supported!", e2);}}
}

编译并生成jar包:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

基于安卓SDK目录下的dx,将jar包转换为dex文件:

在这里插入图片描述

在这里插入图片描述

D:\Service\AndroidStudio\build-tools\30.0.2\dx.bat  --dex --output=demo.dex  NetUtils.jar

再将生成的 demo.dex 上传至手机:

adb push demo.dex /data/local/tmp/demo.dex 

注意:如果无法运行,可以给 demo.dex 赋一个可读的权限。

1.2.4 示例:动态加载dex

示例:直接使用DexClassLoader类去加载dex文件,并执行其中的功能。

详见LoaderDemo

在这里插入图片描述

在这里插入图片描述

package com.nb.loaderdemo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.util.Log;import java.io.File;
import java.lang.reflect.Method;import dalvik.system.DexClassLoader;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//String dexPath = this.getFilesDir().getPath() + File.separator + "y.dex";//String dexPath = this.getFilesDir().getPath() + File.separator + "demo.dex";String dexPath = "/data/local/tmp/demo.dex";Log.e("路径", dexPath);DexClassLoader classLoader = new DexClassLoader(dexPath, this.getFilesDir().getPath(), null, getClassLoader());try {/*Class clazz = classLoader.loadClass("com.yltx.oil.partner.utils.Md5");Object obj = clazz.newInstance();Method action = clazz.getMethod("md5", String.class);String result = (String) action.invoke(obj, "wupeiqi");Log.e("测试", result);*/Class clazz = classLoader.loadClass("com.yltx.oil.partner.utils.Md5");Method action = clazz.getDeclaredMethod("md5",String.class);String result = (String) action.invoke(clazz, "liuyifei");Log.e("测试", result);} catch (Exception e) {Log.e("测试", e.toString());}}
}

1.2.5 示例:动态加载dex

示例:直接使用自定义MyDexClassLoader类去加载dex文件,并执行其中的功能。

http://www.lqws.cn/news/568405.html

相关文章:

  • Python训练营-Day45-tensorboard
  • 设计模式精讲 Day 18:备忘录模式(Memento Pattern)
  • 如何搭建基于RK3588的边缘服务器集群?支持12个RK3588云手机
  • FAST-LIO2源码分析-状态预测
  • 二叉树进阶刷题02(非递归的前中后序遍历)
  • libevent(2)之使用教程(1)介绍
  • 【分析学】 从闭区间套定理出发(二) -- 闭区间连续函数性质
  • 【WRF-Urban数据集】 WRF 模型城市冠层参数 GloUCP 的使用
  • 1 Studying《Computer Vision: Algorithms and Applications 2nd Edition》11-15
  • 【修电脑的小记录】连不上网
  • 强制IDEA始终使用Java 8
  • (24)如何在 Qt 里创建 c++ 类,以前已经学习过如何在 Qt 里引入资源图片文件。以及如何为继承于 Qt已有类的自定义类重新实现虚函数
  • Java面试宝典:基础二
  • 进阶向:Django入门,从零开始构建一个Web应用
  • 面试准备first
  • 【C++11】异常
  • [Linux入门] Linux LVM与磁盘配额入门指南
  • Tomcat 安装使用教程
  • 大数据Hadoop之——安装部署hadoop
  • 深入剖析Nacos服务发现与注册,及如何基于LoadBalancer实现负载均衡
  • 大事件项目记录13-接口开发-补充
  • 【如何实现分布式压测中间件】
  • 【更新至2024年】1996-2024年各省农村居民人均消费支出数据(无缺失)
  • JVM基础--JVM的组成
  • 如何将Excel表的内容转化为json格式呢?
  • SCAU期末笔记 - 操作系统 英文定义题
  • Linux 环境变量剖析
  • CNN, RNN, LSTM
  • 2.4 分层解耦(Spring的IOC和DI讲解)
  • Qt事件系统