Dex加壳解壳原理

更新时间:2023-08-14 13:58:01 阅读量: 人文社科 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Android Dex文件加壳原理 :

1、加壳程序:加密源程序为解壳数据、组装解壳程序和解壳数据

2、解壳程序:解密解壳数据,并运行时通过DexClassLoader动态加载

3、源程序:需要加壳处理的被保护代码 根据解壳数据在解壳程序DEX文件中的不同分布,本文将提出两种Android Dex加壳的实现方案。 加壳程序工作流程:

1、加密源程序APK文件为解壳数据

2、把解壳数据写入解壳程序Dex文件末尾,并在文件尾部添加解壳数据的大小。

3、修改解壳程序DEX头中checksum、signature 和file_size头信息。

4、修改源程序AndroidMainfest.xml文件并覆盖解壳程序

AndroidMainfest.xml文件。

解壳DEX程序工作流程:

1、读取DEX文件末尾数据获取借壳数据长度。

2、从DEX文件读取解壳数据,解密解壳数据。以文件形式保存解密数据到a.APK文件

3、通过DexClassLoader动态加载a.apk。

当数据在解壳文件头中时,加壳程序工作流程:

1、加密源程序APK文件为解壳数据

2、计算解壳数据长度,并添加该长度到解壳DEX文件头末尾,并继续解壳数据到文件头末尾。(插入数据的位置为0x70处)

3、修改解壳程序DEX头中checksum、signature、file_size、header_size、string_ids_off、type_ids_off、proto_ids_off、field_ids_off、

method_ids_off、class_defs_off和data_off相关项。 分析map_off 数据,修改相关的数据偏移量。

4、修改源程序AndroidMainfest.xml文件并覆盖解壳程序

AndroidMainfest.xml文件。

解壳DEX程序工作流程:

1、从0x70处读取解壳数据长度。

2、从DEX文件读取解壳数据,解密解壳数据。以文件形式保存解密数据到a.APK

3、通过DexClassLoader动态加载a.APK。

ELF文件加壳技术

软件的壳一般运行在原始程序的外面,用来保护程序,在对原始程序加壳的过程中,原始程序的入口地址等信息被保存,在外壳运行的过程中,外壳程序会动态的修改任务的入口地址等信息,外壳程序结束后,原始层序开始执行,一般对原始程序加壳时,原始程序首先被加密,在运行外壳程序的时候,外壳程序会对原始程序进行动态的内存解密,使得原始程序恢复其来了的面貌。

只有经过解密后的原始程序才能正常执行。在解密的过程中,外壳程序会对原始程序解密密码或者解密密钥进行验证,只有在密码或者密钥正确的时候才对原始程序解密,后则外壳程序退出这样的安全性和机密性等信息将会的到保护。由于加壳程序在运行过程中,是以整体的形式被加载到内存中,在内存中进行解密的,这种内存解密机制确保无临时文件生成,无原始程序还原等特性,因此可以实现对原始程序更好的保护。

软件加壳实际上是对原始程序及外壳程序进行合并的一个过程,加壳过程实现对原始程序的压缩加密等处理,同时将外壳程序添加到原始程序的开始或末尾,在合并过程中,原始程序的入口被保存,整个程序的入口被改成了外壳程序的入口。这样就可以保证在运行的时候,外壳程序会先被执行,在外壳程序执行的过程中,进行各种保护验证及信息查询,只有验证等信息正确的时候,外壳程序才会对原始程序进行解密还原等处理,并读取保存的原始程序入口,将整个程序的入口改为原始程序的入口,确保在外壳程序退出时原始程序被执行。

软件的加壳实际上是由外壳程序和加壳程序两部分构成的,外壳程序是运行在原始程序外面的代码段,在执行时,该部分代码段会先被执行。加壳程序是将 外壳程序和原始程序合并成代码。在加壳程序中,不仅要完成对文件的合并,文件结构的修改等功能,还要完成对原始程序的加密等功能。经过加壳后,程序将变成由外壳程序,原始程序及解密密钥等共同组成的程序段。

