精华内容
下载资源
问答
  • 本文目的:通过内存加载DEX文件技术,完成一键DEX加固脚本 使用说明 python sheller.py -f xxx.apk 加固原理 和我的另一个项目基本一样,只是多了一步,引入了内存加载DEX技术 一键加固脚本实现步骤 准备原DEX加密...
  • Android DEX加固方案与原理

    千次阅读 2019-11-02 03:08:48
    DEX加固方案的演进

    Android 反编译的威胁

    逆向分析: 漏洞挖掘、协议分析
    二次打包: 盗版、破解、广告

    保护方案

    代码混淆:Java代码、C\C++带马甲、JS\HTML代码
    应用加固:DEX文件、SO文件、资源文件

    APP构建过程中用到的工具

    在这里插入图片描述

    编译流程

    • java源码编译:通过javac将源码编译为.class文件
    • 多dex分包:脚本将类根据一定规则划分到主dex和从dex中,生成配置文件
    • proguard优化/混淆:对.class文件进行压缩、优化、混淆处理
    • 转化为dex文件:dx\d8将.class文件转换为dex文件

    DEX加固方案的演进

    在这里插入图片描述

    • 动态加载:从服务器动态加载业务的DEX
    • DEX内存加载:模拟App启动的时候,将我们的壳、将业务DEX文件加载到内存中,然后通过一些处理方式,让DEX文件把Application启动起来,让应用认为和普通的启动方式是一样的 (缺点:DEX会暴露在内存中)
    • DEX指令抽取:把DEX文件中的一些方法的指令抽取出来,然后在内存中开辟一段区域,然后将我们内存加载的DEX解析到相应的方法指令偏移的地方,方法指令的偏移指向我们开辟的一段内存里面。(缺点:不彻底)
    • 虚拟机加固:我们通过自己实现一套虚拟机,将DEX方法的指令抽取出来,在运行的时候,我们的虚拟机里面就运行被抽取的一段指令。这样攻击者想要破解,首先必须要找到我们虚拟机的入口,将虚拟机整个逻辑还原出来,这样攻击成本相对比较高 (缺点:本身Android应用就运行在虚拟机里面,不论是Dalvik还是ART,增加个虚拟机,就会增加一层对应用运行时代码的解释执行操作,那么解释执行的效率会大大下降)
    • JAVA2C:提升应用运行时的效率,我们的方法会转换为一层在Native(JNI)上实现的逻辑,最终通过JNI编译成so,这样的话在本地执行,而不是在虚拟机执行,执行效率会大大提升。

    DEX内存加载实现原理

    框架原理

    Android加壳框架原理为Proxy/Delegate Application,即使用自定义的代理Application类作为程序入口(修改AndroidManifest.xml),在代理Application中完成壳的解密操作,最后启动原来的Application

    ProxyApplication:框架会提供一个ProxyApplication抽象基类(abstract class),使用者需要继承这个类,并重载initProxyApplication()方法,在其中改变surrounding,如替换ClassLoader等
    DelegateApplication:即应用原有的Application,应用从getApplicationContext()等方法中取到的都是DelegateApplication

    修改入口

    将Manifest中application改为ProxyApplication

    代理Application

    在ProxyApplication中实现如下内容

    • 内存加载DEX:加载原Application
    • ClassLoader设置
    • Application引用替换

    壳启动流程

    • 内存加载DEX文件:通过Dalvik、ART虚拟机JNI接口内存加载被加密隐藏的DEX文件
    • 设置ClassLoader:将DEX文件内存加载产生的mCookie放入ClassLoader中(MutiDex)
    • 加载原Application:基于替换后的ClassLoader查找原始Application类并生成实例
    • Application还原:将API层的所有Application引用替换为原始Application
    展开全文
  • 阿里第一代 android dex加固的脱壳方法-附件资源
  • Dex加固总结之腾讯加固

    千次阅读 2015-11-02 16:01:33
    Dex加固总结之腾讯加固【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!由于dex脱壳的文章很多,讲原理的文章也到处都是,所以我就不抛砖头误导大家了。快到2016年了,时隔一年,来总结一下这些...

    Dex加固总结之腾讯加固

    【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

    由于dex脱壳的文章很多,讲原理的文章也到处都是,所以我就不抛砖头误导大家了。快到2016年了,时隔一年,来总结一下这些加固厂商的手法。

    1.加固前后文件对比,左边为原包

    这里写图片描述

    2.脱壳后类名结构

    这里写图片描述
    tencent.StubShell主要是用来执行腾讯的逻辑代码。

    3.使得反编译工具失败

    插入一个A001类,导致反编译Smali失败
    这里写图片描述
    图一
    这里写图片描述
    图二
    能看到这些的话,腾讯App加固脱壳就完成了。

    Game Over
    ―――――――――――――――――――――――――――――――――
    2015.11.02
    By Ericky

    展开全文
  • 这篇文章介绍一下自己学习dex加固的过程。虽然市面上比这篇文章介绍的技术要先进的多了,但还是从基础抓起吧。而且这种最简单的加固实践起来也遇到好多坑,一开始看reference里的文章真是云里雾里,所以记录一下以免...

    66b52468c121889b900d4956032f1009.png

    8种机械键盘轴体对比

    本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

    这篇文章介绍一下自己学习dex加固的过程。虽然市面上比这篇文章介绍的技术要先进的多了,但还是从基础抓起吧。而且这种最简单的加固实践起来也遇到好多坑,一开始看reference里的文章真是云里雾里,所以记录一下以免以后忘了思想。

    代码见github。

    原理

    1460186676854.png

    我们在加固的过程中需要三个对象:需要加密的Apk(源Apk)

    壳程序Apk(负责解密Apk工作)

    加密工具(将源Apk进行加密和壳Dex合并成新的Dex)解释一下,熟悉android的朋友们都知道。运行android程序后会有一个class.dex文件。它的格式我就不多说了。我们本身有一个source Apk,是我们需要进行加密的Apk。然后我们有一个解壳apk,它负责进行解密,还有一个进行加密的java程序,它负责对apk进行加密。

    加密java程序工作过程:也就是上面那张图。其实这里有种A要B,B要A的循环过程,所以比较难以理解。现在假设我们已经有了解壳apk的class.dex文件了。那么我们把source apk进行加密后,附在解壳dex的后面,这样就形成新的dex了。

    解壳apk工作过程:我们先假设解壳apk的class.dex已经是加固过的dex了,解壳Apk就从这个dex去读取加过密的source apk,然后进行解密,再进行运行。所以,我们最终真正运行的是解壳apk。

    理一下全部过程:

    ①编写source apk

    ②编写解壳apk,假设自己的class.dex已经是加固过的dex。

    ③编写加密java程序过程,把解壳dex和source apk进行整合,得到新的class.dex文件。

    ④关键步骤,幸亏看了reference的文章才知道。跪谢大神们。应该把解壳apk变成.zip文件,再替换里面的class.dex,再重打包重签名。一开始傻逼的我以为替换掉后在eclipse再运行就可,然而这会重新生成class.dex,因此总是找不到source apk。

    过程

    截图来自于Reference<1>。

    source apk

    1460187837027.png

    加密java程序

    1460187936132.png

    这里脱壳程序的dex文件,就是解壳dex,作者改了个名而已。

    class.dex是运行java程序后自动生成的文件。1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41public static void (String[] args){

    try {

    File payloadSrcFile = new File("force/ForceApkObj.apk"); //需要加壳的程序

    System.out.println("apk size:"+payloadSrcFile.length());

    File unShellDexFile = new File("force/ForceApkObj.dex");//解客dex

    byte[] payloadArray = encrpt(readFileBytes(payloadSrcFile));//以二进制形式读出apk,并进行加密处理//对源Apk进行加密操作

    byte[] unShellDexArray = readFileBytes(unShellDexFile);//以二进制形式读出dex

    int payloadLen = payloadArray.length;

    int unShellDexLen = unShellDexArray.length;

    int totalLen = payloadLen + unShellDexLen +4;//多出4字节是存放长度的。

    byte[] newdex = new byte[totalLen]; // 申请了新的长度

    //添加解壳代码

    System.arraycopy(unShellDexArray, 0, newdex, 0, unShellDexLen);//先拷贝dex内容

    //添加加密后的解壳数据

    System.arraycopy(payloadArray, 0, newdex, unShellDexLen, payloadLen);//再在dex内容后面拷贝apk的内容

    //添加解壳数据长度

    System.arraycopy(intToByte(payloadLen), 0, newdex, totalLen-4, 4);//最后4为长度

    //修改DEX file size文件头

    fixFileSizeHeader(newdex);

    //修改DEX SHA1 文件头

    fixSHA1Header(newdex);

    //修改DEX CheckSum文件头

    fixCheckSumHeader(newdex);

    String str = "force/classes.dex";

    File file = new File(str);

    if (!file.exists()) {

    file.createNewFile();

    }

    FileOutputStream localFileOutputStream = new FileOutputStream(str);

    localFileOutputStream.write(newdex);

    localFileOutputStream.flush();

    localFileOutputStream.close();

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    上面的程序很好的体现了下图:

    1460188585849.png

    最后多了四个字节用来存放source dex长度。1

    2

    3

    4

    5

    6

    7

    8public static byte[] intToByte(int number) {

    byte[] b = new byte[4];

    for (int i = 3; i >= 0; i--) {

    b[i] = (byte) (number % 256);

    number >>= 8;

    }

    return b;

    }

    这个是将int转化为byte[4]数组,因为int是32位,每八位换成一个byte。

    更改头部

    更改filesize。1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12private static void fixFileSizeHeader(byte[] dexBytes){

    //新文件长度

    byte[] newfs = intToByte(dexBytes.length);

    System.out.println(Integer.toHexString(dexBytes.length));

    byte[] refs = new byte[4];

    //高位在前,低位在前掉个个--->因为小端格式

    for (int i = 0; i < 4; i++) {

    refs[i] = newfs[newfs.length - 1 - i];

    System.out.println(Integer.toHexString(newfs[i]));

    }

    System.arraycopy(refs, 0, dexBytes, 32, 4);//修改(32-35)

    }

    解壳apk

    1460193831891.png

    RefInvoke.java是封装反射类工具Android程序由不同的组件构成,系统在有需要的时候启动程序组件。因此解壳程序必须在Android系统启动组件之前运行,完成对解壳数据的解壳及APK文件的动态加载,否则会使程序出现加载类失败的异常。Android开发者都知道Applicaiton做为整个应用的上下文,会被系统第一时间调用,这也是应用开发者程序代码的第一执行点。因此通过对AndroidMainfest.xml的application的配置可以实现解壳代码第一时间运行。

    我们需要找到一个时机,就是在脱壳程序还没有运行起来的时候,来加载源程序的Apk,执行他的onCreate方法,那么这个时机不能太晚,不然的话,就是运行脱壳程序,而不是源程序了。查看源码我们知道。Application中有一个方法:attachBaseContext这个方法,他在Application的onCreate方法执行前就会执行了,那么我们的工作就需要在这里进行。

    当在AndroidMainfest.xml文件配置为解壳代码的Application时。源程序原有的Applicaiton将被替换,为了不影响源程序代码逻辑,我们需要在解壳代码运行完成后,替换回源程序原有的Application对象。我们通过在AndroidMainfest.xml文件中配置原有Applicaiton类信息来达到我们 的目的。解壳程序要在运行完毕后通过创建配置的Application对象,并通过反射修改回原Application。1

    在attachBaseContext中,解壳apk1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56//这是context 赋值

    protected void attachBaseContext(Context base){

    super.attachBaseContext(base);

    try {

    //创建两个文件夹payload_odex,payload_lib 私有的,可写的文件目录

    File odex = this.getDir("payload_odex", MODE_PRIVATE);

    File libs = this.getDir("payload_lib", MODE_PRIVATE);

    odexPath = odex.getAbsolutePath();

    libPath = libs.getAbsolutePath();

    apkFileName = odex.getAbsolutePath() + "/payload.apk";

    File dexFile = new File(apkFileName);

    Log.i("demo", "apk size:"+dexFile.length());

    if (!dexFile.exists())

    {

    dexFile.createNewFile(); //在payload_odex文件夹内,创建payload.apk

    // 读取程序classes.dex文件

    byte[] dexdata = this.readDexFileFromApk();

    // 分离出解壳后的apk文件已用于动态加载

    this.splitPayLoadFromDex(dexdata);

    }

    // 配置动态加载环境

    Object currentActivityThread = RefInvoke.invokeStaticMethod(

    "android.app.ActivityThread", "currentActivityThread",

    new Class[] {}, new Object[] {});//获取主线程对象 http://blog.csdn.net/myarrow/article/details/14223493

    String packageName = this.getPackageName();//当前apk的包名

    //下面两句不是太理解

    ArrayMap mPackages = (ArrayMap) RefInvoke.getFieldOjbect(

    "android.app.ActivityThread", currentActivityThread,

    "mPackages");

    WeakReference wr = (WeakReference) mPackages.get(packageName);

    //创建被加壳apk的DexClassLoader对象 加载apk内的类和本地代码(c/c++代码)

    DexClassLoader dLoader = new DexClassLoader(apkFileName, odexPath,

    libPath, (ClassLoader) RefInvoke.getFieldOjbect(

    "android.app.LoadedApk", wr.get(), "mClassLoader"));

    //base.getClassLoader(); 是不是就等同于 (ClassLoader) RefInvoke.getFieldOjbect()? 有空验证下//?

    //把当前进程的DexClassLoader 设置成了被加壳apk的DexClassLoader ----有点c++中进程环境的意思~~

    RefInvoke.setFieldOjbect("android.app.LoadedApk", "mClassLoader",

    wr.get(), dLoader);

    Log.i("demo","classloader:"+dLoader);

    try{

    Object actObj = dLoader.loadClass("com.example.forceapkobj.MainActivity");

    Log.i("demo", "actObj:"+actObj);

    }catch(Exception e){

    Log.i("demo", "activity:"+Log.getStackTraceString(e));

    }

    } catch (Exception e) {

    Log.i("demo", "error:"+Log.getStackTraceString(e));

    e.printStackTrace();

    }

    }

    通过反射置换android.app.ActivityThread 中的mClassLoader为加载解密出APK的DexClassLoader,该DexClassLoader一方面加载了源程序、另一方面以原mClassLoader为父节点,这就保证了即加载了源程序又没有放弃原先加载的资源与系统代码。

    ZipInputStream 类

    ZipInputStream是InputStream的子类,通过此类可以方便地读取ZIP格式的压缩文件,使用ZipInputStream可以像ZipFile一样取得ZIP压缩文件中的每一个ZipEntry。1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17package org.lxh.demo12.zipdemo;

    import java.io.File;

    import java.io.FileInputStream;

    import java.util.zip.ZipEntry;

    import java.util.zip.ZipInputStream;

    public class ZipInputStreamDemo01 {

    public static void main(String[] args) throws Exception { //所有异常抛出

    File zipFile = new File("d:" + File.separator + "mldn.zip");

    ZipInputStream input = null; // 定义压缩输入流

    input = new ZipInputStream(new FileInputStream(zipFile)); // 实例化压缩输入流

    ZipEntry entry = input.getNextEntry(); // 得到一个压缩实体

    System.out.println("压缩实体名称:" + entry.getName()) ;

    // 输出实体名称

    input.close();

    // 关闭压缩输入流

    }

    }

    Reference

    展开全文
  • 常见的非代码抽取的dex加固,可以通过修改或者hook源码中的dex解析函数拿到目标dex完成脱壳。该dex解析函数为DexFile* dexFileParse(const u1* data, size_t length, int flags),位于src4.4.4_r1/dalvik/libdex/Dex...

    常见的非代码抽取的dex加固,可以通过修改或者hook源码中的dex解析函数拿到目标dex完成脱壳。该dex解析函数为DexFile* dexFileParse(const u1* data, size_t length, int flags),位于src4.4.4_r1/dalvik/libdex/DexFile.cpp文件。

    1.修改源码,编译系统,实现脱壳,使用该方法的代表工具--“DexExtractor”。对其的介绍和使用教程见一大牛博客:

    http://www.wjdiankong.cn/apk%E8%84%B1%E5%A3%B3%E5%9C%A3%E6%88%98%E4%B9%8B-%E5%A6%82%E4%BD%95%E8%84%B1%E6%8E%89%E6%A2%86%E6%A2%86%E5%8A%A0%E5%9B%BA%E7%9A%84%E4%BF%9D%E6%8A%A4%E5%A3%B3/

    2.利用Cydia Substrate 框架hook dexFileParse函数,完成脱壳。以下为详细的步骤:

    http://wps2015.org/drops/drops/Android.Hook%E6%A1%86%E6%9E%B6Cydia%E7%AF%87(%E8%84%B1%E5%A3%B3%E6%9C%BA%E5%88%B6%E4%BD%9C).html

    转载于:https://www.cnblogs.com/xunbu7/p/7065054.html

    展开全文
  • Dex加固与反编译

    2020-01-31 23:32:18
    DEX文件转换为jar包或者Smali文件 将二进制资源文件还原为资源源码文件 编译与反编译是相对的过程,转换过程分别由编译器和反编译器实现。 反编译工具 ApkTool dex2jar jd-gui ApkTool 反编译Dex为sm...
  • 我们让程序运行起来,在Dalivk开始加载解密后的dex文件时,把dex文件从内存中dump下来即可。 根据android源码知道,Dalivk在加载dex文件时用到方法 int dvmDexFileOpenPartial(const void* addr, int len, ...
  • 一、前 言Android Apk加固的发展已经有一段时间了,相对来说本篇博客要记录的Android加壳的实现思路是4年的东西了,已经被老鸟玩烂了,Android加固的安全厂商也不会采用这么粗犷的方式来进行Android Apk的加固处理。...
  • 当然,加固还有资源保护等其它处理,但我这里主要讨论的是dex加固。 在阅读以下内容前,你需要对dex结构有一定了解,但不需要太全面,也不用了解字节码保存方式和指令功能。首先,要知道dex的头部结构,以及它重要的...
  • js转dex加密加固,autojs防止破解的终极方案

    千次阅读 热门讨论 2020-06-21 13:46:49
    js转dex加密加固,autojs防止破解的终极方案 首先我们要知道加密加固是为了什么? 加密加固是为了防止自己的脚本被别人破解,损害自己的利益。
  • 什么是Dex文件?classes.dex是apk组成的一部分,包含了能被Dalvik/Art理解的可执行文件,类似Windows的exe文件;APK组成:1. assets目录:存放assets目录下的文件,可以通过AssetManager对象获取2. lib目录:存放所...
  • 简介: APK 加固 dex 加密,解密 更多:作者提 Bug 标签: 12068548497-nkchilds@gmail.com- 现在随意在应用市场下载一个 APK 文件然后反编译,95% 以上基本上都是经过混淆,加密,或第三方加...
  • 现在随意在应用市场下载一个 APK 文件然后反编译,95% 以上基本上都是经过混淆,加密,或第三方加固(第三方加固也是这个原理),那么今天我们就对 Dex 来进行加密解密。让反编译无法正常阅读项目源码。
  • 360加固保的dex脱壳方法

    万次阅读 热门讨论 2016-11-13 15:41:40
    360整体加固classes.dex后的apk程序的特点,以超信1.1.4版本为例。360加固以后,会在apk的assets文件的路径下增加两个文件libjiagu.so和libjiagu_x86.so以及修改原apk的AndroidManifest.xml文件的application标签...
  • apk加固原理之dex加密

    千次阅读 2017-07-17 09:54:48
    apk加固原理之dex加密 原理其实不复杂,加固其实就是加密dex文件,防止dex专程jar 被阅读。后面才是热部署解密dex; 代码如下,注释有解释: import android.os.Environment; import android.support.v7.app....
  • 梆梆加固还原DEX文件

    2017-12-28 11:13:00
    0x01  先说总结:  参照https://www.cnblogs.com/jiaoxiake/p/6818786.html 最后说的步骤, ...  通过DexExtractor将加固后的apk还原odex,拖到jeb里面继续分析,odex-dex步骤没完成。 0x02...
  • apk加固插件 带签名校验、dex加密、资源混淆
  • 首先声明,只针对 Android 8.1 后... 到这里dex 加固基本告一段落。后面的安全问题其实就是 so 问题,这个基本搞java 没办法 搞,后面整理了再发出来; 这里只是展示 思路,可能并不能直接拿来用,见谅; demo 原码:
  • Android APK 加固之动态加载dex(一)

    千次阅读 2019-05-04 11:37:25
    Android APK 加固之动态加载dex(一)前情1.类加载器制作dex文件 前情 最近正在学习Android 安全,为了巩固知识,我会在博客上把Android加固这一方面由浅入深全部总结出来,一直到在内存中加载dex结束。 1.类加载器 ...
  • Android应用的源代码主要分为java与C/C++两部分,其中...在顶象技术的 Android 加固解决方案中,有着DEX 壳保护、指令虚拟化(将DEX文件运行在自实现的虚拟机环境下)等技术。要想了解顶象技术的Android 加固解决方...
  • 1.Dex文件优化与验证: 把dex文件转化为odex的过程,填补一些加载依赖的类。这里存在一代脱壳时机点,比如早期的爱加密在dvmdexfileopen函数下断点。 2.Dex文件解析: 将优化后得dex文件(也就是odex文件)通过mmap...
  • 1.用于动态加载的dex可以放在sdcard中进行加载,但是为了安全起见还是觉得放在asset中, 加载之前把dex复制到app的data空间中更好。 String copyDex(String dexName) { AssetManager as = getAssets(); String ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 500
精华内容 200
关键字:

dex加固