首页 > 其他分享 >Android各代加固总结

Android各代加固总结

时间:2023-03-14 10:22:30浏览次数:32  
标签:Dex 加密 各代 Apk so 内存 加固 Android 加载

Android软件加固概述

从2012年开始,移动互联网进入快速发展阶段,Android App开发热潮的兴起,也推动了Android平台软件保护技术的发展。

• 为何做加固

  1. 保护核心代码
  2. 防止营销作弊的手段
  3. 防止代码被篡改 ...

加固代际

根据不同的理解,现在加固代际基本上可以按照五代或者三代去区分。

第一代:动态加载类

Apk中没有完整原始的Dex,需要运行时动态的加载到内存中

原理

• 落地加载
我们拿到需要加密的Apk和自己的壳程序Apk,然后用加密算法对源Apk进行加密再将壳Apk进行合并得到新的Dex文件,最后替换壳程序中的dex文件即可,得到新的Apk,那么这个新的Apk我们也叫作脱壳程序Apk.他已经不是一个完整意义上的Apk程序了,他的主要工作是:负责解密源Apk.然后加载Apk,让其正常运行起来。运行时首先将我们的Dex文件或者Apk文件解密,然后利用DexClassLoader加载器将其加载进内存中,然后利用反射加载待加固的Apk的Appkication,然后运行待加固程序即可。

• 不落地加载
落地加载将Dex文件解密出来会保存到文件中,再通过DexClassLoader加载进内存中,而不落地加载直接重写DexClassLoader使其可以直接加载字节数组,避免写入文件中。我们要做的是重写DexClassLoader,而这涉及到三个函数defineClass、findClass、loadClass,在一个类被加载的时候,会先后调用这三个函数加载一个类,所以我们需要重写这三个函数。系统的DexClassLoader加载Dex进入内存的也必然是通过字节加载的,而在系统so中的libdvm.so中的openDexFile可以直接加载Dex文件,那么现在清楚了,我们可以通过编写so文件调用openDexFile函数加载Dex字节数组,值得注意的是,openDexFile函数返回值为一个int类型的cookie,可以简单理解成一个dex文件的'身份码',通过该'身份码'即可操控这个dex文件,至于怎么调用该函数,可以通过dlopen和dlsym函数调用。

优劣

• 优点
比较容易实现,无明显的兼容性问题 能有效对抗静态分析和二次打包

• 缺点
启动时需要进行大量的解密运算,容易造成卡死的情况 在内存中的数据为完整的Dex,通过动态调试Dump内存即可获取完整的Dex

特点


Dex字符串加密 资源加密 对抗反编译 对抗调试 Dex动态加载 so加密

第二代:函数抽取类

原理

主要分为两个步骤指令抽取和指令还原

• 指令抽取
解析原始Dex文件格式,保存所有方法的代码结构体信息,通过传入需要置空指令的方法和类名,检索到其代码结构体信息。通过方法的代码结构体信息获取指令个数和偏移地址,构造空指令集,然后覆盖原始指令,重新计算dex文件的checksum和signature信息,回写到头部信息中。

• 指令还原
native层hook系统函数dexFindClass,获取类结构体信息(dexFindClass函数用于查找类的DexClassDef结构),获取类中所有的方法信息,通过指定方法名进行过滤,获取该方法的代码结构体信息,获取该方法被抽取的指令集,修改方法对应的内存地址为可读属性,直接进行指令还原。

优劣

• 优点
加密粒度变小,加密技术从Dex文件级变为方法级 按需解密,解密操作延迟到某类方法被执行前,如果方法不被执行,则不被解密 解密后的代码在内存不连续,克服了内存被Dump的缺点,有效保护了移动客户端的Java代码

• 缺点
使用大量的虚拟机内部结构,会出现兼容性问题,无法保护所有方法 无法对抗自定义虚拟机 它跟虚拟机的JIT优化出现冲突,达不到最佳的性能表现

