Android编译,打包,签名,混淆和反编译相关知识

1.    逆向工程

        逆向工程(又称反向工程),是一种技术过程,即对一项目标产品进行逆向分析及研究,从而演绎并得出该产品的处理流程、组织结构、功能性能规格等设计要素,以制作出功能相近,但又不完全一样的产品。其主要目的是,在不能轻易获得必要的生产信息下,直接从成品的分析,推导出产品的设计原理。

        逆向工程可能会被误认为是对知识产权的严重侵害,但是在实际应用上,反而可能会保护知识产权所有者。例如在集成电路领域,如果怀疑某公司侵犯知识产权,可以用逆向工程技术来寻找证据。——事物的两面性,你要看到积极的一面,摩托罗拉专利侵权。

反编译工具---Apktool 

官方下载地址:

https://ibotpeaches.github.io/Apktool/

使用方法:

(1)    重命名下载的文件为apktool.jar

(2)    下载Windows和Mac下对应的操作apktool的脚本

Windows:https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/windows/apktool.bat

Mac:https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/osx/apktool

(3)    把apktool.bat和apktool.jar放在同一个目录下,并加入PATH环境变量

Android编译,打包,签名,混淆和反编译相关知识_第1张图片
配置环境变量

(4)    直接新启动一个命令行即可执行apktool命令

Android编译,打包,签名,混淆和反编译相关知识_第2张图片
执行apktool

 反编译工具---jadx(新一代反编译大杀器)

下载地址:

https://github.com/skylot/jadx/releases

    下载完成后,可执行文件在bin目录底下,我们配置环境变量即可直接使用命令行,命令行执行jadx-gui,调起可视化界面。我们反编译手机QQ的apk,可以傻瓜式地查看项目的源代码,既然有了反编译的代码,我们就很有可能顺藤摸瓜,得到我们想要的资源,产品架构,解决方案等。


Android编译,打包,签名,混淆和反编译相关知识_第3张图片
JADX

 接下来我们还是先使用Apktool来理解反编译的过程和工作原理,以便以后碰到问题能够自己解决(比如apk加壳的问题)

反编译命令:apktool d -o qq mobileqq_android.apk

d 表示decode ,反编译,与之对应的是building,编译,将源apk反编译到目标目录下,-o表示output,输出路径


Android编译,打包,签名,混淆和反编译相关知识_第4张图片

反编译后的目录结构如下:

Android编译,打包,签名,混淆和反编译相关知识_第5张图片

AndroidManifest.xml 是Android项目中的清单文件,可以直接打开查看

res 是资源文件,layout和 value 都在这里

smali 文件夹是相关的Java代码转换为 Smali 语言后的文件,Smali相关的语法在这里不做详细展开,可以参考书籍《Android软件安全与逆向分析》

将smali文件重新编译成apk文件,编译后的apk是未签名的,(汉化apk就是反编译后替换资源重新编译的结果)。我们也可以修改smali文件,比如打开日志开关等,达到我们研究的效果。

2.    Apk编译打包过程

    从我们在Android Studio中,点击run,到app运行在手机上,之间究竟发生了什么,代码和资源是怎么变成APK的,而APK又是怎么安装上去,并能执行的呢。

Android编译,打包,签名,混淆和反编译相关知识_第6张图片

我们或许都能说出来像上图这样一个简单的过程:Android工程编译打包为APK,签名后通过ADB push到设备或者模拟器上安装。但是再深入就蒙了。

Apk打包过程

我们先看看从Android在线文档找来的APK文件构建流程图,如下(方形为对象,圆形为动作)。


Android编译,打包,签名,混淆和反编译相关知识_第7张图片

流程概述:

(1)    打包资源文件----工程的资源文件(res文件夹下的文件),通过AAPT打包成R.java类(资源索引表),以及.arsc资源文件

aapt-Android Asset Packaging Tool(android资源打包工具)

(2)    如果有aidl,调用build-tools下的aidl可执行文件生成对应的Java接口类

(3)    我们有了R.java和aidl生成的Java文件,再加上工程的源代码,现在可以使用javac进行正常的java编译生成class文件了。

(4)    源码class文件和第三方jar或者library通过dx工具打包成dex文件。dx工具的主要作用是将java字节码转换成Dalvik字节码,在此过程中会压缩常量池,消除一些冗余信息等。

(5)    apkbuilder工具会将所有没有编译的资源,.arsc资源,.dex文件打包到一个完成apk文件中。

(6)    签名,APK需要签名才能在设备上进行安装,通过配置的签名文件(debug和release都有),jarsigner工具会对齐签名。得到一个签名后的apk,signed.apk

(7)    zipAlign工具对签名的signed.apk进行对齐处理,所谓对齐,主要过程是将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。对齐的作用主要是为了减少运行时内存的使用。

(8)    安装,install其实相当于apk资源的一个拷贝和解析的过程

3.    Apk签名

    为什么要使用签名:试想你开发了一个名为robot.apk的项目,将它发布到了android应用商店供用户下载使用。第二天,一个你不认识的开发人员也开发了一个名为robot.apk的项目,将它发布到了应用商店。此时问题就出现了,因为你们的APP名称相同,所以他的APP将你发布的APP给覆盖掉了,从今以后用户在应用商店下载的名为robot的APP都不是你开发的,而是他后开发的那个。

使用系统签名能获取系统权限,不同的签名apk无法覆盖安装原来的应用,防止篡改,如果相同包名的应用签名不同,系统会要求你采用不同的包名。

什么是签名:就是给APP加了一个唯一的密码。这样的情况下,第二天那个人发布他的robot.apk的时候,应用商店发现当前已经有一个同名的apk存在,就要求他输入这个唯一的签名,只有输对了这个密码,才会让他继续发布这个APP并覆盖掉之前你发布的APP,否则,他只有将他的APP改名称再发布。签名保证了你的APP的安全性!

为了防止APK在传送的过程中被第三方篡改,Google 引入了签名机制。

签过名的APK文件比未签名的 APK 文件多了一个 META-AF 文件夹,包含以下三个文件。签名的信息就在这三个文件中。

MANIFEST.MF

CERT.RSA

CERT.SF

如何查看一个apk的签名?

解压CERT.RSA

方法1:命令  keytool -printcert -file   CERT.RSA

方法2:重命名成p7b,然后双击可以查看

签名的方法思路是:先创建签名文件,然后引用,这里说明下再Android Studio中使用release签名的方法

//Android Studio配置keystore签名

signingConfigs {

    release {

        keyAlias 'android'

        keyPassword 'android'

        storeFile file('../keystore/release-platform.jks')

        storePassword 'android'

    }

    debug {

        keyAlias 'androiddebugkey'

        keyPassword 'android'

        storeFile file('../keystore/debug.keystore')

        storePassword 'android'

    }

}

这样编译出来的apk使用的就是正式的签名

buildTypes {

release {

    signingConfig signingConfigs.release    }

debug {

        signingConfig signingConfigs.release    }

}

4.    混淆

打包过程中还有一个混淆的过程很重要

混淆其实是包括了代码压缩、代码混淆以及资源压缩等的优化过程。依靠ProGuard,混淆流程将主项目以及依赖库中未被使用的类、类成员、方法、属性移除,这有助于规避64K方法数的瓶颈;同时,将类、类成员、方法重命名为无意义的简短名称,增加了逆向工程的难度。

混淆的具体过程这里也按下不表,有兴趣后面可以研究。

你可能感兴趣的:(Android编译,打包,签名,混淆和反编译相关知识)