哔哩哔哩:https://www.bilibili.com/video/BV1UE411A7rW?p=1

Android 逆向工程师系统培训‹第九期›( 课程目录 ):https://ke.yijincc.com/course-21.htm

安卓逆向工程师:https://ke.yijincc.com/profession/1.htm

打造年轻人的第一套安卓逆向环境!

原味镜像介绍文章:https://mp.weixin.qq.com/s/gBdcaAx8EInRXPUGeJ5ljQ
原味镜像介绍视频:https://www.bilibili.com/video/BV1qQ4y1R7wW/
下载地址:
谷歌盘:https://drive.google.com/drive/folders/1AdZ1x5G9CcJGXiLqGL9mhDJWlRz8KZl_?usp=sharing
GoFile:https://gofile.io/d/GeqM2O
百度盘:链接:https://pan.baidu.com/s/1anvG0Ol_qICt8u7q5_eQJw 提取码:3x2a
阿里盘:http://49.235.84.125:8080/r0env
登录时用户名:root 密码:toor

1. 逆向环境配置

1. java 开发环境:java jdk、java jre

java jdk 最好安装 jdk8 的最新版本,如果安装更高的 java 版本,一些逆向工具可能使用不了。

安装 java jdk8 的时候会自动弹出 对应 jre 的安装。

2. 安卓开发环境:安卓 sdk、ndk

安卓 sdk 和 ndk 下载完成后,直接解压,然后配置环境变量即可。。。
        也可以通过 android studio 进行 sdk 和 ndk 的安装

通过 Android studio下载的 sdk 中没有 tools 文件夹的解决办法:
                https://blog.csdn.net/General_Ma/article/details/104707265/

sdk 主要配置两个目录:tools、platform_tools

