高效IO之Dex加密(三)

apk提取加密素材_高效IO之Dex加密(三) 更多Android高级架构进阶视频免费学习请点击:哔哩哔哩 ( ゜- ゜)つロ 乾杯~ Bilibili​space.bilibili.comapk加固原理之dex加密原理其实不复杂,加固其实就是加密dex文件,防止dex专程jar 被阅读。后面才是热部署解密dex;一、加密和解密方案既然我们已经弄清了apk是如何打包的,那么将加密流程加到整个打包流程就相对清晰了。如下图什么?还是不懂呢?那来看看... 阅读详情

更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680

apk加固原理之dex加密

原理其实不复杂,加固其实就是加密dex文件,防止dex专程jar 被阅读。后面才是热部署解密dex;

一、加密和解密方案

既然我们已经弄清了apk是如何打包的,那么将加密流程加到整个打包流程就相对清晰了。如下图


19956127-6b914617cd543b28.png

什么?还是不懂呢?那来看看我们整个加密和解密方案呢?


19956127-5ee5bb2c57eefe4d.png

我们的思路如下:

既然我们要加密,那么必然有解密,但是这个解密又必然是整个应用的一部分,但是连这部分都加密的话,那么系统就完全无法解析我们的应用,也就是完全无法安装了。所以我们需要将解密的部分提取出来单独作为一个module,且这个module是不能够被加密的。然后最好的解密时机就是首次启动应用的时候进行,所以Application自然成了我们负责解密的首选。那么是否意味着原apk中不能有这个module呢?答案是:错啦。原apk中同样要将这个解密module打包进去,否则原apk也无法编译通过啊。
我们都知道,系统在加载类的时候都是从我们apk的dex文件中加载的。ClassLoader会去维护一个这样的dex文件数组(这个在前面的热修复章节有介绍过)。而我们要做的就是将原apk中的dex都加密,然后将解密部分的代码单独编程成dex文件(我们称这样的dex为壳dex)连带着加密的dex一起加到新apk中。这样新apk安装后系统就能够找到我们应用启动的入口Application了,不至于由于加密导致系统找不到应用程序入口。而在这个程序入口中我们要做的就是解密被加密的dex文件,然后重新插入到ClassLoader维护的dex文件数组中(这里就涉及到大量的反射知识)。
三、加密实现
方案说了那么多,到底如何实现呢?实现后到底能不能像我们说的那样正常安装运行呢?撸代码来验证!

先来看看我们加密工程未运行前的结构图


19956127-b06dd5a5e705687d.png

再来看看工程运行后,工程结构的变化


19956127-b00a5ecf1ba02193.png

可以看到运行后原apk被加密和解密模块被放到一起重新打包成了新的apk。这个过程代码如何实现呢?

