Android加壳与脱壳(11)——不落地加载的对抗研究
1 |
声明:本文所使用的工具和样本为研究学习使用,任何人不得使用其进行非法用途,其行为与本人无关
|
1.前言
最近抽空把之前写的一些文章梳理出来,力争把相关系列更新完成
前面我们十分清晰的讲解了一代壳的加壳原理,还使用开源代码制作了一代壳加壳器,并进行了对抗研究,后面我们针对一代壳的加壳原理,还进行有针对性的脱壳研究,研究了脱壳点和脱壳原理,并分享了六类一代壳脱壳的相关方法,并进行了具体的实现,以及上一篇文章提供给大家了脱壳工具集。本文将在基础上进一步研究不落地加载的基本原理,以及不落地加载和动态加载的区别,不落地加载开源代码解析,不落地加载加壳器对抗实验。
2.不落地加载原理
2.1 动态加载回顾
我们说动态加载被称为第一代加壳技术,其原理十分简单,主要是使用了动态加载的技术,并选择了合适的加壳时机,具体原理大家参考前文
这里简单总结一下流程:
1 |
APP启动 - - - - - >加载壳的代理类Application - - - - - - >在壳代理类中的attchBaseContext和onCreate函数中对源程序dex进行加载和解密 - - - - - >启动原程序dex的执行流程
|
这个中间需要注意的两点就是类加载器DexClassLoader的替换
和Application的修正
,当然成熟的方案也许需要考虑多dex的加载问题,这里我们就不具体的展开了。
类加载器修正原因:
1 |
我们使用自定义的DexClassLoader加载,使得其不具备Android加载的生命周期,导致后面会出现崩溃,所以我们需要解决,相关的方案前面我也讲解了,一般可以替换为系统类加载器mClassLoader
|
Applicaition修正:
1 |
我们使用代理类的Application,但是可能我们的源Apk里面也包含自身的代理类Application,因此在我们针对这种情况,完成壳的加载后,还需要对Application进行修正
|
至于在壳代理类中需不需要完成原始dex的解密,这取决于原始的dex有无进行加密,但无论怎么处理,DexClassLoader加载了源dex后,都会将其释放在/data/data/...
文件夹或相关的文件夹下,这使得这种加壳技术的防护性较低,恶意攻击者可以直接对本地的源文件进行解密,拿到原始dex。
2.2不落地加载
参考文章:
安卓加固方案从落地加载到类指令抽取编写报告
[[Android加固实现,不落地加载(support 5.0-11)](https:// 链接失效)]
第二代不落地加载器具体实现
由于动态加载存在释放dex到本地的关键致命问题,为了解决这种问题,不落地加载的加壳技术就出现了。不落地加载技术可以实现直接将dex文件加载到内存中,而不需要先释放到本地的文件夹,这样就很好的对本地的释放的缺陷进行了防护。那怎么实现直接加载到dex文件到内存中呢?我们都知道Android中一般用DexClassLoader实现对dex文件的加载,而我们要想实现直接加载到内存中,无疑就需要重写DexClassLoader,重写DexClassLoader必然会涉及到defineClass
、findClass
、loadClass
,因为一个类在加载流程中必然会先后调用这三个函数,因此我们需要重写这三个函数。其实DexClassLoader在加载dex进入内存中也是通过字节加载的,因此我们只需要在Dalivk和Art选择在so文件中重写合适的加载函数,然后通过cookie来进行操作,即可
Dalvik:
1 |
hook重写的函数:libdvm.so中的openDexFile
|
Art:
1
2
|
Android8. 0 以下版本采用call libart的OpenMemory函数实现内存加载dex
Android8. 0 及以上采用系统提供的InMemoryDexClassLoader实现内存加载dex
|
而现在基本都是ART,难点在于8.0及以后有系统提供的内存加载dex接口,所以难点主要集中在8.0以前。8.0以前实现原理是加载虚dex然后替换成真实的cookie返回。这里如何替换是个难点,好在网上大神已经开源了方案,只是一番尝试下来只能在5.0和5.1上使用,并且也不支持多dex。网上查找相关资料,没有找到有用的结果,可能是搜索姿势不对。
3.项目代码分析
前面讲述了那么多的原理,这里我们拿具体的项目来进行全面的分析,帮助大家进行理解
项目地址:05aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6r3M7X3g2*7M7X3W2C8i4K6u0r3d9X3W2S2k6%4f1`.
分析项目前,我们先看看工具的效果
3.1实验效果
大佬开发的工具已经十分的完善,支持linux端和windows端,这里我们简单的使用下linux端的效果
未加壳的样本:

加壳后的样本:

可以发现除了代理类,我们基本看不到源样本的任何代码,这是不是比原来的第一代壳加壳器的防护要更高呢
3.2源码分析
项目的模块大概分为:
1
2
3
|
app: 需要加固的源程序代码
jiagu: 用于生成壳dex
pack: java执行程序,用于打包加固app
|
按照加壳程序的运行流程,我们首先分析pack这个目录

从结构我们可以看出这部分功能主要是制作一个加壳器,但加壳实现具体流程肯定不在这里面,我们从Main类开始分析
3.2.1Main.java
main()

parse()
函数主要作用是对我们输入参数进行过滤
(1)解压APK

主要功能:
1 |
解压APK、删除META - INF、修改Application的名字为代理类
|
(2)解压壳Dex

主要功能:
1 |
将壳的代理样本从jar转换为dex,说明很多真实壳的代理样本通过jar方式进行保存在项目中
|
(3)将壳和原dex进行加密然后组合成一个dex

这里是很多制作加壳器的基本的过程,就是拼接壳和dex为一个dex,这里最关键对dex进行了加密,所以防护上上升了一级
(4)copy so

保存数据到libjiagu.so中
(5)重打包APK

将APK重新的打包
(6)重签名APK

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2025-1-13 09:39
被kanxue编辑
,原因: