Android第一二代壳的脱壳点分析
只讲ART下的脱壳,DVM太过时了
一、脱壳点分析
编写过Android第一二代加固壳的可以知道,无论是通过系统的类加载器加载的,还是通过自定义类加载器加载的,无一例外,最终都逃不过创建DexFile对象:
1 |
|
因此,我们脱壳,也会围绕DexFile这个类(或者说是对象)来进行。
我们要明白,脱壳无非就是从内存中将解密状态下的dex整体dump下来(或者说写成文件存储下来)。而要想实现这一目的,就需要解决以下几个问题:
- 内存中dex的起始地址和大小,或者是DexFile对象,甚至是DexFile对象的首地址。
- 脱壳时机,只有正确的脱壳时机,才能够dump下解密状态下的dex,否则即使dump下来也只是加密状态下的dex。
对于问题一,我们跟踪dex文件的加载流程就可以很容易解决的。dex文件的加载流程具体见:
在链接文章中,拥有dex的起始地址和大小的有这么几个函数:
- DexFile::Open(const uint8_t* base, size_t size, …)
- OpenAndReadMagic(),因为该函数中会创建dex文件输入流,可以借此dump。
- OpenCommon(const uint8_t* base, size_t size, …)
- OpenMemory(const uint8_t* base, size_t size, …)
- DexFile的构造函数
- DexFileVerifier::Verify(const DexFile* dex_file, const uint8_t* begin, size_t size, …)
- DexFileVerifier的构造函数
因此它们都可以作为脱壳点。当然了, 肯定不止这些函数,还有很多很多函数可以作为脱壳点,比如说那些返回值是DexFile类型的函数、与DexFile有关的函数、与cookie有关的函数等等。对这些函数在源码层面进行改写,就可以实现一个简单的脱壳机了。
问题二很简单,如何确定脱壳时机呢?根据脱壳程序中的代码逻辑,首先是壳程序先走一遍dex加载流程,然后再是源程序走一遍dex加载流程,虽然有的脱壳点会触发两次,即会dump两次(一次壳程序dex,一次源程序dex),但是没关系,因为dump下来保存的文件名是固定的,造成的结果就是重写覆盖,而后者就是我们想要的源程序dex。
二、脱壳方法
详见[原创]Android漏洞之战(11)——整体加壳原理和脱壳技巧详解-Android安全-看雪-安全社区|安全招聘|kanxue.com。
参考:
[原创]拨云见日:安卓APP脱壳的本质以及如何快速发现ART下的脱壳点-Android安全-看雪-安全社区|安全招聘|kanxue.com
Android第一二代壳的脱壳点分析
http://example.com/2023/12/12/Android安全/Android第一二代壳的脱壳点分析/