ndk 的安装:官网下载 ( https://developer.android.google.cn/ndk/ )  ndk 进行安装

2. APK 文件结构

APK 是 Android PacKage 的缩写,即 Android 安装包。apk 文件也就是 Android 打包流程的产物。那么 apk 是一个什么类型的文件?它包含了一些什么内容? 弄清楚了这些,我们就可以带着目的性,去分析打包流程,可以更好的关注 apk 文件中的这些内容是在打包流程的哪个过程中产生,以及是如何产生的。

众所周知,apk 文件本质上其实是一个 zip 格式的压缩包。想要知道其中包含了什么,改后缀然后用解压缩工具即可打开任何一个APK文件。 如果有 代码混淆 加密,通过普通解压缩工具打开里面的文件或目录会看到各种乱码

apk 概览

  • assets (程序资源目录)
  • META-INF(签名证书目录)
  • res(界面布局/图片资源目录)
  • AndroidManifest.xml(APK属性/权限/组件声明)
  • classes.dex(Android 虚拟机可执行字节码)
  • resources.arsc(字符串/资源索引文件)

图示:

这里解压了某个未经过 加固加壳 或者 其他手段加密的 Android 安装包文件,以下为结果截图:

https://www.sohu.com/a/149758866_675634

主要注意红色标注部分,这一些文件和文件夹是一个 Android 应用基本都具备的。而其他的一些文件和文件夹则是一些第三方库,或者是其他一些代码生成的。 接下来,依次大概介绍一下这些文件和文件夹的作用。

  • AndroidManifest.xml:这是 Android 应用的全局配置文件,它包含了这个应用的很多配置信息,例如包名、版本号、所需权限、注册的服务等。可以根据这个文件在相当程度上了解这个应用的一些信息。该文件目前状态是被编译为二进制的 XML 文件,可以通过一些工具(如 apktool)反编译后进行查看。Analyze apk 是一个很不错的 apk 分析(~~hack 入门~~)工具。我们可以通过它直接反编译看到原始的 AndroidManifest.xml 文件。

  • assets 文件夹:assets 文件夹用于保存需要保持原始文件的资源文件夹,开发过程中拖了什么到里面,打包完之后里面还是什么。一般用于存放音频,网页(帮助页面之类的),字体等文件。主要需要知道的点是,它与 res 文件夹的区分以及如何在应用中访问该文件夹的资源,如它可以有多级目录而 res 则只有两级。

  • dex 文件:classes.dex 文件是 Android 系统运行于 Dalvik Virtual Machine 上的可执行文件,也是Android 应用程序的核心所在。项目工程中的 Java 源码通过 javac 生成 class 文件,再通过 dx 工具转换为 classes.dex,注意到我们这里有 classes2.dex 和 classes3.dex。这是方法数超过一个 dex 的上限,分 dex 的结果。分 dex 在 Android 5.0 之前需要开发者自行完成,5.0 后 dx 自带支持。dex 文件的数据结构不算复杂,如下图所示。目前一些热补丁有关的技术,主要便是对 dex 做各种处理。

  • lib 文件夹:该目录存放着应用需要的 native 库文件。比如一些底层实现的图片处理、音视频处理、数据加密的库以 so 库的形式在该文件夹中。而该文件夹下有时会多一个层级,这是根据不同CPU 型号而划分的,如 ARM,ARM-v7a,x86等。

  • META-INF 文件夹:该目录的主要作用是用于保证 APK 的完整性以及安全性。该文件夹下,主要有三个文件。
            MANIFEST.MF:这个文件保存了 整个apk文件所有文件的文件名 + SHA-1后的编码值。
                                        这也就意味着,MANIFEST.MF 象征着 apk 包的完整性。
            XXX.RSA:这个文件保存了公钥和加密方式的信息。
            XXX.SF:这个文件与 MANIFEST.MF 的结构一样,只是其编码会被被私钥加密。
                               这样一来每次安装时,通过该文件夹中的文件,就可以完成验证的过程。
                               如果 apk 包被改变了,而篡改者没有私钥生成 CERT.SF,则无法完成校验。

  • res 文件夹:顾名思义,该文件夹是资源文件夹。它里面存放的所有文件都会被映射到 R 文件中,生成对应的资源 ID,便于代码中通过 ID 直接访问。其中的资源文件包括了动画(anim),图像(drwable),布局(layout),常量值(values),颜色值(colors),尺寸值(dimens),字符串(strings),自定义样式(styles)等。

  • resource.arsc 文件:这个文件可以说是所有文件中结构最复杂的。它记录了资源文件,资源文件位置(各个维度的路径)和资源 id 的映射关系。并且将所有的 string 都存放在了 string pool 中,节省了在查找资源时,字符串处理的开销。

    我们可以使用 Androdi Studio 2.2 Preview 中的新功能 Analyze apk (这个新功能用来分析 apk 非常好用,强烈推荐各位读者可以尝试一下)来看看它到底包含了些什么,一图胜过千言:

    可以看到,首先是有个 package 可选,实际上 resource.arsc 是可以包含多个 package 的资源的。 然后可以看到一个 Resource Types 的列表。这里看到的是 drawable 的 type。 右边显示了有多少个 drawable 以及多少项 configurations,以及表的具体内容为 ID - Name - 各个维度的值(在这里即是资源的路径),通过这个,我们可以完成通过 id + 对应的 configuration 获取对应资源的操作。

    而后面要提到资源混淆的原理,就是修改这里各个维度的值,并修改对应 res 里面的文件夹以及文件名实现的。

    具体其完整的数据结构比较复杂,在这里就不展开说了,有兴趣的读者可以自行查阅信息,甚至写一个 parser 出来也是非常有意思的。

总结:

3. APK 打包流程

android配置构建 官方文档

Android应用程序(APK)的编译打包过程:https://www.cnblogs.com/sjm19910902/p/6416022.html

Android APK打包流程:https://www.cnblogs.com/xunbu7/p/7345912.html
APK打包流程:https://blog.csdn.net/loongago/article/details/89646920
apk文件以及打包流程:https://blog.csdn.net/mysimplelove/article/details/93516904
浅述Android Apk打包流程:https://www.jianshu.com/p/d29c37dda256
Android 打包之流程:https://www.jianshu.com/p/d22f52a6a6fb

APK打包安装过程:https://segmentfault.com/a/1190000004916563

原创]记一次APP脱壳重打包过程:https://bbs.pediy.com/thread-220151.htm

下图的是官网对于Android编译打包流程的介绍。

官方的介绍非常笼统,简而言之,其大致流程就是: 编译–>DEX–>打包–>签名和对齐

来一张外国大神的图片(注:这张图少了签名的步骤)

流程图:

重点关心的是

  • (1)这个过程的输入是什么?
  • (2)这个过程的输出是什么?
  • (3)这个过程使用了什么工具?至于使用什么参数,可以自己去看对应命令的帮助文件,或者在网上搜索,

aapt -> aidl -> javac -> dx(dex) -> apkbuilder -> jarsigner -> zipalign

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

名称 功能介绍 在操作系统中的路径
aapt Android 资源打包工具 ${ANDROID_SDK_HOME}/platform-tools/appt
aidl

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

( aidl 全名 Android Interface Definition Language,即Android接口定义语言 )

${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 包 (SDK3.0 之后弃用而使用 sdklib.jar 打包 apk ${ANDROID_SDK_HOME}/tools/opkbuilder
jarsigner .jar文件的签名工具 ${JDK_HOME}/jarsigner或/usr/bin/jarsigner
zipalign 字节码对齐工具 ${ANDROID_SDK_HOME}/tools/zipalign

补充:apkbuilder 在 SDK3.0 之前使用 apkbuilder 去打包,在 SDK3.0 之后就弃用了,而使用 sdklib.jar 打包 apk。

下面各个工具在打包中的用法:

编译打包步骤:

  • 1. 打包资源文件,生成R.java文件。打包资源的工具是aapt(The Android Asset Packaing Tool)(E:\Documents\Android\sdk\build-tools\25.0.0\aapt.exe)。在这个过程中,项目中的AndroidManifest.xml文件和布局文件XML都会编译,然后生成相应的R.java,另外AndroidManifest.xml会被aapt编译成二进制。存放在APP的res目录下的资源,该类资源在APP打包前大多会被编译,变成二进制文件,并会为每个该类文件赋予一个resource id。对于该类资源的访问,应用层代码则是通过resource id进行访问的。Android应用在编译过程中aapt工具会对资源文件进行编译,并生成一个resource.arsc文件,resource.arsc文件相当于一个文件索引表,记录了很多跟资源相关的信息。
  • 2. 处理aidl文件,生成相应的Java文件。这一过程中使用到的工具是aidl(Android Interface Definition Language),即Android接口描述语言(E:\Documents\Android\sdk\build-tools\25.0.0\aidl.exe)。aidl工具解析接口定义文件然后生成相应的Java代码接口供程序调用。如果在项目没有使用到aidl文件,则可以跳过这一步。
  • 3. 编译项目源代码,生成class文件。项目中所有的Java代码,包括R.java.aidl文件,都会变Java编译器(javac)编译成.class文件,生成的class文件位于工程中的bin/classes目录下。
  • 4. 转换所有的class文件,生成classes.dex文件。dx工具生成可供Android系统Dalvik虚拟机执行的classes.dex文件,该工具位于(E:\Documents\Android\sdk\build-tools\25.0.0\dx.bat)。任何第三方的libraries.class文件都会被转换成.dex文件。dx工具的主要工作是将Java字节码转成成Dalvik字节码、压缩常量池、消除冗余信息等。
  • 5. 打包生成APK文件。所有没有编译的资源,如images、assets目录下资源(该类文件是一些原始文件,APP打包时并不会对其进行编译,而是直接打包到APP中,对于这一类资源文件的访问,应用层代码需要通过文件名对其进行访问);编译过的资源和.dex文件都会被apkbuilder工具打包到最终的.apk文件中。打包的工具apkbuilder位于 android-sdk/tools目录下。apkbuilder为一个脚本文件,实际调用的是(E:\Documents\Android\sdk\tools\lib)文件中的com.android.sdklib.build.ApkbuilderMain类。
  • 6. 对APK文件进行签名。一旦APK文件生成,它必须被签名才能被安装在设备上。在开发过程中,主要用到的就是两种签名的keystore。一种是用于调试的debug.keystore,它主要用于调试,在Eclipse或者Android Studio中直接run以后跑在手机上的就是使用的debug.keystore。另一种就是用于发布正式版本的keystore。
  • 7. 对签名后的APK文件进行对齐处理。如果你发布的 apk 是正式版的话,就必须对APK进行对齐处理,用到的工具是zipalign(E:\Documents\Android\sdk\build-tools\25.0.0\zipalign.exe)。对齐的主要过程是将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。对齐的作用就是减少运行时内存的使用。

上述流程都是Android Studio在编译时调用各种编译命令自动完成的

第一步:打包资源文件,生成R.java文件

编译 R.java 类 需要用到 AndroidSDK 提供的 aapt 工具,aapt 参数众多,以下是主要参数:

 -d  one or more device assets to include, separated by commas  -f  force overwrite of existing files  -g  specify a pixel tolerance to force images to grayscale, default 0  -j  specify a jar or zip file containing classes to include  -k  junk path of file(s) added  -m  make package directories under location specified by -J  -u  update existing packages (add new, replace older, remove deleted files)  -v  verbose output  -x  create extending (non-application) resource IDs  -z  require localization of resource attributes marked with  localization="suggested"  -A  additional directory in which to find raw asset files  -G  A file to output proguard options into.  -F  specify the apk file to output  -I  add an existing package to base include set  -J  specify where to output R.java resource constant definitions  -M  specify full path to AndroidManifest.xml to include in zip  -P  specify where to output public resource definitions  -S  directory in which to find resources.  Multiple directories will be scann  

aapt 编译 R.java 文件具体如下:

需要进入应用程序目录,新建一个gen目录,没有gen目录,命令将会出现找不到文件的错误!

命令成功执行后将会在 gen 目录下生成成包结构的目录树,及 R.java 文件。

列子:

aapt 资源编译

  1. 编译assets目录和res/raw目录下的资源
  2. 编译res目录下的资源文件
  3. 给res目录下的每个资源赋予一个资源ID,生成resource.arsc资源索引文件
  4. 解析并编译AndroidMainifest.xml
  5. 资源打包成*.ap_,资源ID常量定义自R.java

资源索引

aapt 给每一个非 assets 目录的资源定义一个资源ID,它是一个4字节(byte = 32bit)的数字,格式是PPTTNNNN,PP代表资源所属的包(package),TT代表资源的类型(Type),NNNN代表这个类型下面的资源名称(Entry ID)。

  • Package ID相当于是一个命名空间,标定资源的来源。系统资源的命名空间,它的package ID等于0x01;自己的APP资源名称空间,Package ID一般定义为0x7f。
  • Type ID是指资源的类型ID。资源的类型都有animator、anim、color、drawable、layout、menu、raw、string和xml等等若干种,每一种都会被赋予一个ID。
  • Entry ID是指每一个资源在其所属的资源类型中所出现的次序。

代码编译和打包

  • AIDL -> 生成对应的java接口
  • Javac -> 生成.class文件
  • dex-> 生成dex文件
  • APkBuilder:aapt打包好的资源、dex打包好的代码文件、第三方库资源和jar文件、native -> apk

第二步:处理AIDL文件,生成对应的.java文件

当然,有很多工程没有用到AIDL,那这个过程就可以省了

将 .aidl 文件生成 .java 文件需要用到 AndroidSDK 自带的 aidl 工具,此工具具体参数如下:

-I<DIR>    search path for import statements.
-d<FILE>   generate dependency file.
-p<FILE>   file created by --preprocess to import.
-o<FOLDER> base output folder for generated files.
-b         fail when trying to compile a parcelable.
值得注意的是:这个工具的参数与参数值之间不能有空格,Google也有对工资不满意的工程师! 

例子:

第三步:编译Java文件,生成对应的.class文件

javac 命令用法如下:

其中,可能的选项包括:  -g                         生成所有调试信息  -g:none                    不生成任何调试信息  -g:{lines,vars,source}     只生成某些调试信息  -nowarn                    不生成任何警告  -verbose                   输出有关编译器正在执行的操作的消息  -deprecation               输出使用已过时的 API 的源位置  -classpath <路径>            指定查找用户类文件和注释处理程序的位置  -cp <路径>                   指定查找用户类文件和注释处理程序的位置  -sourcepath <路径>           指定查找输入源文件的位置  -bootclasspath <路径>        覆盖引导类文件的位置  -extdirs <目录>              覆盖安装的扩展目录的位置  -endorseddirs <目录>         覆盖签名的标准路径的位置  -proc:{none,only}          控制是否执行注释处理和/或编译。  -processor <class1>[,<class2>,<class3>...]要运行的注释处理程序的名称;绕过默认的搜索进程  -processorpath <路径>        指定查找注释处理程序的位置  -d <目录>                    指定存放生成的类文件的位置  -s <目录>                    指定存放生成的源文件的位置  -implicit:{none,class}     指定是否为隐式引用文件生成类文件  -encoding <编码>             指定源文件使用的字符编码  -source <版本>               提供与指定版本的源兼容性  -target <版本>               生成特定 VM 版本的类文件  -version                   版本信息  -help                      输出标准选项的提要  -Akey[=value]              传递给注释处理程序的选项  -X                         输出非标准选项的提要  -J<标志>                     直接将 <标志> 传递给运行时系统  

例子:

javac -encoding utf-8 -target 1.5 -bootclasspath E:\Androiddev\android-sdk-windows2.2\platforms\android-3\android.jar -d bin src\com\byread\reader\*.java gen\com\byread\reader\R.java

第四步:把.class文件转化成Davik VM支持的.dex文件

将工程 bin目录下的 class 文件编译成 classes.dex,Android 虚拟机只能执行 dex 文件。

例子:

第五步:打包生成未签名的 .apk 文件

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

apkbuilder  工具用法如下:

-v      Verbose.
-d      Debug Mode: Includes debug files in the APK file.
-u      Creates an unsigned package.
-storetype Forces the KeyStore type. If ommited the default is used.  -z      Followed by the path to a zip archive.  Adds the content of the application package.  -f      Followed by the path to a file.  Adds the file to the application package.  -rf     Followed by the path to a source folder.  Adds the java resources found in that folder to the application  package, while keeping their path relative to the source folder.  -rj     Followed by the path to a jar file or a folder containing  jar files.  Adds the java resources found in the jar file(s) to the application  package.  -nf     Followed by the root folder containing native libraries to  include in the application package.

列子:

apkbuilder  ${output.apk.file} -u -z  ${packagedresource.file} -f  ${dex.file}  -rf  ${source.dir}  -rj  ${libraries.dir}

第六步:对未签名 .apk 文件进行签名

通过 jarsigner 命令用证书文件对未签名的 APK 文件进行签名

【输入】未签名的.apk文件
【输出】签名的.apk文件
【工具】jarsigner

用法:jarsigner [选项] jar 文件别名  jarsigner -verify [选项] jar 文件  [-keystore <url>]           密钥库位置
[-storepass <口令>]         用于密钥库完整性的口令
[-storetype <类型>]         密钥库类型
[-keypass <口令>]           专用密钥的口令(如果不同)
[-sigfile <文件>]           .SF/.DSA 文件的名称
[-signedjar <文件>]         已签名的 JAR 文件的名称
[-digestalg <算法>]    摘要算法的名称
[-sigalg <算法>]       签名算法的名称
[-verify]                   验证已签名的 JAR 文件
[-verbose]                  签名/验证时输出详细信息
[-certs]                    输出详细信息和验证时显示证书
[-tsa <url>]                时间戳机构的位置
[-tsacert <别名>]           时间戳机构的公共密钥证书
[-altsigner <类>]           替代的签名机制的类名
[-altsignerpath <路径列表>] 替代的签名机制的位置
[-internalsf]               在签名块内包含 .SF 文件
[-sectionsonly]             不计算整个清单的散列
[-protected]                密钥库已保护验证路径
[-providerName <名称>]      提供者名称
[-providerClass <类>        加密服务提供者的名称
[-providerArg <参数>]] ... 主类文件和构造函数参数  

只需要按步骤生成 MANIFEST.MF, CERT.RSA,CERT.SF 并放入META-INF 文件夹即可。

第七步:对签名后的.apk文件进行对齐处理

不进行对齐处理是不能发布到Google Market的

【输入】签名后的.apk文件
【输出】对齐后的.apk文件
【工具】zipalign工具

知道了这些细节之后,我们就可以实现很多我们想实现东西了,比如:自动化,我们可以使用某种脚本,像Windows下的批处理,linux下的Bash,Java下的Ant,Python、Perl这样的脚本语言,甚至直接用Java、.net这们的强类型语言也是可以的。

以上便是APK打包的整个流程,我们再来总结一下:

  • 除了assets和res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理;
  • 除了assets资源之外,其它的资源都会被赋予一个资源ID;
  • 打包工具负责编译和打包资源,编译完成之后,会生成一个resources.arsc文件和一个R.java,前者保存的是一个资源索引表,后者定义了各个资源ID常量。
  • 应用程序配置文件AndroidManifest.xml同样会被编译成二进制的XML文件,然后再打包到APK里面去。
  • 应用程序在运行时通过AssetManager来访问资源,或通过资源ID来访问,或通过文件名来访问。

4. APK 安装流程

Android中APK安装流程解析:https://blog.csdn.net/mysimplelove/article/details/93619361

APK安装后最终放置在了哪里?安装APP到底是怎样的一个过程?如何打开并修改APK程序包?

如果使用 WinHex 打开apk文件,从文件头就可以看出APK安装包其实就是一个zip格式的压缩包,所以我们只需将apk文件的后缀修改为 .zip 或 .rar ,就可以轻松的在电脑上打开并查看apk软件内部的文件和数据(当然你也可以使用手机R.E管理器查看)。

Android 安装 apk包的五种方式:

  • 1, 通过工具安装:R.P 或 ES等管理工具,有安装界面。
  • 2,adb install 安装,无安装界面。
  • 3,android market 在线安装,无安装界面。
  • 4,直接 copy 到系统目录/system/app下,无安装界面。此目录下的应用一般是系统自带的系统级程序和常归应用。
  • 5,pm(android 系统自带工具) 命令行安装,无安装界面。

apk 文件在安装到手机过程中,涉及到如下几个目录:

/system/framwork:    保存的是资源型的应用程序,它们用来打包资源文件。
/data/app-private:   保存受DRM保护的私有应用程序。
/vendor/app:         保存设备厂商提供的应用程序。
/system/app           ------- 系统自带的应用安装目录,获得 adb root权限才能删除
/data/app             ------- 用户程序安装的目录,安装时把 apk文件 复制到 此目录
/data/data            ------- 存放应用程序的数据
/data/dalvik-cache    将 apk 中的 dex文件 安装到 dalvik-cache 目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)/data/system:该目录下的packages.xml文件,类似于Windows的注册表,记录了系统的permissions,每个apk的name,codePath,,version,userid等信息,这些信息主要通过AndroidManifest.xml文件解析获取,解析完apk后将更新信息写入这个文件并保存到flash,下次开机的时候直接从里面读取相关信息并添加到内存相关列表中。当有APK安装、升级或者删除时会更新这个文件。/data/system/packages.xml /data/system/packages.list: packages.list指定了应用的默认存储位置/data/data/com.xxx.xxx;package.xml中包含了该应用 权限、应用包名、APK的安装位置、版本、userID等信息,并且两者都有同一个userld。之所以每个 应用都要一个userId,是因为Android在系统设计上把每个应用当做Linux系统上的一个用户对待, 这样就可以利用已有的Linux用户管理机制来设计Android应用,比如应用目录,应用权限,应用进程管理等。

安装过程:

当我们新安装一个应用的时候,通常系统会执行以下流程:

校验apk包签名 → 复制程序包到 /data/app 目录 → 建立 /data/data/com.xxx 数据目录 → 提取释放lib文件 → dexopt优化classes.dex处理后释放到 /data/dalvik-cache 目录

在这个过程中,Android 系统服务还会更新以下系统文件:

  • /data/system/packages.list   --  分配存储APP的uid/gid,也就是用户/所属组
  • /data/system/packages.xml  --  记录保存APP权限、签名证书、安装路径、版本信息等

由此可见,我们安装好的软件程序包被原本不动存放在 /data/app 目录之下,数据目录则被安放在 /data/data/pkg_name(包名) 目录之中。而卸载过程则相反,进行删除相关文件处理。

整个 apk 安装流程:

  • 复制 APK 到 /data/app 目录 下,解压(会放到 data/app/包名/ 目录下面,同时 apk 中的 so 文件 也会拷贝到此目录下的 lib 文件目录中。)并扫描安装包。而系统出厂的 apk 被放到 /system分区下,这就是没有ROOT手机前,我们无法删除系统app的原因。( 下面 是用 MT 管理器 (需要获取root 权限) 打开)
  • 资源管理器解析 APK 里的资源文件。
  • 解析 AndroidManifest.xml(Android应用程序的解析过程就是解析这个xml文件的过程)。解析的内容会被更新到/data/system/packages.xml 和 /data/system/packages.list中,packages.list 中指名了该应用默认存储的位置,packages.xml 中包含了该应用申请的权限、签名和代码所在位置等信息,并且两者都有一个 相同的 userId。之所以每个应用都有一个userId,是因为Android 在系统设计上把每个应用当作Linux系统上的一个用户对待,这样就可以利用已有的Linux上用户管理机制来设计Android应用,比如应用目录,应用权限,应用进程管理等。做完以上操作,就相当于应用在系统注册了,可以被系统识别。接下来就得保存应用的执行文件了,根据 packages.xml中指定的 codePath,创建一个目录,即在 /data/data/ 目录 下创建对应的 应用数据目录。apk会被命名成 base.apk 并拷贝到此,其中 lib 目录用来存放 native 库
  • 然后对 dex 文件进行优化,并保存在 dalvik-cache目录 下。其命名规则是 apk路径+classes.dex。(此时应用就可以运行了,但如果每次应用运行还得去base.apk中取dex文件,效率就太低了。为了提升效率,Android系统在应用安装时还会做些优化操作,把所有可运行的dex文件单独提取放在一块并做些优化。在Dalvik模式下,会使用dexopt把base.apk中的dex文件优化为odex,存储在/data/dalvik-cache中,如果是ART模式,则会使用dex2oat优化成oat文件也存储在该目录下,并且文件名一样,但文件大小会大很多,因为ART模式会在安装时把dex优化为机器码,所以在ART模式下的应用运行更快,但apk安装速度相对Dalvik模式下变慢,并且会占用更多的ROM。)
  • 将 AndroidManifest 文件解析出的四大组件信息注册到 PackageManagerService 中。
  • 安装完成后,发送广播。
  • 显示icon图标:应用程序经过PMS中的逻辑处理后,相当于已经注册好了,如果想要在Android桌面上看到icon图标,则需要Launcher将系统中已经安装的程序展现在桌面上。

安装图解和过程描述:

安装过程并没有把资源文件, assets目录下文件拷贝出来,他们还在apk包里面呆着,所以,当应用要访问资源的时候,其实是从apk包里读取出来的。其过程是,首先加载apk里的resources.arsc(这个文件是存储资源Id与值的映射文件),根据资源id读取加载相应的资源。

删除安装过程:就是删除在上述三个目录下创建的文件及目录。

总体说来就两件事情:拷贝APK解析APK,解析APK主要是解析 AndroidManifest.xml,以便获得它的安装信息。在安装的过程中还会这个应用分配 Linux用户ID 和 Linux用户组ID(以便它可以在系统中获取合适的运行权限)。

涉及的三个进程

  • PackageInstaller进程:PackageInstaller事实上是一个应用,它负责APK安装以及卸载过程中与用户的交互流程。
  • SystemServer进程:该进程主要运行的是系统服务,APK的安装、卸载和查询都由PackageManagerService负责,它也是Android核心系统服务的一种,在SystemServer里初始化系统服务的时候被启动。
  • DefaultContainerService进程:DefaultContainerService也是一个单独的进程,它主要负责检查和复制设备上的文件,APK的复制就是由DefaultContainerService来完成的。

apk 解析流程

  • Android不同类型
    /system/framwork:保存的是资源型的应用程序,它们用来打包资源文件。
    /system/app:保存系统自带的应用程序。
    /data/app:保存用户安装的应用程序。
    /data/app-private:保存受DRM保护的私有应用程序。
    /vendor/app:保存设备厂商提供的应用程序。
  • DEX的dexopt流程
    dexopt操作实际上对DEX文件在执行前进行一些优化,但是不同的虚拟机操作有所不同。
    Davlik:将dex文件优化生成odex文件,这个odex文件的后缀也是dex,保存在/data/dalvik-cache目录下。
    ART:将dex文件翻译生成oat文件

如何修改 & 反编译APK软件包?

如果只是修改程序包的一些图片/assets资源,直接在电脑上用解压缩工具,解压后就可以修改替换,但是重新打包后需要重新签名,否则没有签名或者签名校验不正确的应用是无法安装成功的。

而如果想要修改apk包中其他的已经编译后的文件,则需要反编译。由于 Android 本质上就是一个 Java 虚拟机,而 classes.dex 文件则是众多 .class 文件的打包集合,一般我们先要使用 dex2jar 将 classes.dex 解包为 Java jar 文件,然后再通过 JD-GUI 将 jar 文件的 .class 文件反编译为 .java 源码。

整个反编译dex的过程原理大致简单来说就是这样,但是实际操作起来难度不小,因为很多程序都经过了混淆加密处理(比如QQ,微信等等大公司的软件不可能让人分分钟反编译破解,否则整个安卓APP世界还不乱套了...)

对于apk程序包其他的一些xml布局文件,直接打开是乱码怎么办?dex字节码都能反编译成功,xml就更简单一些了。网上有很多现成的工具,比如 AXMLPrinter2.jar ,可以直接解码反编译xml文件,当然执行 .jar文件需要在电脑上事先安装好 JRE(Java运行环境)哟!

关于 Android 应用的反编译这里仅是简单介绍一下原理和过程,明白了解一下就好。具体的方法百度一搜一大把。

虚拟机

安卓逆向_1 --- 逆向环境配置、APK 文件结构、APK 打包流程相关推荐

  1. Android APK文件结构 完整打包编译的流程 APK安装过程 详解

    Android apk文件结构 打包编译的流程 Android官网 配置构建 流程 Configure your build The build process APK文件结构 assets res ...

  2. ionic环境配置,生成apk

    什么是Ionic3框架? Ionic3框架是一个混合开发框架,其本身依赖于Angular,Sass,Cordova. 使用Ionic3框架可以做什么? 使用Ionic3可以使用前端相关技术快速开发多平 ...

  3. yolov5 6.0版本->onnx->ncnn +安卓部署 附加ncnn环境配置 保姆级详细教程

    目标检测:yolov5 6.0版本 ncnn环境安装 至 +安卓部署 一条龙教程 文章目录 背景 一.准备阶段 1.参考文章 #2.流程 二.pt模型->onnx 三.Windows下ncnn环 ...

  4. mac flutter 开发环境配置 从0到1 流程

    本文首发简书,本人为原作者,转至掘金 转载请注明出处 原文连接 掘金连接 https://www.jianshu.com/p/c55ad0e8f24f 高能提示:文章字数不多,图很多,请做好战斗准备 ...

  5. Mac Futter 开发环境配置 从0到1 流程

    前言 写这篇文章的原因是我自己的macbook开不开机,返修后,所有开发环境全部没有了,正好要重新配置开发环境,所以写一个从零配置的文章 因为flutter涉及到跨平台开发,所以预想中会包含四部分 m ...

  6. Win11安卓应用使用及环境配置教程

    就在昨天,很多小伙伴都说可以安装Windows11的安卓子系统了,不管是实体机和虚拟机都可以安装,这是Windows11发布时大家最期待的功能,大家的热情都很高,第一时间就把收集来的教程全部整理了一下 ...

  7. 超简单配置Android持续集成自动化打包流程 - GitHub+GitLab-CI+蒲公英+钉钉

    我的Github:github.com/BzCoder GitLab-CI的相关语法:fennay.github.io/gitlab-ci-c- 欢迎各位留言讨论 场景 为了优化工作流程,解放开发人员 ...

  8. Android逆向 小米5X 抓包调试 环境配置

    1. 线刷救砖 2. 解除BL锁 3. 一键刷入recovery工具 刷机教程 4. 刷机需要安装的 安装包 和 面具 adb push E:\Download\shuaji\AospExtended ...

  9. 100天精通Andriod逆向——第3天:真机环境配置

    目录 一.真机环境配置(刷机基础教程) 1.1 刷机方式的分类 1.2 刷机包的分类 1.3 谷歌手机工厂镜像 1.4 简单配置 1.5 进入 Bootloader 模式 1.6 安装谷歌驱动 1.7 ...

最新文章

  1. Annotataion
  2. 只有2GB内存在20亿个整数中找到出现次数最多的数
  3. mysql导入100000000需要多久_MYSQL批量插入千万级数据只需百秒
  4. VTK:直线网格之RectilinearGrid
  5. 分布式数据库——TiDB的介绍和基本原理
  6. rocketmq 同步刷盘和异步刷盘以及主从复制之同步复制和异步复制你理解了吗
  7. 如何html中添加动态图片,把动态图片添加到视频画面中 视频添加自定义动态图片 视频加动态logo...
  8. 解决:java.lang.IllegalStateException: ApplicationEventMulticaster not initialized
  9. 带属性的字符串(NSMutableAttributedString)的使用
  10. 华为Mate 30系列或下血本采用双主摄方案:CMOS尺寸破纪录
  11. Android之Handler
  12. 使用shell编写九九乘法表,mysql分库备份
  13. c# 委托和委托事件
  14. JSP面试题(重要)
  15. 华为荣耀6 root
  16. 2017到2018总结与展望
  17. 宠物收养所(c++)
  18. 如何获取股票交易数据接口?
  19. Python实现旋转按钮控制小风扇
  20. 推流地址 java_如何通过代码生成推流地址和播放地址?

热门文章

  1. 简化Swagger使用的自制Starter:spring-boot-starter-swagger,欢迎使用和吐槽
  2. 谷歌、微软、OpenAI等巨头七大机器学习开源项目 看这篇就够了
  3. 【LeetCode】3月31日打卡-Day16-数组排序算法汇总
  4. RISC-V正在采取行动,避免MIPS类的碎片化
  5. python模拟http请求
  6. JavaWeb从开发环境搭建,到第一个servlet程序(图文)
  7. p1470 Longest Prefix
  8. LUOGU P4016 负载平衡问题
  9. HTML中关于图像和表格,链接等的知识
  10. 20155234 2016-2017-2 《Java程序设计》第5周学习总结