探索黑客技术攻防,实战研究与安全创新

导航菜单

Android下APK及DEX文件解析

APK文件

APK是AndroidPackage的缩写,即Android安装包。APK是类似SymbianSis或Sisx的文件格式,PC上的安装文件的后缀名为“.exe”。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。

使用Android打包工具(aapt),可以将DEX文件、资源文件以及AndroidManifest.xml文件(二进制格式)组合成一个应用程序包(APK)。APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件。Dex是DalvikVMexecutes的全称,即AndroidDalvik执行程序,并非JavaME的字节码,而是Dalvik字节码。

一个APK文件结构通常如下所示:META-INF\Jar文件中常可以看到存放资源文件的目录程序全局配置文件字节码res\


AndroidManifest.xml
classes.dexDalvik
resources.arsc


编译后的二进制资源文件

从文件结构我们可以知道,Android在运行一个程序时,首先需要UnZip,然后类似Symbian那样直接运行。APK文件与WindowsMobile中的PE文件有所区别,程序的保密性和可靠性不是很高,通过Dexdump命令可以反编译,但这样做符合发展规律,微软的WindowsGadgets或者说WPF也采用了这种构架方式。

在Android平台中,dalvikvm的执行文件被打包为apk格式,最终运行时,加载器会解压获取编译后的androidmanifest.xml文件中的permission分支相关的安全访问,但仍然存在很多安全限制,如果将apk文件传到/system/app文件夹下,则会发现执行是不受限的。我们平时安装的文件可能不是这个文件夹,而在androidrom中,系统的APK文件默认会放入此文件夹,拥有Root权限。

DEX文件

DEX是DalvikVMexecutes的全称,即AndroidDalvik执行程序,并非JavaME的字节码,而是Dalvik字节码。Google在新发布的Android平台上使用自己的Dalvik虚拟机来定义,这种虚拟机执行的并非Java字节码,而是另一种字节码:DEX格式。在编译Java代码之后,通过Android平台上的工具,可以将Java字节码转换成Dex字节码。虽然Google称Dalvik是为了移动设备定制的,但业界很多人认为这是为了规避向Sun申请Javalicense。这个DalvikVM针对手机程序/CPU做过最佳化,可以同时执行许多VM而不占用太多资源。

对AndroidDEX文件进行优化,需要注意的一点是,DEX文件结构虽是紧凑的,但要想提高程序的运行速度,仍然需要对DEX文件进行进一步优化。

调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的每一个域,验证DEX文件中的所有类,并对一些特定的类进行优化,对方法里的操作码进行优化。优化后的文件大小会有所增加,应该是原AndroidDEX文件的1~4倍。优化发生的时机有两个:对于预置应用,可以在系统编译后生成优化文件,以ODEX结尾,这样在发布时,除APK文件(不包含DEX)外,还有一个相应的AndroidDEX文件;对于非预置应用,包含在APK文件里的DEX文件会在运行时被优化,优化后的文件被保存在缓存中。

每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。虚拟机的线程机制、内存分配和管理、Mutex等都是依赖底层操作系统而实现的。所有Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制。不同的应用在不同的进程空间里运行,加之对不同来源的应用都使用不同的Linux用户来运行,从而可以最大程度的保护应用的安全和独立运行。

Zygote是一个虚拟机进程,同时也是一个虚拟机实例的孵化器,每当系统要求执行一个Android应用程序,Zygote就会FORK出一个子进程来执行该应用程序。这样做的好处显而易见,Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化、库的加载、预置类库的加载和初始化等操作。而在系统需要一个新的虚拟机实例时,Zygote通过复制自身,最快速的提供一个系统。另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。Android应用开发和Dalvik虚拟机所使用的编程语言是Java,和JavaSE一样,编译时使用SunJDK将Java源程序编译成标准的Java字节码文件(.class文件)。而后通过工具软件DX把所有的字节码文件转成AndroidDEX文件(classes.dex),最后使用Android打包工具(aapt)将DEX文件、资源文件以及AndroidManifest.xml文件(二进制格式)组合成一个应用程序包(APK),应用程序包可以被发布到手机上运行。

DEX文件反汇编

Android模拟器中提供了一个DEX文件的反编译工具Dexdump。用法为首先启动Android模拟器,把要查看的DEX文件用adbpush上传到模拟器中,通过adbshell登录,找到要查看的DEX文件,再执行“dexdumpxxx.dex”即可。(在模拟器环境下,使用电脑执行AndroidDebugBridge(adb)工具可以操作LinuxShell,也可实现与模拟器下adbd程序之间的通信。)

另一个我们能找到的DEX文件反编译工具是Dedexer,它可以读取DEX格式的文件,生成一种类似于汇编语言的输出。

下载ddx1.5.zip后,解压缩会生成一个dedexer目录,其中包含build.xml文件,需要根据本机的环境配置build.xml的内容。环境配置好之后就可以开始编译了,当然首先要保证已经安装好了ant编译工具。

那么,我们如何使用ddx呢?执行命令“java-jarddx.jar-d反编译文件存放目录dex文件”,即可得到ddx文件,进行分析阅读。

(完)