1、既然要加密,必然要选择加密方式,初始化加密算法

    //这里我们选择已封装好的Cipher加密。
    public static final String DEFAULT_PWD = "abcdefghijklmnop";//加密和解密的key要一致,所以解密模块的key也要是同样的。
    private static final String algorithmStr = "AES/ECB/PKCS5Padding";
    private static Cipher encryptCipher;//用来的加密的Cipher实例
    private static Cipher decryptCipher;//用来解密的Cipher实例
    /**
     *  初始化加密算法
     * @param password  这里的password对应DEFAULT_PWD
     */
    public static void init(String password) {
        try {
            // 生成一个实现指定转换的 Cipher 对象。
            encryptCipher = Cipher.getInstance(algorithmStr);
            decryptCipher = Cipher.getInstance(algorithmStr);// algorithmStr
            byte[] keyStr = password.getBytes();
            SecretKeySpec key = new SecretKeySpec(keyStr, "AES");
            encryptCipher.init(Cipher.ENCRYPT_MODE, key);
            decryptCipher.init(Cipher.DECRYPT_MODE, key);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
    }

2、加密之前我们需要先创建两个目录用来存放原apk和解密模块压缩出来的源文件

                /**
             * 分别在apk和aar目录下生成两个temp目录用来存放加密的未打包的apk文件
             */
            File apkTemp = new File("source/apk/temp");
            if(apkTemp.exists()) {
                File[] files = apkTemp.listFiles();
                for(File file:files) {
                    if(file.exists()) {
                        file.delete();
                    }
                }
            }
            File aarTemp = new File("source/aar/temp");
            if(aarTemp.exists()) {
                File[] files = aarTemp.listFiles();
                for(File file:files) {
                    if(file.exists()) {
                        file.delete();
                    }
                }
            }

3、解压原apk,并加密原apk中的dex文件。

        /**    
          * 解压原apk文件到apk/temp目录下,并加密dex文件
          */
         File sourceApk = new File("source/apk/app-debug.apk");
            File newApkDir = new File(sourceApk.getParent() + File.separator + "temp");
            if(!newApkDir.exists()) {
                newApkDir.mkdirs();
            }
          //解压原apk,加密dex
            AESUtil.encryptAPKFile(sourceApk,newApkDir);
            if (newApkDir.isDirectory()) {
                File[] listFiles = newApkDir.listFiles();
                for (File file : listFiles) {
                    if (file.isFile()) {
                        //修改classes.dex名为classes_.dex,避免等会与aar中的classes.dex重名
                        if (file.getName().endsWith(".dex")) {
                            String name = file.getName();
                            int cursor = name.indexOf(".dex");
                            String newName = file.getParent()+ File.separator + 
                                    name.substring(0, cursor) + "_" + ".dex";
                            file.renameTo(new File(newName));
                        }
                    }
                }
            }

什么?没看到解压和加密的核心代码?传送门在这里,自己去看。

4、解压aar文件,并生成壳dex

先解压aar文件,再利用dx工具将解压出来的classes.jar文件转换成壳dex,并拷贝到新apk的源目录下

            /**
             * 解压aar文件(不能进行加密的部分),再利用dx将jar转换成dex,并将dex文件拷贝到apk/temp中来
             */
            File aarFile = new File("source/aar/mylibrary-debug.aar");
             File sourceAarDex = null;
            try {
            //解压aar文件,并通过dx工具将jar文件转换成dex文件
                sourceAarDex  = DxUtil.jar2Dex(aarFile);
            }catch(Exception e){
                e.printStackTrace();
            }
 
            File copyAarDex = new File(newApkDir.getPath() + File.separator + "classes.dex");
            if (!copyAarDex.exists()) {
                copyAarDex.createNewFile();
        }
            //拷贝aar/temp中的classes.dex到apk/temp中
            FileOutputStream fos = new FileOutputStream(copyAarDex);
            byte[] fbytes = ByteUtil.getBytes(sourceAarDex);
            fos.write(fbytes);
            fos.flush();
            fos.close();

想看如何通过dx工具将jar转换成dex的核心代码?

 public static void dxCommand(File aarDex, File classes_jar) throws IOException, InterruptedException {
            Runtime runtime = Runtime.getRuntime();
            //这里需要注意,commond中dx需要配置环境变量后才可以这样写,否则需要指定dx.bat的绝对路径
            String commond = "cmd.exe /C dx --dex --output=" + aarDex.getAbsolutePath() + " " +classes_jar.getAbsolutePath();
            Process process = runtime.exec(commond);
            System.out.println("runtime  dxCommand");
             process.waitFor();
             System.out.println("waitFor  dxCommand");
            } catch (InterruptedException e) {
               System.out.println("InterruptedException  dxCommand");
                e.printStackTrace();
                throw e;
            }
            if (process.exitValue() != 0) {
                 System.out.println("getErrorStream  dxCommand");
                InputStream inputStream = process.getErrorStream();
                int len;
                byte[] buffer = new byte[2048];
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                while((len=inputStream.read(buffer)) != -1){
                    bos.write(buffer,0,len);
                }
                    //输出出错信息
                System.out.println(new String(bos.toByteArray(),"GBK"));
                throw new RuntimeException("dx run failed");
            }
            process.destroy();
        }

5、一切就绪,打包apk/temp目录生成新的未签名apk文件

 File unsignedApk = new File("result/apk-unsigned.apk");
 unsignedApk.getParentFile().mkdirs();
 ZipUtil.zip(newApkDir, unsignedApk);

6、给加密后组合压缩成的新apk文件重新签名

File signedApk = new File("result/apk-signed.apk");
SignatureUtil.signature(unsignedApk, signedApk);

我们继续看看这个签名是个什么黑科技:

/**
     * 为加密后的apk文件添加签名
     * @param unsignedApk
     * @param signedApk
     * @throws InterruptedException
     * @throws IOException
     */
       public static void signature(File unsignedApk, File signedApk) throws InterruptedException, IOException {
            String cmd[] = {"cmd.exe", "/C","jarsigner",  "-sigalg", "MD5withRSA",
                    "-digestalg", "SHA1",
                    "-keystore", "C:/Users/cizongfa/.android/debug.keystore",
                    "-storepass", "android",
                    "-keypass", "android",
                    "-signedjar", signedApk.getAbsolutePath(),
                    unsignedApk.getAbsolutePath(),
                    "androiddebugkey"};
            Process process = Runtime.getRuntime().exec(cmd);
            System.out.println("start sign");
            try {
                int waitResult = process.waitFor();
                System.out.println("waitResult: " + waitResult);
            } catch (InterruptedException e) {
                e.printStackTrace();
                throw e;
            }
            System.out.println("process.exitValue() " + process.exitValue() );
            if (process.exitValue() != 0) {
                InputStream inputStream = process.getErrorStream();
                int len;
                byte[] buffer = new byte[2048];
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                while((len=inputStream.read(buffer)) != -1){
                    bos.write(buffer,0,len);
                }
                System.out.println(new String(bos.toByteArray(),"GBK"));
                throw new RuntimeException("签名执行失败");
            }
            System.out.println("finish signed");
            process.destroy();
        }

更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680

原文链接:https://blog.youkuaiyun.com/LVEfrist/article/details/101061370

IO操作Dex文件加密,APK加固项目实战 (1) 加密阶段(2)合成新的dex文件(3)修改原apk文件并重打包签名(4)运行壳程序加载原dex文件。 阅读详情

相关推荐

IO操作Dex文件加密,APK加固项目实战,Android开发必须会的技能

在这一阶段,我们首先将apk解压,会看到如下图的6个文件和目录。其中,我们需要修改的只有2个文件,分别是classes.dex和AndroidManifest.xml文件,其他文件和文件加都不需要改动。首先,我们把解压后apk目录下原来的classes.dex文件替换成我们在0x02上一步合成的新的classes.dex文件。然后,由于我们程序运行的时候,首先加载的其实是壳程序里的ProxyApplication类。

2401_84149256的博客 1267

【Android 逆向】脱壳解决方案 ( DEX 整体加壳 | 函数抽取加壳 | VMP 加壳 | Dex2C 加壳 | Android 应用加固防护级别 )

一、DEX 整体加壳、 二、函数抽取加壳、 三、VMP 加壳、 四、Dex2C 加壳、 五、Android 应用加固防护级别、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 8451

IO操作Dex文件加密,APK加固项目实战(2),2024年上半年最接地气的Android面经

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

2401_84149220的博客 1034

使用 Dex2C 加壳保护 Android APK 代码

因为 jarsigner 只能生成老的 v1 签名,apksigner 支持 v1/v2/v3/v4 新版签名,才能确保 APK 在 Android 7.0 及以上系统正常、安全安装。首先在 app 代码合适的位置,如 Application 的静态代码块或 onCreate 等,添加加载 so 库代码,并重新生成 apk。project-source.zip 是个 jni 工程,里面包含我们编译出来的 C 代码,解压出来后可以直接使用 ndk 编译。

1604

安卓APK加固实战:基于IO流操作的Dex文件加密与动态加载方案

在移动应用开发中,代码保护是保障应用安全与知识产权的核心环节。其基本原理在于通过技术手段防止核心逻辑被轻易逆向分析。从技术价值看,有效的代码保护能直接抵御外挂、破解和山寨应用,维护开发者收益。常见的应用场景包括金融、游戏等高价值应用的安全加固。其中,Dex文件作为安卓应用的代码载体,其保护尤为关键。本文聚焦于通过自定义IO流操作对Dex文件进行AES加密,并设计外壳程序实现运行时动态解密与加载。该方案能有效应对静态分析,并结合密钥管理、反调试等策略,为安卓应用提供一套可落地的自制加固方案,兼顾安全性与工程实

weixin_33796177的博客 366

2024年IO操作Dex文件加密,APK加固项目实战(1),面试一路绿灯Offer拿到手软

我坚信,坚持学习,每天进步一点,滴水穿石,我们离成功都很近!以下是总结出来的字节经典面试题目,包含:计算机网络,Kotlin,数据结构与算法,Framework源码,微信小程序,NDK音视频开发,计算机网络等。字节高级Android经典面试题和答案网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取一个人可以走的很快,但一群人才能走的更远!

2401_84538135的博客 1350

