Android安全--42--说说Android软件壳

时间:2024-03-09 15:59:45

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