Android安全--42--说说Android软件壳
本博文实际发布于:2019年11月1日,2020年3月19日修改过部分内容
最近忙里抽闲研究了一段时间Andorid软件壳,有两个感想:
1、以前的低级软件壳很低级,现在的高级软件壳很高级
2、作为一个偏业务的安全人员,研究软件壳尤其是脱壳,实际上没有太大意义,因此以后大概率不会再深究这东西
============================================================================
本篇博文分为两大部分
第一部分:软件壳概述。包括查壳工具、壳特征、壳与脱壳方法简述
第二部分:软件壳碎碎念。
============================================================================
软件壳概述
一、查壳工具
APKID
是一款专门用来识别APK文件特征的开源工具,它使用Python脚本配合yara规则,实现了APK编译器识别规则与常见的软件壳特征识别规则,支持快速识别APK的软件壳信息,准确率高且易扩展。
截止现在仍在不断更新。
Github:
https://github.com/rednaga/yara-python
安装方法:
git clone https://github.com/rednaga/yara-python
cd yara-python
sudo python setup.py install
pip install apkid
- 1
- 2
- 3
- 4
使用方法
apkid /lalala/test.apk
- 1
二、常见的加固厂商特征
仅作为学习使用
厂商 | 特征 |
---|---|
娜迦: | libchaosvmp.so、libddog.so、libfdog.so |
梆梆: | libsecexe.so、libsecmain.so、libSecShell.so |
梆梆企业版: | libDexHelper.so、libDexHelper-x86.so |
爱加密: | libexec.so、libexecmain.so、ijiami.dat |
360: | libprotectClass.so、libjiagu.so、libjiagu_art.so、libjiagu_x86.so |
百度: | libbaiduprotect.so |
阿里聚安全: | aliprotect.dat、libsgmain.so、libsgsecuritybody.so |
腾讯: | libup.so、libexec.so、libshell.so、mix.dex、lib/armeabi/mix.dex、lib/armeabi/mixz.dex |
腾讯御安全: | libtosprotection.armeabi.so、libtosprotection.armeabi-v7a.so、libtosprotection.x86.so |
通付盾: | libegis.so、libNSaferOnly.so |
网秦: | libnqshield.so |
网易易盾: | libnesec.so |
APKProtect: | libAPKProtect.so |
几维安全: | libkwscmm.so、libkwscr.so、libkwslinker.so |
顶象科技: | libx3g.so |
软件壳的代级完全就是民间随意称呼的,除了第一代壳没有争议,其他的代级在不同的文献中有不同的定义
三、动态加载型壳(第一代壳)
第一代壳也是最好脱的壳,教科书级,网络教程一搜一大把那种,免费版的壳多为该壳。
1、加壳技术 - Dex加密
Dex字符串加密
:不解释
资源加密
:不解释
对抗反编译
:主要是针对反编译工具(如apktool),利用反编译工具本身存在的缺陷(如漏洞或某种特殊情况下出现的异常等),使得反编译失败,以此实现对反编译工具的抵抗。
反调试
:主要是针对IDA或GDB的反调试,检测相应的文件或相应参数的值(如android_server或TracePid值),以此判断当前是否处于调试状态。
自定义DexClassLoader
:主要是针对dex文件加固、加壳等情况
2、脱壳方法
2.1、缓存脱壳法
动态加载型壳使用DexClassLoader
这种方式将加密后的DEX文件在内存中解密后进行动态加载,但由于一些软件壳并没有处理DEX优化时缓存的路径,最终使得系统执行dexopt命令对加载的DEX文件进行优化时,将优化结果放到了默认的/data/dalvik-cache
目录下。
解密时不需要做任何额外的工作,只需要将/data/dalvik-cache
目录下的ODEX文件取出,进行一次deodex操作,即可完成脱壳工作。
2.2、内存dump脱壳法
因为第一代壳在内存中是完全解密的,可以从内存中dump需要解密的APK内存,即可完成脱壳工作。
在内存中寻找dex.035(还未被优化的dex文件)或者dex.036(已经被优化的dex文件)
完成该方法的脱壳工具:
https://github.com/strazzere/android-unpacker
该工具的核心是通过find_magic_memory()
方法读取/proc/pid/maps
内存映射表,找到DEX所在的内存起始位置,然后通过dump_memory()
方法将内存dump下来
2.3、动态调试脱壳法
本质还是内存dump脱壳法,需要通过调试器找到合适的dump时机,即DEX文件已经在内存中完全解密,且其中的代码还没有开始执行。寻找合适的Dump时机是动态调试脱壳法的重点。
主要在于分析AOSP源码文件:dalvik/dexopt/OptMain.cpp
中
主流的设断点的方法有dvmDexFileOpenPartial()
、dexFileParse()
方法,在该方法处设置断点,当执行到该断点时,使用内存dump脚本将其dump下来,即可完成脱壳操作。
动态调试脱壳与DEX加载代码的处理方式有关。
2.4、HOOK脱壳法
该方法使用HOOK框架,配合HOOK代码(需要找到合适的脱壳时机),实现工具的自动化脱壳。
主要的下断函数:dvmDexFileOpenPartial()
2.5、系统定制脱壳法
针对第一代壳在dvmDexFileOpenPartial()
、dexFileParse()
方法处设置断点来脱壳的特点,修改它们在源码中的实现,然后编译修改后的代码,刷机形成定制的系统并运行,以此实现脱壳。
四、代码抽取壳(第二代壳)
即DEX已经加载到内存中,但仍处于加密状态。免费壳部分为该壳。
1、加壳技术 - Dex抽取与so加固
Dex代码抽取到外部:dex不再是整体的加密,把关键方法的代码抽取到外部
Dex动态加载:动态加载dex文件
So加密:针对so的一些函数进行加密
2、脱壳方法
2.1、内存重组脱壳法
代码抽取壳特征:
将DEX文件的DexCode提取后填0,将DEX文件的所有内容保存于APK文件中,当APK运行时,会在内存中进行动态解密,所有解密的方法内容指针都位于DEX文件结构体外部的内存中,从而有效避免了在只知道DEX文件的起始地址的情况下就可以快速进行dump的问题。
脱壳方法:
解析内存中DEX文件的格式,将其重新组合成DEX文件,可以实现100%的DEX代码还原。
针对Dex脱壳工具:
ZjDroid、dumpdex工具
对付一切内存中完整的dex,包括壳与动态加载的jar
针对So脱壳工具:
elfrebuild
构造映射soinfo,然后对其进行重建
2.2、HOOK脱壳法
合适的HOOK点是libdvm.so
中的dvmCallMethodV()
方法。APK启动时,会首先执行它的Application类的onCreate()
方法。Dalvik虚拟机时通过dvmCallMethodV()
方法来启动Java方法的,它的实现位于AOSP源代码的dalvik/vm/interp/Stack.cpp
中。
函数如下:
void dvmCallMethodV(Thread* self, const Method* method, Object* obj,
bool fromJni, JValue* pResult, va_list args);
- 1
- 2
对第二个Method类型的method参数,可以通过它的name字段来判断当前执行的方法名。当确定当前的方法是onCreate()
时,可以进一步判断方法所在的类的名字,从而确定其是否为脱壳的目标。
获取ClassObject
类型的类对象指针后,可以通过它的pDvmDex
字段获取内存重组脱壳法所使用的DvmDex
结构体的信息,接下来的DEX内存重组步骤就和内存重组脱壳法一样了。
2.3、系统定制脱壳法
第二代壳通用脱壳方法,直接上工具:
工具地址及其用法:
https://github.com/zyq8709/DexHunter
五、代码抽取壳(第三代壳/第二代壳)
1、加壳技术 - Dex动态解密与so混淆
Dex代码动态解密
So代码膨胀混淆:比如花指令之类
2、脱壳方法
2.1、dex2oat
ART模式下,dex2oat生成oat时,内存中的dex是完整的,此时可以用修改后的dex2oat文件替换原系统的dex2oat文件
2.2、系统定制法
HOOK函数Dalvik_dalvik_system_DexFile_defineClassNative(),枚举所有的DexClassDef,对所有的class调用dvmDefineClass进行强制加载
六、代码混淆壳(第四代壳/第三代壳)
基于LLVM的虚拟机软件壳,即虚拟壳,还有基于白盒的代码混淆,第三代壳代表了Android平台上*别的软件加密技术。
这类壳脱壳博主不会,再见!
软件壳参考文章
博主所列的文章,都是博主阅读并研究过的,这些文章对博主的学习研究帮助很大
------------------------------------------------------------------------------------------
梆梆软件壳:
早期的梆梆加固原理,年代久远,仅用做学习:
https://blog.csdn.net/androidsecurity/article/details/8892635
梆梆个人版加固脱壳,也仅用做学习:
https://wenku.baidu.com/view/ac7ecba09b6648d7c0c74677.html
梆梆免费壳脱壳,比较新,具有实际价值:
https://blog.csdn.net/m0_37344790/article/details/79782265
梆梆加固逻辑漏洞脱壳
https://blog.csdn.net/DaoDivDiFang/article/details/83830196
梆梆加固破解
https://www.jianshu.com/p/955c0b1507c7
也是一个梆梆免费版的壳
https://www.52pojie.cn/thread-586058-1-1.html
------------------------------------------------------------------------------------------
爱加密软件壳:
脱掉爱加密的壳
https://www.jianshu.com/p/2ed471bc9b15
ZJDroid脱爱加密壳经过
https://blog.csdn.net/ljb_wh/article/details/39083399
爱加密脱壳示例
https://blog.csdn.net/PLA12147111/article/details/100708899
------------------------------------------------------------------------------------------
360软件壳:
1、识别360加固的代数
2、第一代360脱壳:xposed插件脱壳、静态脱壳
3、第二代360脱壳:so手动dum并修复、open+memcmp手动脱壳、mmap手动脱壳
4、第三代360脱壳:drizzledumper脱壳、dex2oat脱壳
Android脱壳圣战—360脱壳与修复
https://blog.csdn.net/yxp1198287349/article/details/84382504
老外挑战360壳
https://blog.csdn.net/freakishfox/article/details/79752847
360加固动态脱壳
https://blog.csdn.net/zhangmiaoping23/article/details/52138085
------------------------------------------------------------------------------------------
百度软件壳:
使用内存dump脱百度壳
https://blog.csdn.net/u014753925/article/details/52935354
百度脱壳加固分析
https://blog.csdn.net/hk9259/article/details/47429285
------------------------------------------------------------------------------------------
腾讯软件壳:
乐固脱壳实战
https://blog.csdn.net/hbhgyu/article/details/81437656
360加固、乐固一件脱壳
https://www.jianshu.com/p/138c9de2c987