dex2c:项目的核心功能/场景

dex2c:项目的核心功能/场景 dex2c 是一款基于方法调用的 AOT(Ahead-Of-Time)编译器,它能够将 Dalvik 字节码与 JNI(Java Native Interface)本地代码进行封装。此工具旨在为 Android 应用提供一种新的保护机制,通过将关键代码转换为本地代码,从而提高应用的运行效率和安全性。 项目介绍 dex2c 项目是基于 amimo/dcc 的分支版本...

gitblog_00403的博客 771

Android dex文件通用自动脱壳器

标 题: 【原创】Android dex文件通用自动脱壳器 作 者: zyqqyz 时 间: 2015-09-01,13:03:30 链 接: http://bbs.pediy.com/showthread.php?t=203776 之前做了一个Android dex的通用脱壳器,主要思想是以AOP的模式对运行时ART和DVM进行定制,附件中是在HITCON上演讲的ppt。 源码地址:https://github.com/zyq8709/DexHunter 代码较挫,大家可以看看,有兴趣的可以继续在上边改一改:)。 github上有一段demo视频和相关的样本,大家有兴趣也可以试试。 测试了国内主流的6款在线加固服务,可以正常脱下来。有其他的样本的也可以试试,发现问题的话请联系我。 为了方便大家阅读,我把对运行时的关键修改摘了出来。class_linker.txt 是对ART的修改,dalvik_system_DexFile.txt是对DVM的修改。 demo视频下载:http://pan.baidu.com/s/1o6Mjwim 密码:x1ay 因为那个视频是H264编码的MP4,所以可能比较挑播放器,大家可以换着试试,比如kmplayer等。 我传了一份到优酷,视频地址:http://v.youku.com/v_show/id_XMTMyNDc4OTQwMA==.html*转载请注明来自看雪论坛@PEdiy.com

安卓加密壳(dexcrypt) , 防止apktool,dex2jar 等工具逆向你的apk,附上下载地址

工具支持 apk 一键自动加密,dex2jar 与 apktool 都不能正常解密出代码,但是还是无法防御 IDA 的反汇编,不过已经足够了,压缩包超过1M,使用百度网盘进行下载比较快些。 测试过的程序: 拉卡拉 3.0.2 龙斗士 2.2.2 ... 如果工具不支持加壳你的程序,可以邮件给我! 软件界面如下: 2013-10-11      国庆了

六桥风月IT随笔 2845

【Android 安全】DEX 加密_2021_04_05.zip

Android dex 加密 , Android 安全 专栏 https://blog.youkuaiyun.com/han1202012/category_10559800.html 博客源码快照

告别臃肿VS!仅用Visual Studio 2022 Build Tools为Qt 5.12.12配置MSVC2017开发环境

本文详细介绍了如何仅使用Visual Studio 2022 Build Tools为Qt 5.12.12配置MSVC2017开发环境,避免安装臃肿的完整VS。通过精准选择组件、配置Qt Creator编译器和优化Kit设置,实现高效、精简的Windows平台Qt开发环境搭建,特别适合追求性能和资源优化的开发者。

weixin_30340617的博客 352

【Android 安全】DEX 加密 ( Java 工具开发 | 解压 apk 文件 | 加密生成 dex 文件 | 打包未签名 apk 文件 | 文件解压缩相关代码 )

一、解压 apk 文件、 二、加密生成 dex 文件、 三、打包未签名 apk 文件、 四、完整代码示例、 五、文件解压缩相关代码、 六、执行结果

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 3324

python:numpy分享(保姆级教程)

创建数组:array和ndarray、rand()、randn()、arange()、randint()、uniform()astype()基础函数:ceil()、floor()、rint()、argmax()、argmin()、cumsum()、cumprod()numpy 是数据分析必不可少的第三方库,具有高性能的特点,多用于做数组分析。内置函数:ceil()、floor()、rint()主要用于数组计算,支持多维数组。array和ndarray。比较函数:all、any。去重函数:unique。

sulin123123的博客 1733

Android IO、序列化、dex加密

IO 原理:实际是调用系统内核的函数库,进行数据同步后,由内核将数据写入磁盘; 页 4K数据为一页,一页数据是IO操作的基本单位; 在空间局部性原理下,为了优化,如果数据量较大的情况下,可能会出现预占位4~16K的情况;实际还没写数据,只是提前先多开辟空间,减少了多次开辟空间的操作; 基础IO FileInputSteam inputSteam/FileOutSteam outSteam: 并没有实现inputSteam.flush(), 实际每次调用inputSteam.write()都

