APK安装在安卓机器上的,相当于就是windows的exe文件
APK实际上是个压缩包 只要是压缩的东西 .jar也是压缩包 里面是.class(java编译后的一些东西)
APK是Android Package的缩写,即Android安装包。而apk文件其实就是一个压缩包,我们可以将apk文件的后缀改为.zip来观察apk中的文件。
参考文章:安卓逆向学习——APK结构_怎么学习apk结构-CSDN博客
1、结构
2、常见目录
参考文章:
安卓逆向入门笔记(一)——apk文件结构 - 『移动安全区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
3、实践
1)下载一个APK
2)解压缩看看文件目录
4、常用目录分析
1)assets文件夹
assets 这里存放的是静态资源文件(图片,视频等),这个文件夹下的资源文件不会被编译。不被编译的资源文件是指在编译过程中不会被转换成二进制代码的文件,而是直接被打包到最终的程序中。这些文件通常是一些静态资源,如图片、音频、文本文件等。
没有被编译过,拿出来可以直接用。
2)lib文件夹
lib:.so库(c或c++编译的动态链接库)。APK文件中的动态链接库(Dynamic Link Library,简称DLL)是一种可重用的代码库,它包含在应用程序中,以便在运行时被调用。这些库通常包含许多常见的函数和程序,可以在多个应用程序中共享,从而提高了代码的复用性和效率。
lib文件夹下的每个目录都适用于不同的环境下,armeabi-v7a目录基本通用所有android设备,arm64-v8a目录只适用于64位的android设备,x86目录常见用于android模拟器,x86-64目录适用于支持x86_64架构的Android设备(适用于支持通常称为“x86-64”的指令集的 CPU)
以下图中为arm64-v8a目录——为cpu的平台
因为语言分很多种
最底层机器码
再上一层是汇编代码(低级符号语言)
最上层C语言(高级符号语言)
汇编和C语言都是认机器的 代码最终都是经过CPU去执行的 认机器其实就是认CPU 不同的架构的CPU代码就不一样 编译之后的机器码就不一样
第一个是arm5 的CPU (比较老)
第二个是arm7 的CPU (目前大多数还是arm7的CPU)
第三个是arm8 的CPU (支持64位的CPU)
有时候在动态调试的时候会存在 静态分析跟动态调试的ARM代码不一样 这个有可能是真机运行的时候是使用的64位的CPU,apk里面又提供了64位的so文件。即静态分析与动态调试使用的是不同文件夹。
有时候会存在libs文件夹 是放的一些引用的第三方的java包 不单单是在APK里面 在java里面如果引用一些第三方工程 也是放在libs目录下的
3)META-INF文件夹
META-INF:在Android应用的APK文件中,META-INF文件夹是存放数字签名相关文件的文件夹,包含以下三个文件:
- MANIFEST.MF:MANIFEST.MF文件是一个摘要清单文件,它包含了apk文件中除自己以外所有文件的数字摘要。
- CERT.SF:CERT.SF文件是用于存储通过私钥加密后得到的MANIFEST.MF文件的数字签名信息以及MANIFEST.MF文件中数字摘要的数字签名信息。
- CERT.RSA:CERT.RSA文件包含了CERT.SF文件的数字签名和对文件签名时所使用的数字证书。
总之,META-INF文件夹中的文件是用于保护APK文件的完整性和真实性的重要文件,可以确保APK文件来自合法的开发者,并且没有被篡改过。(如果把APK里面的文件改了,就算只改了代码,但是已经已经和原本的签名无法对应,这时候想在安卓机上安装该APK是安装不上的 此时需要一个工具,幸运破解器去破解一下系统核心 不重签名也可以安装上)重签名的意思是改了apk需要重新签名 (雷电模拟器上面不重签名也可以安装)
现在看这些东西是不是有些不明白?什么是数字摘要、什么是数字签名、什么是数字证书什么的,没事,我们接下来讲解这些东西,让你搞明白。
APK签名机制原理
问:什么是数字摘要?
答:数字摘要是一种数学算法,将任何长度的数据转换为固定长度的唯一字符串,而且不同的明文通过Hash算法转换成固定长度的密文,其结果总是不同的,而同样的明文其摘要必定一致。数字摘要通常用于数据完整性验证和加密技术中,以确保数据在传输或存储过程中没有被篡改或损坏。数字摘要算法是单向的,即无法通过数字摘要反推出原始数据。常见的数字摘要使用的Hash算法有MD5、SHA-1、SHA-256等。这里插一嘴,现在MD5在有的情况下已经不安全了,可能会出现不同的数据加密成相同的密文,因为明文的排列是有无数种可能的,而MD5所转换的密文长度是固定的128位,无限的数据对应有限的长度是不可能永远让不同的数据转换为不同的内容的。
问:为什么会出现数字签名?
答:要回答这个问题说来话长,我们要先从信息的传输开始讲起。
对称加密:
这天小红和小明在教室里通过纸条来传递信息,但小红和小明间隔甚远,需要经过其他同学帮助才能成功传输信息,在这个过程中是无法保证信息不被泄露的,那为了这个传输的信息不被泄露就需要对信息进行加密,而加密和解密是需要一个双方都知道的密钥来进行的,加密者用密钥对明文进行加密得到密文,解密者用密钥对密文进行解密得到明文,加解密都用同样的密钥,即为对称加密。所以双方该如何确定出一个同样的密钥呢?如果由一方生成密钥,再将密钥发送给对方,那么攻击者也可以获取到密钥,就会导致加解密没有了作用。
那么什么办法可以解决这个问题呢?可以用非对称加密。
非对称加密:
在非对称加密中,密钥总是成对出现的,分别称之为公钥和私钥,私钥由自己安全保管不外泄,而公钥则可以发给网络中的任何人。用其中一把密钥加密的明文只能用另一把密钥进行解密,无法使用同一把密钥进行加解密,比如用公钥进行加密的明文只能用私钥进行解密,公钥自己没法解密。
你可能还是会有疑问,如果一方将公钥发送给另一方,自己再用私钥对明文进行加密,再把加密的数据给另一方,那这不还是会导致加解密没有了作用?又或者一方将私钥发送给另一方,自己再用公钥对明文进行加密,再把加密的数据给另一方,这不还是会被攻击者获取到私钥从而解密数据?如果非对称加密这么使用确实会出现这种问题,但是非对称加密一般不这么用,而是下面这种操作:
现在是服务器和浏览器之间的信息传输,它们之间是怎么做才能信息不外泄呢?
第一步:服务器会将非对称加密中的公钥发送给浏览器,浏览器生成一串随机数字,而这串随机数字使用服务器发送过来的公钥进行加密。
第二步:将通过公钥加密的随机数字发送给服务器,服务器接收后使用私钥进行解密,这样双方就都得到了一个同样的随机数字,而这个随机数字可以作为对称加密的密钥。
第三步:使用随机数字作为密钥对真正需要传递的数据进行加密传输。
这样就算是攻击者拦截到了服务器发送给浏览器的公钥,也只能无济于事,因为通过公钥加密的数据没法通过公钥进行解密。这套流程也被称之为SSL(安全套接字层)。
这看似很美好,但是这真的无懈可击吗?不,因为服务器和浏览器之间无法得知接收的公钥或者数据来自于谁,这样攻击者可以先将服务器发送的公钥拦截下来替换成自己的公钥,浏览器接收到之后无法辨别这个公钥是来自于谁的,只会傻傻的使用这个公钥对生成的随机数字进行加密,然后返回给服务器,攻击者再将返回的内容拦截下来,通过自己的私钥进行解密,这样攻击者又获得了对称加密的密钥。
所以想要解决这个问题,那么就需要知道接收到的信息是由谁发送的,这就引出了下一个概念——数字证书。
数字证书:
在讲数字证书之前,我们需要知道一个第三方机构——CA机构。CA机构是指数字证书认证机构(Certificate Authority),也称为证书颁发机构。它是一种可信第三方机构,负责颁发数字证书,用于证明数字身份、数字签名等安全通信和交易中的身份验证和数据保护。CA机构通过对证书申请者的身份进行认证,为其颁发数字证书,使得用户可以在网络上进行加密通信、数字签名、身份认证等安全操作,保障网络安全和数据隐私。
我们来讲讲数字证书和CA机构在身份验证中是扮演一个什么样的角色:
第一步、服务器会将自己的公钥、域名,还有自己所申请认证证书的CA机构,以及数字摘要的Hash算法、签名算法(用于生成数字签名的加密算法)、数字摘要、原始数据等信息打包在一起发送给自己申请的CA机构,该机构也有一对公私钥对,CA机构会用它的私钥对打包数据中的数字摘要进行加密,得到一个密文,而这个密文就是签名,数字签名生成后会被放在证书中发送给服务器的管理员,而这个证书就叫做TLS证书。
第二步、服务器将CA机构发送过来的TLS证书代替原本要发送给浏览器的公钥发送给浏览器,浏览器拿到这个证书之后不会选择第一时间相信,而是拿CA机构公开的公钥对证书中的签名进行解密得到数字摘要,浏览器也会从证书中提取出原始数据和数字摘要的Hash算法进行转换,这样就可以获得原始数据的数字摘要,再将这两数字摘要一对比就知道数据在服务器发送过来的途中有没有被篡改了。
第三步、如果解密后的数字摘要和由原始数据转换成的数字摘要一致,那么浏览器就会从证书中提取出公钥,从而可以安全的进行SSL。
不过需要注意的是,上面的数字证书是https的验证流程,而apk文件和https在验证数字证书的过程中所用到的算法和流程也有所不同。
HTTPS所用的数字证书通常需要经过CA机构的认证和颁发。而apk文件的数字证书包含了签名者的公钥、签名算法、签名时间等信息,在Android系统中使用的数字证书,是可以由开发者自行生成和使用。
Android在安装APK时,会验证APK的数字签名是否合法。验证的过程包括以下几个步骤:
- 提取APK文件中的数字证书。
- 从数字证书中提取公钥。
- 使用该公钥对APK文件中的数字签名进行解密,得到数字摘要。
- 对APK文件进行Hash运算,生成数字摘要。
- 比较步骤3和步骤4中生成的数字摘要是否一致,如果一致则认为数字签名合法,否则认为数字签名不合法。
需要注意的是,数字证书中包含了数字签名的信息,包括签名者的公钥、签名算法、签名时间等。数字签名本身是对APK文件的数字摘要进行加密得到的,而不是对证书进行加密。
APK文件中的数字证书通常存储在META-INF目录下的CERT.RSA文件中。在安装APK文件时,Android系统会提取CERT.RSA文件中的数字证书,并使用证书中的公钥对APK文件进行验证,以确保APK的真实性和完整性。如果数字证书无效或不匹配,则会提示安装失败或警告用户存在安全风险。
MT管理器是一个可以对APK文件进行修改和重新签名的工具。它使用的签名工具是Android SDK中的apksigner工具,一个官方提供的APK签名工具。
当MT管理器对APK文件进行修改后,它会将修改后的文件打包成一个新的APK文件。然后,MT管理器会调用apksigner工具,使用开发者提供的数字证书对新的APK文件进行签名。签名过程中,apksigner会对APK文件进行Hash运算,生成数字摘要,并使用提供的数字证书对数字摘要进行加密,最后生成新的META-INF目录和CERT.RSA文件。
最后,MT管理器会将签名后的APK文件保存到指定位置。需要注意的是,MT管理器只能对已经进行过数字签名的APK文件进行修改和重新签名。因为apksigner要求原本的APK文件必须进行了数字签名才能进行重新签名的操作。所以如果APK文件没有进行数字签名,apksigner无法对其进行签名操作,从而无法通过MT管理器进行修改和签名。
总结来说,Android系统验证APK的数字签名是为了确保APK的真实性和完整性。MT管理器使用apksigner工具对APK文件进行签名,并要求原始APK文件已经进行了数字签名才能进行修改和重新签名操作。
4)AndroidManifest.xml配置文件
清单文件 大部分也是需要反编译 比如该APK 需要系统哪些权限、apk包名 apk的名字 apk是否支持调试
AndroidManifest.xml是Android应用程序中最重要的文件之一,它包含了应用程序的基本信息,如应用程序的名称、图标、版本号、权限、组件(Activity、Service、BroadcastReceiver、Content Provider)等等。在应用程序运行时,系统会根据这个文件来管理应用程序的生命周期,启动和关闭应用程序,管理应用程序的组件等等。
我们来了解一下AndroidManifest.xml文件的主要组成部分:
- manifest标签
manifest标签是AndroidManifest.xml文件的根标签,它包含了应用程序的基本信息,如包名、版本号、SDK版本、应用程序的名称和图标等等。
- application标签
application标签是应用程序的主要标签,它包含了应用程序的所有组件,如Activity(活动)、Service(服务)、Broadcast Receiver(广播接收器)、Content Provider(内容提供者)等等。在application标签中,也可以设置应用程序的全局属性,如主题、权限等等。
- activity标签
activity标签定义了一个Activity组件,它包含了Activity的基本信息,如Activity的名称、图标、主题、启动模式等等。在activity标签中,还可以定义Activity的布局、Intent过滤器等等。
- service标签
service标签定义了一个Service组件,它包含了Service的基本信息,如Service的名称、图标、启动模式等等。在service标签中,还可以定义Service的Intent过滤器等等。
- receiver标签
receiver标签定义了一个BroadcastReceiver组件,它包含了BroadcastReceiver的基本信息,如BroadcastReceiver的名称、图标、权限等等。在receiver标签中,还可以定义BroadcastReceiver的Intent过滤器等等。
- provider标签
provider标签定义了一个Content Provider组件,它包含了Content Provider的基本信息,如Content Provider的名称、图标、权限等等。在provider标签中,还可以定义Content Provider的URI和Mime Type等等。
- uses-permission标签
uses-permission标签定义了应用程序需要的权限,如访问网络、读取SD卡等等。在应用程序安装时,系统会提示用户授权这些权限。
- uses-feature标签
uses-feature标签定义了应用程序需要的硬件或软件特性,如摄像头、GPS等等。在应用程序安装时,系统会检查设备是否支持这些特性。
以上是AndroidManifest.xml文件的主要组成部分,它们共同定义了应用程序的基本信息和组件,是应用程序的重要配置文件。现在如果看起来有点懵,没关系,后面实战会使用到它的,以后也会对它进行详解,那时你或许会有一点对它的理解了。
5)resources.arsc文件
语言包 程序的加密等 也是编译的
resources.arsc文件是Android应用程序的资源文件之一,它是一个二进制文件,包含了应用程序的所有资源信息,例如布局文件、字符串、图片等。这个文件在应用程序编译过程中由aapt工具生成,并被打包进APK文件中。
resources.arsc文件的主要作用是提供资源的索引和映射关系。它将资源文件名、类型、值等信息映射到一个唯一的整数ID上。这个ID在R文件中定义,并且可以通过代码中的R类来引用。例如,R.layout.main表示布局文件main.xml对应的ID,R.string.app_name表示字符串资源app_name对应的ID。
当应用程序运行时,系统会根据R类中的ID来查找对应的资源,并将其加载到内存中,供应用程序使用。这个过程是通过解析resources.arsc文件和R类实现的。通过这种方式,应用程序可以方便地访问和使用资源,而不需要手动处理资源文件的位置和命名等问题。
需要注意的是,resources.arsc文件只包含资源的索引和映射关系,并不包含实际的资源内容。实际的资源内容存储在res文件夹中,按照资源类型和名称进行组织。当应用程序需要使用资源时,系统会根据resources.arsc文件中的索引信息找到对应的资源文件,并将其加载到内存中。
总之,resources.arsc文件是Android应用程序的资源文件之一,包含了资源的索引和映射关系。它和R类一起构成了应用程序访问和使用资源的基础。通过解析resources.arsc文件和使用R类,应用程序可以方便地加载和使用资源。
这里只是简单介绍了resources.arsc文件,其实还有一个比较重要的知识点,那就是resources.arsc文件结构,我怕篇幅太过于长了,这里就不细讲了,有兴趣的可以自行去了解,比如可以观看以下这些文章:
Android资源管理及资源的编译和打包过程分析 - 掘金 (juejin.cn)
(32条消息) 手把手教你解析Resources.arsc_beyond702的博客-CSDN博客
Android逆向:resource.arsc文件解析(Config List) - 掘金 (juejin.cn)
(32条消息) resource.arsc二进制内容解析 之 Dynamic package reference_BennuCTech的博客-CSDN博客
如果可以全部看完,那你对resources的文件结构和打包流程、资源管理及资源的编译的有了一定的了解。
6)res文件夹
res:资源文件目录,二进制格式。实际上,APK文件下的res文件夹并不是二进制格式,而是经过编译后的二进制资源文件。在Android应用程序开发中,资源文件通常是以XML格式存储的,如布局文件、字符串资源、颜色资源等。在编译时,Android编译器会将这些XML资源文件编译成二进制格式的资源文件,以提高应用程序的运行效率和安全性。虽然res文件夹下的二进制资源文件不能直接编辑和修改,但是开发者仍然可以通过Android提供的资源管理工具,如aapt、apktool等,来反编译和编辑这些资源文件的。
与assets文件夹的差别是 该目录下的是编译之后的文件 打开可能会有乱码的情况。这里面的文件如果需要查看的话,需要先进行反编译。反编译工具用到的是apktool。
在res文件夹中,主要包含以下子文件夹和文件:
res子目录 | 存储的资源类型 |
---|---|
animator/ | 用于定义属性动画的 XML 文件。 |
anim/ | 用于定义补间动画的 XML 文件。属性动画也可保存在此目录中,但为了区分这两种类型,属性动画首选 animator/ 目录。 |
color/ | 定义颜色状态列表的 XML 文件。如需了解详情,请参阅颜色状态列表资源。 |
drawable/ | 位图文件(PNG、.9.png 、JPG 或 GIF)或编译为以下可绘制资源子类型的 XML 文件:位图文件九宫图(可调整大小的位图)状态列表形状动画可绘制对象其他可绘制对象如需了解详情,请参阅可绘制资源。 |
mipmap/ | 适用于不同启动器图标密度的可绘制对象文件。如需详细了解如何使用 mipmap/ 文件夹管理启动器图标,请参阅将应用图标放在 mipmap 目录中。 |
layout/ | 用于定义界面布局的 XML 文件。如需了解详情,请参阅布局资源。 |
menu/ | 用于定义应用菜单(例如选项菜单、上下文菜单或子菜单)的 XML 文件。如需了解详情,请参阅菜单资源。 |
raw/ | 需以原始形式保存的任意文件。如要使用原始 InputStream 打开这些资源,请使用资源 ID(即 R.raw.*filename* )调用 Resources.openRawResource() 。但是,如需访问原始文件名和文件层次结构,请考虑将资源保存在 assets/ 目录(而非 res/raw/ )下。assets/ 中的文件没有资源 ID,因此您只能使用 AssetManager 读取这些文件。 |
values/ | 包含字符串、整数和颜色等简单值的 XML 文件。其他 res/ 子目录中的 XML 资源文件会根据 XML 文件名定义单个资源,而 values/ 目录中的文件可描述多个资源。对于此目录中的文件,<resources> 元素的每个子元素均会定义一个资源。例如,<string> 元素会创建 R.string 资源,<color> 元素会创建 R.color 资源。由于每个资源均使用自己的 XML 元素进行定义,因此您可以随意命名文件,并在某个文件中放入不同的资源类型。但是,您可能需要将独特的资源类型放在不同的文件中,使其一目了然。例如,对于可在此目录中创建的资源,下面给出了相应的文件名约定:arrays.xml 用于资源数组(类型化数组)colors.xml 用于颜色值dimens.xml 用于维度值strings.xml 用于字符串值styles.xml 用于样式如需了解详情,请参阅字符串资源、样式资源和更多资源类型。 |
xml/ | 可在运行时通过调用 Resources.getXML() 读取的任意 XML 文件。各种 XML 配置文件(例如搜索配置)都必须保存在此处。 |
font/ | 带有扩展名的字体文件(例如 TTF、OTF 或 TTC),或包含 <font-family> 元素的 XML 文件。如需详细了解以资源形式使用的字体,请参阅将字体添加为 XML 资源。 |
上表的内容为安卓官方文档中所记录的内容。
上表所定义的子目录中,保存的资源为默认资源。换言之,这些资源定义应用的默认设计和内容。然而,不同类型的 Android 设备可能需要不同类型的资源。
例如,开发者可以为屏幕尺寸大于普通屏幕的设备提供不同的布局资源,以充分利用额外的屏幕空间。还可以提供不同的字符串资源,以便根据设备的语言设置翻译界面中的文本。如需为不同设备配置提供这些不同资源,除默认资源以外,开发者还需提供备用资源。这个现在可能不太明白,但后面实战会讲到。
在Android应用程序中,res文件夹中的资源文件可通过引用其资源 ID 来应用该资源。所有资源 ID 都在项目的 R
类中进行定义,该类由 aapt
工具自动生成,可以通过这些ID值来访问和使用应用程序中的资源。
那R类和res文件夹的关系是怎么样的呢?
R类与res文件夹下的资源文件之间的关系如下:
- R类的包名与应用程序的包名相同,即com.example.myapp。
- R类中的子类与res文件夹下的子文件夹相对应,如Rdrawable对应drawable文件夹,R𝑑𝑟𝑎𝑤𝑎𝑏𝑙𝑒对应𝑑𝑟𝑎𝑤𝑎𝑏𝑙𝑒文件夹,𝑅layout对应layout文件夹(前面的类名表示表示子类,前面的类名表示表示子类,后面的类名表示父类)。
- R类中的每个子类都包含了对应资源文件的ID值,如R$drawable中包含了所有drawable文件夹下的图片的ID值。
- R类中的ID值是由Android编译器(aapt工具)自动生成的,每个ID值都是唯一的,可以通过这些ID值来访问和使用对应的资源文件。
虽说所有资源 ID 都在项目的 R
类中进行定义,但是有的安卓应用程序中R类中有attr子类,而res下却没有attr子目录的。遇到这种情况不要觉得惊讶,下面就要着重讲讲res下的values子目录了。
所有资源ID都在项目的R类中进行定义,也就是说是可以通过资源ID来进行引用的资源那就会在项目的R类中进行定义。所以res文件夹下的子目录也就官方列出的那些,而且每个子目录都装有特定类型的资源,资源还不能乱放,那有的在R类中定义了资源ID的资源但res下没有对应资源的子类,如attr、bool等资源都会在values子目录中声明,前面官方文档中也提到了 values/
目录中的文件可描述多个资源,所有在values子目录中一个xml文件就描述了特定类型的多个资源。我们来看看这里面有哪些资源在values子目录中并且于R类中声明:
Bool:
包含布尔值的 XML 资源,保存在 的 XML 文件: res/values-small/bools.xml
。
color:
包含颜色值(十六进制颜色)的 XML 资源,保存在 的 XML 文件: res/values/colors.xml
。
dimen
包含尺寸值(及度量单位)的 XML 资源,保存在 的 XML 文件: res/values/dimens.xml
。
id:
提供应用资源和组件的唯一标识符的 XML 资源,保存在 的 XML 文件:res/values/ids.xml
。
integer:
包含整数值的 XML 资源,保存在 的 XML 文件:res/values/integers.xml
。
integers:
提供整数数组的 XML 资源,保存在 的 XML 文件: res/values/integers.xml
。
array:
提供 (可用于可绘制对象数组)的 XML 资源,保存在 的 XML 文件: res/values/arrays.xml
。
这些虽说是安卓官方文档所展示的values文件夹中的资源类型,但其实values中的资源类型还不止这些,如drawable、plural等资源类型。还有一点,上面所述的资源类型integers和array都是通过名称进行引用的,而不是通过资源ID来进行引用的。
总的来说就是通过资源ID来进行引用的资源那就会在项目的R类中进行定义,在R类中定义的资源在res下的子目录中找不到,那就去res/values中寻找。有的资源类型没有在R类中定义的是因为该资源类型不是通过资源的ID去引用的,而是通过名称等其他方式进行的引用。
为了更好的理解这玩意实战中的作用,我们来进行次实战——将程序的默认启动activity改为我们自己的activity。
我这里使用的是apktool。
第一步:先把要反编译的apk文件放到apktool所在的文件夹
第二步:在此文件夹中打开powershell并且输入cmd
第三步:输入命令:apktool.bat d 要反编译的apk文件名
7)classes.dex文件
实际上就是smali代码 源代码
可能会有好几个dex文件 本身可以合成一个 在虚拟机运行时也会有合成的过程 分开放是因软件的大小有限制 在我们反编译的过程中 其实代码包含的内容是这几个dex文件合起来的内容 这几个dex一般来说时不重复的
classes.dex文件是Android应用程序的核心组件之一,它是应用程序的可执行文件,包含了应用程序的所有Java类和方法。它是一个被编译过的DEX(Dalvik Executable)文件,是Dalvik虚拟机的格式,用于在Android设备上运行Java应用程序。
在Android开发中,Java源码需要通过Android SDK提供的工具链进行编译,并且会被转换成Dalvik虚拟机可以执行的DEX格式,生成classes.dex文件。这个文件包含了应用程序的所有Java类和方法,可以在Android设备上运行。
Dalvik虚拟机是Google专门为Android操作系统设计的一个虚拟机,与标准的Java虚拟机JVM有一些区别。Dalvik虚拟机是基于寄存器的,而JVM是基于栈的。这种设计使得Dalvik虚拟机能够更好地适应移动设备的资源限制,提供更高效的执行性能。
然而,自Android 5.0(Lollipop)起,Android引入了ART(Android Runtime)作为新的运行时环境,取代了之前的Dalvik虚拟机。在ART环境下,应用程序的Java字节码文件仍然会被编译成DEX格式的可执行文件,即classes.dex文件。
当用户安装应用程序时,系统会将APK文件解压,并将其中的classes.dex文件加载到ART虚拟机中,以执行应用程序的Java代码。classes.dex文件中的Java代码实现了APK的主要逻辑,包括各种功能和业务逻辑的实现。
总结来说,classes.dex文件是Android应用程序的核心组件之一,包含了应用程序的所有Java类和方法。它是一个被编译过的DEX文件,用于在ART虚拟机上执行Java代码。通过加载和执行classes.dex文件,Android应用程序能够在Android设备上运行并提供各种功能。
到这里apk的结构总算讲完了,我们现在讲讲额外的知识点——十六进制状态下的apk文件
为什么要讲这个呢?因为我闲逛时看到了这篇帖子——[原创]基于APK文件格式的反编译对抗机制-Android安全-看雪论坛-安全社区|安全招聘|bbs.pediy.com (kanxue.com),我觉得甚是有趣,就想借着讲apk文件结构顺便把apk文件格式讲了。
编译后生成的apk文件实质上就是一个.zip的压缩包,是可以直接通过解压缩工具打开和解压,我们先来详细了解一下ZIP文件结构。