apk编译与反编译

来源:互联网 发布:java实现数据增量同步 编辑:程序博客网 时间:2024/04/29 06:04

/*

author:少仲

blog: http://blog.csdn.net/py_panyu

weibo: http://weibo.com/u/3849478598

欢迎转载,转载请注明出处.

*/


0x1 apk编译过程


步骤中提到的工具如下表:

名称

功能介绍

在操作系统中的路径

aapt

Android资源打包工具

${ANDROID_SDK_HOME}/platform-tools/appt

aidl

Android接口描述语言转化为.java文件的工具

${ANDROID_SDK_HOME}/platform-tools/aidl

javac

Java Compiler

${JDK_HOME}/javac或/usr/bin/javac

dex

转化.class文件为Davik VM能识别的.dex文件

${ANDROID_SDK_HOME}/platform-tools/dx

apkbuilder

生成apk

${ANDROID_SDK_HOME}/tools/opkbuilder

jarsigner

.jar文件的签名工具

${JDK_HOME}/jarsigner或/usr/bin/jarsigner

zipalign

字节码对齐工具

${ANDROID_SDK_HOME}/tools/zipalign

 

第一步:打包资源文件,生成R.java文件
【输入】Resource文件(就是工程中res中的文件)、Assets文件(相当于另外一种资源,这种资源Android系统并不像对res中的文件那样优化它)、AndroidManifest.xml文件(包名就是从这里读取的,因为生成R.java文件需要包名)、Android基础类库(Android.jar文件)
【输出】打包好的资源(一般在Android工程的bin目录可以看到一个叫resources.ap_的文件就是它了)、R.java文件(在gen目录中,大家应该很熟悉了)
【工具】aapt工具,它的路径在${ANDROID_SDK_HOME}/platform-tools/aapt(如果你使用的是Windows系统,按惯例路径应该这样写:%ANDROID_SDK_HOME%\platform-tools\aapt.exe,下同).


第二步:处理AIDL文件,生成对应的.java文件(当然,有很多工程没有用到AIDL,那这个过程就可以省了)
【输入】源码文件、aidl文件、framework.aidl文件
【输出】对应的.java文件
【工具】aidl工具


第三步:编译Java文件,生成对应的.class文件
【输入】源码文件(包括R.java和AIDL生成的.java文件)、库文件(.jar文件)
【输出】.class文件
【工具】javac工具


第四步:把.class文件转化成Davik VM支持的.dex文件
【输入】 .class文件(包括Aidl生成.class文件,R生成的.class文件,源文件生成的.class文件),库文件(.jar文件)
【输出】.dex文件
【工具】javac工具


第五步:打包生成未签名的.apk文件
【输入】打包后的资源文件、打包后类文件(.dex文件)、libs文件(包括.so文件,当然很多工程都没有这样的文件,如果你不使用C/C++开发的话)
【输出】未签名的.apk文件
【工具】apkbuilder工具


第六步:对未签名.apk文件进行签名
【输入】未签名的.apk文件
【输出】签名的.apk文件
【工具】jarsigner


第七步:对签名后的.apk文件进行对齐处理(不进行对齐处理是不能发布到Google Market的)
【输入】签名后的.apk文件
【输出】对齐后的.apk文件
【工具】zipalign工具


知道了这些细节以后,我们就可以实现很多自动化的东西,比如日构建系统,自动生成发布文件等等.


0x2 apk文件结构

新建一个hello.apk,默认编译,然后将编译好的apk重命名成zip文件,用winrar打开.



(1).AndroidManifest.xml

       这里的AndroidManifest.xml就是源代码中的AndroidManifest.xml编译后所得到的文件.AndroidManifest.xml是安卓应用程序的全局配置文件,该文件保存了apk的包名,版本信息,sdk版本,Activity ,Service, Boardcast Receiver, Content Provider等应用组件的配置信息.还有程序所需要的权限也是在AndroidManifest.xml这个文件中声明的.


(2).classes.dex

虽然Android开发的源语言是java,但是Android应用程序却不在标准的java虚拟机上运行.Google为Android平台专门设计了一套用于运行Android程序的虚拟机,这就是Dalvik虚拟机(Dalvik Virtual Machine).而classes.dex就是运行在Dalvik虚拟机上的可执行文件.我们编写的java源代码经过java编译器编译后会生成.class文件;而Android SDK自带的dx工具(dx.bat在\sdk安装目录\sdk\build-tools\android-4.4这条路径下,dx.jar在\sdk安装目录\sdk\build-tools\android-4.4\lib这条路径下)会将这些.class文件转换为classes.dex.值得一提的是,在Android5.0中,Dalvik虚拟机已经被ART虚拟机(Android Runtime)所取代.


(3).resources.arsc

arsc,是一个包含了已被编译好的资源的二进制格式文件.我们知道,一个安卓应用程序往往包含了很多的资源(例如:layout文件,图片,字符串,菜单).那么程序在运行时,是怎么调用这些资源的呢?其实在apk编译和生成过程中,AAPT一方面会在源代码中为每个资源文件都赋予一个32位的整数做为标记,这些整数全部保存在R.java这个源文件中,R.java是系统自动生成的,用户是无法对其进行修改的.这里需要注意一点:assets文件夹中的资源文件是不会被编译的.另一方面,AAPT会生成一个resources.arsc文件,这个二进制文件包含了所有的资源名字以及标记这些资源的数字.resources.arsc的作用是当app运行时,手机设备通过该文件能够很方便匹配和解析apk中的资源.


(4).res文件夹

 apk中的res文件夹由drawable文件夹,layout文件夹,menu文件夹这3个子文件夹组成.其中,drawable文件夹用于存放apk的图片资源,layout文件夹用于存放布局文件,menu文件夹用于存放菜单文件.

 

(5).META-INF文件夹

存放的是签名信息,用来保证apk包的完整性和系统的安全


总结,android开发就是把源代码和资源编译成apk形式,而android逆向就是为了把apk还原成源代码和资源.apk文件就是一个带签名的zip包,目前主流的程序将核心代码都采用ndk开发,所以会多生成一个.so文件.


0x3 反编译

使用反编译工具dex2jar可将dex文件反编译成.jar文件,然后运用jd-gui工具即可查看反编译后得到的源代码.

(1).将classes.dex放到dex2jar的目录下

(2).dex2jar classes.dex


(3).使用jd-gui查看jar文件




0x4 反编译+重打包

使用apktool反编译apk文件:apktool d Hello.apk



之后找到Hello\res\values\string.xml,它包含了apk中的字符串资源.我们将hello_world的值改为”hellohell”



我这里反编译出现了错误,之后我就懒得去看为什么了,反正也不重要…..然后我就找了一个工具



反编译+修改+回编译+签名..然后搞定了


0 0
原创粉丝点击