Android apk安装包反编译——apktool工具

目录

  • 一、apk 文件结构
  • 二、下载 apktool
  • 三、 使用 apktool 反编译 apk
  • 四、编译为apk
  • 五、apk签名
    • 1.生成密钥库
    • 2.使用 v1 签名
    • 3.使用 v2 签名
  • 六、Dex 加解密原理

一、apk 文件结构

首先是 apk,即安卓程序的安装包。Apk 是一种类似于 Symbian Sis 或 Sisx 的文件格式。通过将 APK 文件直接传到 Android 模拟器或 Android 手机中执行即可安装。
而 apk 文件实际上就是一个 MIME 为 ZIP 的压缩包,只不过后缀名进行了更改。

我们可以直接把 .apk 后缀的文件修改成 .zip 后缀的压缩包格式,然后解压后就可以看到内部的文件结构,就像下面这样:

在这里插入图片描述

文件夹结构说明:

  • assets 文件夹: 保存一些额外的资源文件,如游戏的声音文件,字体文件、图片等等,在代码中可以用 AssetManager 获取 assets 文件夹的资源。
  • lib 文件夹: 存放用 C/C++ 编写的,用NDK编译生成的 so 文件,供 java 端调用。
  • META-INF 文件夹: 存放 apk 签名信息,用来保证apk包的完整性和系统的安全。在 IDE 编译生成一个 apk 包时,会对里面所有的文件做一个校验计算,并把计算结果存放在 META-INF 文件夹内,apk 在安装的时候,系统会按照同样的算法对 apk 包里面的文件做校验,如果结果与 META-INF 里面的值不一样,系统就不会安装这个 apk,这就保证了 apk 包里的文件不能被随意修改和替换。比如拿到一个 apk 包后,如果想要替换里面的一幅图片,一段代码, 或一段版权信息,想直接解压缩、替换再重新打包,基本是不可能的。如此一来就给病毒感染和恶意修改增加了难度,有助于保护系统的安全。
  • res文件夹: 存放资源文件,包括icon,xml布局文件
  • AndroidManifest.xml文件: 应用程序的清单文件,每个应用都必须定义和包含的,它描述了应用的名字、版本、权限、引用的库文件等信息。
  • classes.dex文件: 传统 Class 文件是由一个 Java 源码文件生成的 .Class 文件,而 Android 是把所有 Class 文件进行合并优化,然后生成一个最终的 class.dex 文件。它包含 APK 的可执行代码,是分析 Android 软件时最常见的目标。由于 dex 文件很难看懂,可通过 apktool 反编译得到.smali文件,smali文件是对Dalvik虚拟机字节码的一种解释(也可以说是翻译),并非一种官方标准语言。通过对smali文件的解读可以获取源码的信息。当然 你也可以通过dex2jar工具将 classes.dex 文件转化为 jar 包,然后再通过 jadx 或者 jd-gui 可以查看 jar 包里面的代码。一般软件开发者会对 classes.dex 进行加固,防止别人轻易反编译
  • resources.arsc文件: 二进制资源文件,如:字符串常量就会存放在 strings.xml 中。
  • smali: smali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为 Android 字节码的反汇编语言。利用 apktool 或者 Android Killer,反编classes.dex文件,就可以得到以smali为后缀的文件,这些 smali 文件就是 Dalvik 的寄存器语言。
    简单的说,smali就是Dalvik VM内部执行的核心代码,andorid逆向分析的关键点。

二、下载 apktool

可在下面两种下载中选择一种方式下载:

apktool github发下页面
apktool 下载

(我这里使用的是 apktool_2.9.1.jar 版本)

三、 使用 apktool 反编译 apk

将 apk 安装包和下载的 apktool 放在同一目录。
假如我的安装包叫 base.apk ,我想把它反编译到 test 文件夹下,反编译命令如下:

java -jar apktool_2.9.1.jar d base.apk -o test

该命令将会自动新建一个 test 文件夹, 反编译后的所有文件都将被放到里面。

说明:
与 jadx 不同,apktool 反编译 apk 后,你在反编译后的 AndroidManifest.xml 里是找不到 versionCode 内部版本号 和 versionName 版本名称 的,因为 apktool 把它放到了 apktool.yml 文件里,如果你要修改 versionCode 、versionName ,可以在 apktool.yml 文件里修改。

四、编译为apk

假如你修改了 test 文件夹里的代码 或者 修改了 versionCode 、versionName 等其他内容,可用下面的命令将 test 文件夹编译为 apk 。

java -jar apktool_2.9.1.jar b test -o test.apk

该命令将 test 文件夹编译为 test.apk 。

到这里你已经得到了一个修改后的 apk,但是这个编译后的 apk 还无法安装到手机上,因为修改了文件,在安装时手机会对安装包里的签名进行比对签名,如果签名对不上说明apk被篡改了,就不会进行安装。

所以,如果现在要对修改后的 apk 重新进行签名,才能安装。

五、apk签名

关于 apk 签名的具体细节说明,可参考这篇文章:Android apk之v1、v2、v3签名

1.生成密钥库

使用如下命令生成 keystore 格式的密钥库:

keytool -genkey -alias new.keystore -keyalg RSA -validity 20000 -keystore new.keystore

输入两次密钥口令,一直回车,最后输入y
在这里插入图片描述

2.使用 v1 签名

使用如下命令进行签名:

jarsigner -verbose -keystore new.keystore -signedjar D:\fanbiany\sign1.apk D:\fanbiany\test.apk new.keystore