在外壳程序中,不仅要提供对原始程序文件提取、解密等功能,还要实现内存解密、解密后数据填回等功能,同时外壳程序还要实现对程序入口地址修改,控制权转意等功能。这样在外壳程序运行时,才能保证对原始程序进行正确的处理并保证原始程序可被执行。

常见的外壳加载过程分为四步:

1) 保存原程序的入口参数。外壳程序执行前,会读取各个寄存器的信息并将这些

信息保存,当外壳程序执行完的时候,这些寄存器信息将被回复,同时源程序入口将被设置为真正的入口地址。

2) 解密原程序各个被加密的区。在加壳程序运行过程中,原程序的各个区都会被加密,这些加密后的区段完全失去了原来的信息结构,使得不仅不能被反编译,也无法被加载执行。在壳程序执行的过程中,壳程序根据加密规则,选用相应的解密算法对被加密的各个区在内存中进行解密,并且解密后的数据存放在原来的位置,这样在壳程序执行完成后,原程序己经在内存中被解密并恢复。内存中此时存储的是可被执行的程序源码。

3) 初始化IAT信息表。在程序正常执行的过程中,加载器实现对IAT的填写。在系统执行被加密的程序时,由于外壳程序会先被执行,则外壳程序在执行过程中会新建自己的IAT输入表,并且让加载器指向该新建的输入表。当外壳程序运行完后,外壳程序要修改原并填写原输入表,同时修改加载器的指向,使源程序被加载并执行。

4) 壳交出控制权。

Dex加密保护

Dex文件是对Java源码编译生成的全部class文件进行合并而产生的文件。 该文件主要包括文件头、魔术字段、检验码字段、SHA-1签名字段、map—off字段、stringjds—size/off字段等。文件头:文件头主要包括校验和以及其他结构的偏移地地和长度信息。

魔数字段:魔数字段是4字节的dex文件标识符,对dex文件进行标识是它的主要作用。

检验码字段:该字段主要用来对文件的完整性进行检测。

SHA-1签名字段:20字节码的该签名字段主要是为了实现校验的唯一性。

map_off字段:该字段中保存的是map的开始位置。通过该字段,可以方便快速的定位到map数据。

striiig_ids__size/off字段:这两个字段是字符串标识字段,源文件编译后的字符串信息都存储在这两个字段中。

安卓程序中采用RC4算法作为对dex文件进行加密的工程算法。RC4是Rob Rivest在1987年设计的密钢长度可变的流加密算法。它加解密使用相同的密钥,

因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也是安全套接层(SSL)可采用的算法之一。RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4—个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钢并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。

由于异或运算的对合性,RC4加密解密使用同一套算法,具体加解密流程如 下:

RC4加密解密流程图

Dex加壳原理

对dex文件加密也可以理解成对dex文件进行加壳,利用加壳程序及相应的算法对原数据进行加密,并将加密后的数据存放在解壳程序的尾部,或者把数据放在Dex头的后面,位于解壳程序文件头。同时在解壳文件末尾添加加壳后元数据的大小等信息。加壳是为了保护内部的数据,但是对内部数据的保护应该采用相应的加密算法,使得原数据失去原有的结构及特性。在应用运行的时候,由解壳程序根据相应的解密算法对数据进行解密。

Dex的加壳过程

加壳是为了保证运行时先执行外壳,在外壳中进行解密。这样不仅可以保证原文件信息的安全性,也实确保了内存解密技术在dalvik虚拟机上实现的可能性。 在对dex文件进行加壳前,应先对文件内容进行加密。通过加密使得原dex文作失去了原有的文件结构等信息。但由于加密后的文件无法被加载器识别并加载,因此需要外壳文件来确保加壳后文件可被加载器加载。由上图分析可知,外壳文件没被进行加密处理,这样就保证了外壳文件可被加载并处理。外壳文件在运行过程中实现对加壳文件的解密等操作,使得加壳文件恢复原文件特性,可被热载器重新识别并执行。

