Android 逆向学习【2】——APK基本结构

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文件夹是存放数字签名相关文件的文件夹,包含以下三个文件:

  1. MANIFEST.MF:MANIFEST.MF文件是一个摘要清单文件,它包含了apk文件中除自己以外所有文件的数字摘要。
  2. CERT.SF:CERT.SF文件是用于存储通过私钥加密后得到的MANIFEST.MF文件的数字签名信息以及MANIFEST.MF文件中数字摘要的数字签名信息。
  3. 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的数字签名是否合法。验证的过程包括以下几个步骤:

  1. 提取APK文件中的数字证书。
  2. 从数字证书中提取公钥。
  3. 使用该公钥对APK文件中的数字签名进行解密,得到数字摘要。
  4. 对APK文件进行Hash运算,生成数字摘要。
  5. 比较步骤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文件的主要组成部分:

  1. manifest标签

manifest标签是AndroidManifest.xml文件的根标签,它包含了应用程序的基本信息,如包名、版本号、SDK版本、应用程序的名称和图标等等。

  1. application标签

application标签是应用程序的主要标签,它包含了应用程序的所有组件,如Activity(活动)、Service(服务)、Broadcast Receiver(广播接收器)、Content Provider(内容提供者)等等。在application标签中,也可以设置应用程序的全局属性,如主题、权限等等。

  1. activity标签

activity标签定义了一个Activity组件,它包含了Activity的基本信息,如Activity的名称、图标、主题、启动模式等等。在activity标签中,还可以定义Activity的布局、Intent过滤器等等。

  1. service标签

service标签定义了一个Service组件,它包含了Service的基本信息,如Service的名称、图标、启动模式等等。在service标签中,还可以定义Service的Intent过滤器等等。

  1. receiver标签

receiver标签定义了一个BroadcastReceiver组件,它包含了BroadcastReceiver的基本信息,如BroadcastReceiver的名称、图标、权限等等。在receiver标签中,还可以定义BroadcastReceiver的Intent过滤器等等。

  1. provider标签

provider标签定义了一个Content Provider组件,它包含了Content Provider的基本信息,如Content Provider的名称、图标、权限等等。在provider标签中,还可以定义Content Provider的URI和Mime Type等等。

  1. uses-permission标签

uses-permission标签定义了应用程序需要的权限,如访问网络、读取SD卡等等。在应用程序安装时,系统会提示用户授权这些权限。

  1. 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文件夹下的资源文件之间的关系如下:

  1. R类的包名与应用程序的包名相同,即com.example.myapp。
  2. R类中的子类与res文件夹下的子文件夹相对应,如Rdrawable对应drawable文件夹,R𝑑𝑟𝑎𝑤𝑎𝑏𝑙𝑒对应𝑑𝑟𝑎𝑤𝑎𝑏𝑙𝑒文件夹,𝑅layout对应layout文件夹(前面的类名表示表示子类,前面的类名表示表示子类,后面的类名表示父类)。
  3. R类中的每个子类都包含了对应资源文件的ID值,如R$drawable中包含了所有drawable文件夹下的图片的ID值。
  4. 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文件结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654279.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI预测福彩3D采取888=3策略+和值012路一缩定乾坤测试5月28日预测第4弹

昨天的第二套方案已命中&#xff0c;第一套方案由于杀了对子&#xff0c;导致最终出错。 今天继续基于8883的大底&#xff0c;使用尽可能少的条件进行缩号&#xff0c;同时&#xff0c;同样准备两套方案&#xff0c;一套是我自己的条件进行缩号&#xff0c;另外一套是8883的大底…

工业制造企业为什么要进行数字化转型

人人都在谈数字化转型&#xff0c;政府谈数字化策略方针&#xff0c;企业谈数字化转型方案&#xff0c;员工谈数字化提效工具。互联网企业在谈&#xff0c;工业企业也在谈。 在这种大趋势下&#xff0c;作为一个从事TOB行业十年的老兵&#xff0c;今天就来给大家讲讲&#xff…

ubuntu openvoice部署过程记录,解决python3 -m unidic download 时 unidic无法下载的问题

github给的安装顺序&#xff1a; conda create -n openvoice python3.9 conda activate openvoice git clone gitgithub.com:myshell-ai/OpenVoice.git cd OpenVoice pip install -e .安装MeloTTS: pip install githttps://github.com/myshell-ai/MeloTTS.git python -m unid…

Follow Your Pose: Pose-Guided Text-to-Video Generation using Pose-Free Videos

清华深&港科&深先进&Tencent AAAI24https://github.com/mayuelala/FollowYourPose 问题引入 本文的任务是根据文本来生成高质量的角色视频&#xff0c;并且可以通过pose来控制任务的姿势&#xff1b;当前缺少video-pose caption数据集&#xff0c;所以提出一个两…

【ARM+Codesys案例】T3/RK3568/树莓派+Codesys枕式包装机运动控制器

枕式包装机是一种包装能力非常强&#xff0c;且能适合多种规格用于食品和非食品包装的连续式包装机。它不但能用于无商标包装材料的包装&#xff0c;而且能够使用预先印有商标图案的卷筒材料进行高速包装。同时&#xff0c;具有稳定性高、生产效率高&#xff0c;适合连续包装、…

[图解]伪创新并不宣传自己简单易学

1 00:00:00,450 --> 00:00:04,790 今天这个题目&#xff0c;主要是解答一道 2 00:00:05,580 --> 00:00:07,490 前一阵出过的竞赛题 3 00:00:11,700 --> 00:00:15,170 因为这道题导致我们很多人做错了 4 00:00:15,600 --> 00:00:21,690 然后竞赛的轮次一直没有能…