说明:
该命令使用上面生成的 new.keystore 密钥库对 D:\fanbiany\test.apk 进行签名,最后生成 D:\fanbiany\sign1.apk

3.使用 v2 签名

先找到你的 apksigner.jar 所在路径,我的是在C:\Users\kingdee\AppData\Local\Android\Sdk\build-tools\33.0.2\lib\apksigner.jar

执行如下命令进行 v2 签名:

java -jar C:\Users\kingdee\AppData\Local\Android\Sdk\build-tools\33.0.2\lib\apksigner.jar sign --ks new.keystore --out sign2.apk  sign1.apk

说明:
使用 apksigner.jar 然后用 new.keystore 密钥库对 sign1.apk进行签名,最后生成 sign2.apk

六、Dex 加解密原理

一般 apk 都会进行加固,即对 Dex 加密,Dex 就是格式的文件里是 apk 的代码,加密后反编译是看不到项目主要代码的,从而保证了 apk 的安全性。

关于 Dex 加解密原理,可参考如下文章查看细节:
性能优化专题七–Apk加固之Dex文件的加密与解密
Dex 加解密与多 Dex 加载
APK 加固之 Dex 加解密,反编译都看不到项目主要代码。


本文参考:
Android 逆向入门保姆级教程
静态分析android程序之阅读smali代码
为什么有些APK解包后没有DEX文件?

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

zabbix添加监控主机(agent)并告警

一、添加监控主机 总体来说,在被监控主机上安装部署zabbix-agent,并修改配置文件(zabbix_agentd.conf)的参数。然后在zabbix 服务端zabbix-get检查是否可以监控。如果可以了,就可以在web页面添加了,要监控…

SpringBoot知识

1、Spring和SpringBoot对比 2、版本调整 (1)先排除是否是JDK与SpringBoot的版本不一致导致的:如JDK1.8和SpringBoot3.1.5冲突; (2)调整编译版本 (3)调整maven的jdk (4&…

12.30_黑马数据结构与算法笔记Java

目录 320 全排列无重复 Leetcode47 321 组合 Leetcode77 分析 322 组合 Leetcode77 实现 323 组合 Leetcode77 剪枝 324 组合之和 Leetcode 39 325 组合之和 Leetcode 40 326 组合之和 Leetcode 216 327 N皇后 Leetcode51-1 328 N皇后 Leetcode51-2 329 解数独 Leetco…

Java:IO流——字节流和字符流

目录 IO流的基本概念 IO流体系结构 FileOutputStream字节输出流 构造方法 成员方法 细节 关流 FileInputStream字节输入流 构造方法及成员方法 read不带参数代码示例 read带参数代码示例​编辑 将字节数组或字符数组转成字符串 FileReader 字符输入流 构造方法和…

移动硬盘打不开怎么办?没有比这更好的办法了

移动硬盘打不开是常见故障,可能的原因有很多,例如硬盘驱动器故障、文件系统损坏、分区表错误等。本文将详细分析这些原因,并提供相应的解决方法,帮助您解决移动硬盘打不开的问题。 当移动硬盘打不开时,为了保留其中的文…

设计模式(4)--对象行为(11)--访问者

1. 意图 表示一个作用于某对象结构中的各元素的操作。 使你可以在不改变各元素的类的前提下定义于作用于这些元素的新操作。 2. 五种角色 抽象访问者(Visitor)、具体访问者(Concrete Visitor)、抽象元素(Element)、 具体元素(Concrete Element)、对象结构(ObjectStructure) 3…

[场景实现]:多选框与树形结构递归

一、场景描述 实现一个分配权限的页面,最左侧是大的权限模块的名称,左右侧是控制其是否勾选的多选框。中间部分是一级权限模块下的子权限名称及多选框。 请求此权限模块数据的接口返回的是树形结构 对象数组。 主要属性为menuName表示权限名&#xff0…

ArkTS - 组件生命周期

一、先说下自定义组件 在arkTs中,自定义组件分为两种(我的总结): 一种是:根组件,就是被装饰器Entry装饰的入口组件,这也是自定义组件(父组件)。 另一种是:没有被Entry装饰的自定义…

设计模式Java向

设计原则: 开闭原则: 用例对象和提供抽象功能进行分割,用例不变,抽象功能被实现,用于不断的扩展,于是源代码不需要进行修改,只在原有基础上进行抽象功能的实现从而进行代码扩展。不变源于代码…

x-cmd-pkg | deno - 更快更强的 JS 和 TS 运行时

目录 简介首次用户技术特点进一步阅读 简介 Deno 是一个基于 V8 引擎和 Rust 语言构建的 JavaScript 和 TypeScript 运行时环境,于 2018 年由 Ryan Dahl 在演讲中宣布,并在 2020 年正式发布 1.0,目标是提供一个高效且安全的脚本环境。 安全…

typora的笔记丢失了怎么办?

突然打开电脑发现原本保存的typora的笔记全部不见了,头痛…… 解决方法:点击typora中的文件,选择偏好设置,点击[恢复未保存的草稿],然后可以在文件夹中找到最后一次保存该文件的版本。 自己又将自动保存勾选上了&…

数据结构学习 Leetcode322 零钱兑换

关键词:动态规划 完全背包 记忆化搜索 一个套路: 01背包:空间优化之后dp【target1】,遍历的时候要逆序遍历完全背包:空间优化之后dp【target1】,遍历的时候要正序遍历 题目: 方法一&#xff…