记录黑客技术中优秀的内容, 传播黑客文化,分享黑客技术精华

基于代理Application机制的Anddroid应用加壳方法

2017-02-21 03:40

基于代理Application机制的Anddroid应用加壳方法。壳是指一个程序的外面再包裹上另外一段代码,保护里面的代码不被非法修改或反编译的程序。它们一般都先于程序运行,拿到控制权,然后完成它们保护软件的任务。对于Android APP来说,所有的实现逻辑都集成于DEX文件中,DEX文件是一个APP的核心所在,因此保护DEX文件被逆向或者修改尤其重要。Android应用的DEX加壳过程如下:

\

尽管上述DEX加壳过程中,关于如何对DEX进行加密或者利用其它方法对其进行处理的方法有很多,但是通过自定义DexClassLoader替换原DexClassLoader,并通过后者来加载被保护代码是所有加壳程序都必须实现的必经之路。本文重点介绍的就是通过一种代理Application的机制把原DexClassLoader替换成用自定义的DexClassLoader,并通过它来加载被保护DEX代码从而达到正常运行加壳后的Android应用。

Android应用中有且仅有为一个Application组件,并且Application组件的生命周期从应用启动开始到应用退出结束, 与Android的整个应用的生命周期是相同的,因此通过在Application组件外面包裹一层壳来隐藏整个应用的DEX文件,是最简单且有效的一种方法。

显然,系统的DexClassLoader已经不能用来加载被保护后的DEX文件,因此我们必须定义一个自定义的DexClassLoader来完成加载被保护后的DEX文件。所有的Class包括自定义Application组件(下文一律称为MyWrapperProxyApplication)都必须被自定义的ClassLoader所加载。为了要实现这个需求,需要在MyWrapperProxyApplication被加载之前,必须用自定义的DexClassLoader先替换掉API层的默认的DexClassLoader,否则MyWrapperProxyApplication就会被默认的DexClassLoader加载。但这会产生一个悖论,因为MyWrapperProxyApplication组件的onCreate函数是整个Android应用的入口,MyWrapperProxyApplication被加载之前,没有任何应用代码可以运行,因此替换ClassLoader无法办到。基于代理Application框架就是用来解决这类问题的。

首先我们需要修改AndroidManifest.xml文件:

在我们这个框架里,加壳后的应用一共有两个Application对象,一个是我们自己自定义的MyWrapperProxyApplication,另外一个就是被保护后的Application对象,我们姑且称之为OriginalApplication,首先我们需要修改Android应用的AndroidManifest.xml文件对新加的Application组件进行重新定义。老的AndroidManifest.xml文件定义:

android:name=".MyApplication"

android:icon="@drawable/icon"

android:label="@string/app_name" >

修改后AndroidManifest.xml文件定义为:

android:name=".MyWrapperProxyApplication"

android:icon="@drawable/icon"

android:label="@string/app_name" >

android:name="ORIGINAL_APPLICATION_CLASS_NAME"

android:value=".MyApplication" >

....

我们通常认为Application:onCreate()函数是整个应用的入口,所以我们直接在Application:onCreate函数里面生成自定义的DexClassLoader即可,但当应用注册有ContentProvider的时候,这并不正确的。ContentProvider:onCreate()调用优先于Application:onCreate()函数的调用,但是自定义的DexClassLoader也必须把ContentProvider组件也加载到内存里面,所以如果直接就在Application:onCreate()里面替换系统默认的DexClassLoader是行不通的。

幸好,我们还有另一个方法:attachBaseContext()。Android的几个主要组件Application、Activity和Service都是ContextWrapper的子类。ContextWrapper一方面继承了Context,一方面又包含了一个Context对象(称为mBase),对Context的实现为转发给mBase对象处理。这一个听起来很绕的设计,是为了对这些组件中的Context功能做延迟初始化(delay init)的处理。其类图关系如下所示:

\

ContextWrapper完成这个延迟化处理的方法就是attachBaseContext()。可以这样说,Application对象在刚刚构造完成时是“残废”的,访问所有Context的方法都会抛出NullPointerException。只有attachBaseContext()执行完后,它的功能才完整。在ContentProvider:onCreate()中,我们知道Application:onCreate()还没有运行,但已经可以使用getContext().getApplicationContext()函数获取Application对象,并访问其Context方法。显然,Android的API设计者不能允许此时获取的Application是“残废”的。结论是Application:attachBaseContext()必须要发生在ContentProvider:onCreate()之前,否则API将出现BUG;无论Android的系统版本如何变化,这一点也不能改变。

知识来源: www.2cto.com/article/201702/602098.html

阅读:101136 | 评论:0 | 标签:无

想收藏或者和大家分享这篇好文章→复制链接地址

“基于代理Application机制的Anddroid应用加壳方法”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

关注公众号hackdig,学习最新黑客技术

推广

工具

标签云