C++学习日记 | LAB 6 static library 静态库

资料来源&#xff1a;南科大 余仕琪 C/C Program Design LINK&#xff1a;CPP/week06 at main ShiqiYu/CPP GitHub 一、本节内容 本节主要介绍静态库和动态库。 1.1 静态库和动态库的概念 静态链接和静态库(也称为存档)是链接器将所有使用的库函数复制到可执行文件的结果。静…

存内计算从浮点运算优化对数据经济的提升

本篇文章将介绍存内计算技术对于数据经济的提升&#xff0c;我们将从提出问题、解答问题与阐述应用三个方面进行展开介绍&#xff0c;并引入浮点存算、等新兴存算技术进行简要介绍。 一.数据经济&存内计算&#xff0c;结合是否可行&#xff1f; 数据经济与存内计算&#…

恭喜社区迎来新PMC成员!

恭喜Apache SeaTunnel社区又迎来一位PMC Memberliugddx&#xff01;在社区持续活跃的两年间&#xff0c;大家经常看到这位开源爱好者出现在社区的各种活动中&#xff0c;为项目和社区发展添砖加瓦。如今成为项目PMC Member&#xff0c;意味着在社区中的责任更重了&#xff0c;他…

Github Page 部署失败

添加 .gitmodules 文件 [submodule "themes/ayer"]path themes/ayerurl https://github.com/Shen-Yu/hexo-theme-ayer.git 添加 .nojekyll 文件

文心一言 VS 讯飞星火 VS chatgpt (269)-- 算法导论20.2 4题

四、修改 proto-vEB 结构&#xff0c;以支持重复关键字。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 在原始的 van Emde Boas 树&#xff08;vEB tree&#xff09;结构中&#xff0c;关键字&#xff08;key&#xff09;是唯一的&#xff0c;不允许有重复的关…

.NET 轻量级、高效任务调度器:ScheduleTask

前言 至于任务调度这个基础功能&#xff0c;重要性不言而喻&#xff0c;大多数业务系统都会用到,世面上有很多成熟的三方库比如Quartz&#xff0c;Hangfire&#xff0c;Coravel 这里我们不讨论三方的库如何使用 而是从0开始自己制作一个简易的任务调度,如果只是到分钟级别的粒…

centos7防火墙入站白名单配置

firewall-cmd --set-default-zonedropfirewall-cmd --get-active-zone记录下当前激活网卡firewall-cmd --permanent --change-interfaceens33 --zonedrop firewall-cmd --zonedrop --list-all 添加信任的源IP和开放端口 firewall-cmd --permanent --add-source192.168.254.1 -…

pikachu—exec“eval“

这是原画面 然后呢&#xff1f; 我们知道会传入到后台rce_eval.php来处理然后通过 eval()是啥? 在eval括号里面可以执行外来机器的命令 然后我们通过php的一个内置的命令 我们通过phpinfo()&#xff1b; 这是输入后的结果

华为机考入门python3--(26)牛客26-字符串排序

分类&#xff1a;字符串 知识点&#xff1a; 字符串是否仅由字母构成 my_str.isalpha() 字母列表按小写排序 letters.sort(keylambda x: x.lower()) 题目来自【牛客】 def custom_sort(input_str):letters []non_letters []for char in input_str:if char.isalpha…

打工人都在偷偷做的副业项目—steam搬砖

steam搬砖其实是一个非常老牌的项目了&#xff0c;之前只有玩游戏玩市场的人知道&#xff0c;其他普通人都不知道。 我们陪跑这个项目不是说这个项目不行了&#xff0c;再拿出来割韭菜&#xff0c;现在依然可以做&#xff0c;我们本身就是项目和培训一比一在做&#xff0c;这一…

R语言学习 - 箱线图一步法

箱线图 - 一步绘制 绘图时通常会碰到两个头疼的问题&#xff1a; 1、有时需要绘制很多的图&#xff0c;唯一的不同就是输入文件&#xff0c;其它都不需要修改。如果用R脚本&#xff0c;需要反复替换文件名&#xff0c;繁琐又容易出错。 (R也有命令行参数&#xff0c;不熟&…

关于高性能滤波器和普通型滤波器的区别说明

高性能滤波器和普通型滤波器在性能和滤波效果上存在显著差异。以三安培为代表分析高性能滤波器和普通型滤波器的区别&#xff1a; 从上图曲线可看出&#xff1a; 1.高性能滤波器和普通型滤波器的滤波范围不同。普通型滤波器有效滤波范围为 150KHz~30MHz&#xff0c;而高性能滤…

QColor官网文档简介

颜色可以用不同的模型来进行表示,常见的有RGB,HSV或者CMYK.QColor基于RGB值创建颜色,如果要转接到HSV或者CMYK需要使用转接函数toHsv() toCmyk() 返回期望格式的副本 get...和set...函数具体参见文档用isValid()检查RGB颜色是否合法颜色组成部分可以单独检索QRgb是一种无符号整…

Hololens 2 新建自定义按钮

官方链接地址 1、创建Cube 2、添加PressableButton脚本&#xff0c;并点击AddNearin… 3、把Cube拖入到MovingButtonVisuals变量中 4、点击NearInteractionTouchable组件&#xff08;这个组件是添加和上一个脚本绑定的&#xff0c;自动添加上来的&#xff09;上的Fix… 5、…