qq_32506429的博客 1491

B站李沐讲论文笔记AlexNet

B站李沐讲论文笔记AlexNet

夏知识不进脑子薇的博客 790

嵌入式系统开发笔记112:通过有人云测试MQTT

项目中使用到“有人”公司的WH-LTE-7S0模块,本文讲解通过有人云进行MQTT测试的方法。

snmplink的博客 999

JavaIO 实战 —— dex 文件加密

上一篇文章介绍了 IO 的基础知识,本节我们来举一个 IO 的应用实例——Dex 文件加密。当然,通常情况下我们是使用 Gradle 进行 Dex 加密的,这里使用 IO 权当是练手了。

tmacfrank 1331

通过 MATLAB/Simulink + Simscape Battery,构建了锂电池老化模型与容量衰减仿真系统

本文基于MATLAB/Simulink平台,构建锂电池老化模型与容量衰减仿真系统,研究储能电池健康管理技术。通过搭建电化学-老化耦合模型,模拟循环和日历老化机制,分析温度、充放电倍率、DOD等因素对电池寿命的影响。系统实现了SOH在线估计和RUL预测功能,仿真了标准日历老化、高倍率循环和峰谷套利等典型工况下的电池衰减行为。结果表明:高温和深充放会显著加速电池老化,而精准的SOH管理可提升储能系统经济性30%以上。文章还探讨了数字孪生、机器学习等高级优化方向,为储能系统长周期运营提供技术支撑。

xiaoheshang_123的博客 400

IO操作Dex文件加密,APK加固示例

通过上面的示例,我们实现了Dex文件的加密与解密,并在应用启动时动态加载加密的Dex文件。通过代码混淆和资源文件加密,我们可以进一步提升APK的安全性。这些措施可以有效地保护应用程序不被逆向工程和破解。

qq_34358193的博客 831

OpenStack [ compute_id ] 设计上的小缺陷

而 nova 代码中硬编码(或默认配置)将 compute_id 放在 site-packages 目录,属于 设计上的小缺陷—— 把 “库安装目录” 和 “运行时数据目录” 混在一起了,才导致需要临时调整这个目录的权限。# 配置项说明:node_identity_file 是 nova 用于指定节点标识文件路径的官方配置项,优先级高于代码中的默认路径。自定义 compute_id 路径,指向 /var/lib/nova/ 目录下的 compute_id 文件;

求知若渴,虚心若愚。 491

dolphinscheduler-3.4.0

dolphinscheduler集群部署

docsz的博客 661

【31】File IO 项目实战—dex文件改造

(1)一个人只要自己不放弃自己,整个世界也不会放弃你. (2)天生我才必有大用 (3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟. (4)做难事必有所得 (5)精神乃真正的刀锋 (6)战胜对手有两次,第一次在内心中. (7)好好活就是做有意义的事情. (8)亡羊补牢,为时未晚 (9)科技领域,没有捷径与投机取巧。 (10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。 (11)基础不牢,地动天摇 (12)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~ .

青风百草 483

基于 STM32 的智慧图书馆智能控制系统设计与实现

智慧图书馆智能控制系统集成环境调控、安全监控、借阅管理与信息推送功能,通过 STM32 主控芯片联动传感器、执行器及云平台,实现图书馆智能化管理。系统架构分为感知层(传感器)、控制层(STM32 主控)、执行层(继电器 / 显示屏)及云端层(数据交互),支持温度自动调节、灯光自控、火情安防监控、天气推送及 RFID 借还书管理。本系统通过 STM32 实现多传感器融合与设备控制,结合 RFID 与云平台技术,构建了集环境智能调控、安全监控、便捷借阅于一体的智慧图书馆解决方案。

weixin_42300449的博客 2210

Android-IO加解密核心与dex文件改造过程分析

1.IO应用加解密核心原理 2.文件加密的意义 3.文件加密与文件混淆 4.初探加密算法 5.dex文件加密与解密 6.APK打包流程与加壳过程 7.APK解包流程与脱壳过程

李木子的博客 1409

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

上一篇: 高效IO之File文件操作类的基础用法(二)
下一篇: 高级UI晋升之触摸事件分发机制(一)
Python_林一
博客等级 码龄7年 889粉丝 510原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值