特点


除一代有的特点外 内存中无完整、连续的Dex so代码混淆、膨胀

第三代:VMP、Dex2C类

原理

• VMP
执行到关键代码时进入壳so执行,关于这一点,不同的厂商有着不同的做法,比如把关键函数变成native函数,在壳so中动态或者静态注册

再比如更改关键方法的方法体

无论哪种方法其实都是为了能让壳函数代替原函数去执行 当执行该函数的指令时,解析出指令的OpCode,通过一个巨大的switch case找到处理对应OpCode的函数,然后执行

简单讲就是壳将原本的指令进行一次封装,将原本的指令转换为另一种表现形式

• Dex2C
首先也是将关键代码注册为native函数,主要借助于JNI反射技术,将Java层的方法全部反射为native层,增大分析难度。之后再通过混淆、字符串加密等操作生成so,最后将so进行加固保护。

优劣

• 优点
加固强度高,目前没有公开的脱壳工具 经过混淆加密后很难还原原函数

• 缺点
效率较低,启动、运行时都比较耗时稳定性、可控性差,容易产生崩溃

特点


除一、二代全部特点外 so代码虚拟化 对抗之前所有的脱壳方法

so加密

section加密

• 原理
将关键方法,存放在自定义的section中,通过解析每个section,将我们自定义的section进行加密。因为so在加载时会优先加载.init_array,所以将解密方法放在.init_array中,获取内存中各个section的起始地址和大小,将需要解密的section还原。

函数加密

• 原理
解析so,根据方法名找到指定的方法,将方法进行加密。加载so时,获取指定方法的地址,通过解密方法将指定方法解密。

特点



由于原本的指令已经被加密成其他的字节,IDA等静态分析工具中会出现大段无法识别的代码

各厂商特征

除此外还有很多大佬们可以自行总结

某梆
lib/libDexHelper.so、lib/libDexHelper-x86.so、

某加密
assets/ijiami.ajm、assets/ijiami.dat、assets/ijm_lib/libexec.so、assets/ijm_lib/libexecmain.so

某企鹅
lib/libshell-super.2019.so、lib/libshella-4.1.0.29.so

某数字
assets/libjiagu.so、assets/libjiagu_x86.so

某迦
lib/libxloader.so

assets/libvdog、assets/libvdog64、assets/libvdog-x86

某付盾
lib/libegis.so、lib/libegis-x86.so

脱壳工具

FRIDA-DEXDump

原理

通过Frida在内存中搜索dex\n035,因为Dex的头部都会存在一个dex\n035的模数,所以通过在内存中搜索dex\n035可以搜索到Dex文件。对于一些Dex它们被抹去了头部信息,对于这样的情况,FRIDA-DEXDump也提供了对应的方法,通过遍历当前进程中所有可以读的内存段,通过判断这个段的大小和Dex文件中一些关键区域的关系可以判断是否为一个Dex。

使用

在FRIDA-DEXDump GitHub中下载代码到本地或者通过pip3 install frida-dexdump安装

用法就是首先打开,我们需要脱壳的软件,然后执行python main.py -d程序执行开始检索内存中的Dex

检索到后会保存在SavePath对应的目录下
也可以通过python main.py -h查看它的其他使用方法

最终得到它脱出来的Dex,可以看下它脱壳效果

Youpk

原理

从ClassLinker中遍历所有DexFile对象,在虚拟机中Dex文件都用DexFile对象来表示,并Dump出所有Dex文件。此时只是整体Dump,Dex中的方法还未还原。遍历DexFile中的ClassDef结构,获取到所有Class,主动调用Class中的所有的方法,让程序强制走switch解释器执行,在解释器中添加Hook代码,当方法执行时自动保存CodeItem。根据保存的CodeItem和Dump下来的Dex进行合并,还原Dex中被抽取的指令。

使用

首先下载刷机包和还原工具,目前仅支持刷pixel 1手机