加密过程是将dex明文内容改成密文内容的过程,通过加密,dex失去了原有结构及格式,预防了反编译攻击。通过对dex文件加壳及加密分析可知,加壳加密后文件的结构及组织形式都会被改变。新文件不仅有原文件信息,更有外壳信息等结构。具体加壳加密后新文件结构如下图所示。在完成加壳加密等处理过程后,文件的头信息,文件大小,校验码等信息都将被改变。切文件的结构也分成了外壳信息,原文件加密信息及源文件长度等。这些新信息的改变,保证dex文件可被正

确加载,正确执行并正确脱壳解密。

加壳加密后dex文件结构图

在Dex文件被加密并写入壳程序后,加壳程序会将解壳程序进行过程中需要 的密钥信息存储在SO文件中,这样在解壳程序运行时,就可以访问SO文件,并从中获得解密密销。

解密过程实现

加壳后的程序,发布的是壳程序及被加密过的Dex数据。在程序被执行时壳程序先被执行壳程序访问SO获得解密密钥,将源文件解密,然后执行原程序。

执行过程中,为了实现解壳及解壳后程序的正常执行,应该保证下列各步骤正常:保证解壳程序被第一时间运行:保证在解壳程序执行后,源程序的application被执行:实现通过DexGassLoader对apk代码的动态加载;保证解壳后的资源文件被代码动态引用。

(1) 脱壳第一时间运行

Android应用开发指明Android运行机制,通过对其分析可知,不同的组件构成了Android应用程序,在应用程序启动时,系统首先启动各个组件。要保证脱壳

程序的.第一时间运行,应该使其在各组件启动前运行,只有在组件启动前,脱壳程序完成对原程序数据的解密及加载,才能使原程序正常加载并被执行。在应用启动时,作为系统下文的Application会被系统最先调用,是开发者开发的程序的执行入口点。因此,可以迪过修改AndroidMainfest.xml中关于Application 配罝。实现脱壳程序的最先运行。

(2) 原程序在股壳程序运行完后被第一时间运行

为了保证脱壳程序被第一时间运行,AndroidMainfest.xml配置文件中的Application被修改为脱壳程序的Application,修改后,原程序的Application彼全部替换,程序逻辑被改变。为了保证原程序逻辑及执行过程不被改变,应该在脱先程序运行完后,第一时间将Application对象换回原程序的。通过在AndroidMainfest.xml文件中配置原有Applicaiton类信息来达到想要的目的。

(3) 实现通过DexClassLoader对apk代码的动态加载

在Android系统中,DexclassLoader加载的类是没有组件生命周期的,也就 是说即使DexClassLoader通过对APK的动态加载完成了对组件类的加载,当系统启动该组件时,还会出现加载类失败的异常。通过查看Android源代码可知组件类的加载是由另一个ClassLoader来完成的。DexCIassLoader和系统组件ClassLoader并不存在关系,系统组件ClassLoader当然找不到由DexCiassLoader加载的类,如果把系统组件ClassLoader的parent修改成DexCIassLoader,最终可以实现对apk代码的动态加载。

(4) 保证解壳后的资源文件被代码动态引用

代码默认引用的资源文件在最外层的解壳程序中,因此需要增加系统的资源加载路径来实现对解壳后APK文件资源的加载。

上面的过程可以保证外壳程序被先执行,在外壳程序被执行的过程中,实现对源文件的解密,配置文件的修改等信息。这样在外壳程序提出时,原程序将会被正常加载执行。具体外壳程序进行脱壳,原文件解密及配置文件修改过程下图:

解壳及配置修改过程

在外壳程序处理过程中,要对原程序进行内存解密处理,以使原dex文件恢 复原有的结构等信息,从而可被正常执行。dex 文件在解密过程中,解密模块先获得原文件的开始位置,长度等信息,进而提取出加密后的原文件内容,然后从so库中获得解密密钥等信息,进行文件解密,然后修改配置文件,交出控制权等。解密完成后,明文内容被从新填写回内存中原位置。

本文来源:https://www.bwwdw.com/article/l4tj.html

Top