解压相关的镜像,fastboot flash xxx /Download/xxx.img依次刷入

配置待脱壳的App包名adb shell "echo com.xxx >> /data/local/tmp/unpacker.config"
启动Apk等待脱壳,每隔10秒将自动重新脱壳(已完全dump的dex将被忽略), 当日志打印unpack end时脱壳完成
dump文件路径为/data/data/包名/unpacker,使用adb命令将文件pull出

使用dexfixer.jar修复Dex,java -jar dexfixer.jar /path/unpacker /path/output
最后我们对比一下还原前后的代码
还原前

还原后

总结

本文简单地总结了一下Android加固的背景和发展历史,也介绍了一些目前常见的脱壳工具。对于so加密的情况,目前也有许多方法应对,比如ida动态调试dump内存中的so,GG模拟器dump内存,frida dump so,unidbg等等。对于混淆的so,也有jnitrace,unidbg,还有hluwa大佬的大作obpo等工具辅助我们分析。除此以外还有还有一些优秀的脱壳工具如Fart等,我也没有再做介绍了。总之感谢这些大佬们的努力和开源,没有你们就没有白嫖的我们,哈哈...


标签:Dex,加密,各代,Apk,so,内存,加固,Android,加载
From: https://www.cnblogs.com/CYCLearning/p/17213960.html

相关文章

  • Android设备上运行live555的推流程序
    在live555使用NDK21编译出arm64-v8a和armeabi-v7a中我们编译出了v8a和v7a的可执行文件我们可以使用testH264VideoStreamer程序进行推流我们将testH264VideoStreamerpush......
  • 注解处理器 3:实战 Android Router 插件实现
    前篇文档:注解处理器1:javax.lang.model包讲解前篇文档:注解处理器2:java注解处理器Gradle关联文章:Gradle功能介绍组件化介绍文章:Android组件化本文的Demo地址:Git......
  • Linux-等保加固-记录用户的登录和操作日志
    通过脚本代码实现记录所有用户的登录操作日志,防止出现安全事件后无据可查修改/etc/profile配置文件,在配置文件中新增以下内容 vi/etc/profileihistoryUSER=`whoam......
  • Android Studio菜单的制作
    废话不多说直接上代码//激活显示菜单@OverridepublicbooleanonCreateOptionsMenu(Menumenu){getMenuInflater().inflate(R.menu.option,menu);......
  • Android布局
    RelativeLayout根据父级定位android:layout_alignParentLeft="true"父容器左边android:layout_alignParentRight="true"父容器右边android:layout_alignParentTop="......
  • Android TabLayout加强版SlidingTabLayout
    众所周知TabLayout纯在很多问题和不足,因此各路神仙对其各种修改,在GitHub上比较被肯定三个TabLayout其中一个就是SlidingTabLayout,接下来我简单介绍一下使用:首先:依赖和X......
  • Android 关于WebView加载完成的多种监听方式
    第一种方式:setWebViewClient()>>>>>>onPageFinished()缺点是6.0以上手机只会调用响应一次,如下:mWebView.setWebViewClient(newWebViewClient(){@Override......
  • Android RecyclerView异步更新数据导致的崩溃问题
          AndroidRecyclerView异步更新数据导致的崩溃问题 之前写极光即时通讯UI的时候,发现的问题,今天突发奇想,来分享给大家.问题症状:如果绑定的集合List中......
  • Android WebView重定向链接无法显示的问题
    最近在网上看到一些这样的帖子,但是大多都无法解决重定向重排版链接的加载问题我这边给出一个最终解决方案,绝对比任何复杂的方式可靠何为重定向链接?当用户或​​搜索引擎......
  • Android 自定义EditText (限制表情输入&超出长度提示)
    有需要的直接拿去用,有什么问题请评论,第一时间回复/***CreatedbyXinghai.Zhaoon18/05/23.*//**作者:赵星海*时间:18/05/2415:56*用途:用于防止表情输出和最大......