Android逆向之反编译APK_apk反编译-程序员宅基地

技术标签: apk反编译  dex2jar  APK逆向  apktool工具  Android  

前言

日常开发中,我们可能需要反编译 apk 去查看或分析一些问题,如:

1、这个 app 效果挺酷的啊,怎么实现的呢?此时你就可以反编译看下它的布局和代码实现

2、这个 app 里面的资源挺多的啊,我想拿过来用,此时你就可以反编译去拿这个 app 里面的资源

3、使用 aop 在一个类里面插入了一些代码,想验证一下,此时你就可以反编译查看是否按照你的预期插入了代码

4、我想改吧改吧这个 app ,例如替换它的 app icon,替换里面的翻译,app 汉化等等,此时你就可以反编译修改,然后打成一个新的 apk 发布(这种大家知道就好,千万别去做啥坏事)

上面列举的 4 种场景基本可以覆盖我们日常开发中遇到的问题了,接下来我们就正式进入 APK 反编译技术的讲解

注意:下面演示均是在 mac 下进行

一、反编译工具介绍

如果我们只是需要 app 中的图片资源,可以直接修改 xxx.apk的后缀为 xxx.zip,解压后的文件目录如下:

image-20221022210917119.png

所有的代码处于 classes.dex 中,图片布局等资源处于 res 目录下。此时你可以直接去 res 目录下复制图片资源使用,但是你去打开 AndroidManifest.xml 文件和 activity_main.xml 文件,会发现看不懂

AndroidManifest.xml 文件:

image-20221022175713114.png

activity_main.xml 文件:

image-20221022175816393.png

就是一推整齐排列的 16 进制数,那如果我想看懂要怎么办呢?

答:使用 apktool

1.1、apktool

作用:反编译 APK 中的资源

下载链接:ibotpeaches.github.io/Apktool/ins…

打开下载链接会出现如下界面:

image-20221021173948270.png

mac 建议使用红框中的 Homebrew 去安装,执行 brew install apktool 命令一键安装,它会自动给你配置好环境变量以及增加文件的操作权限

安装完成后,输入apktool命令 ,如果展示了 apktool 相关信息证明你配置成功了,如下图:

image-20221021174740419.png

1.1.1、apktool 使用

接下来我们通过 apktool 来反编译 apk 中的资源

1、先准备一个 apk 文件

2、执行 apktool d xxx.apk 命令

其中 d 是 decode 的意思,表示我们要对 xxx.apk 进行解码,我们还可以再加上一些附加参数来控制 decode 的更多行为:

-f :如果目标文件夹已存在,则强制删除现有文件夹(默认如果目标文件夹已存在,则解码失败)

-o :指定解码目标文件夹的名称(默认使用 APK 文件的名字来命名目标文件夹)

-s :不反编译dex文件,也就是说 classes.dex 文件会被保留(默认会将 dex 文件解码成 smali 文件)

-r :不反编译资源文件,也就是说 resources.arsc 文件会被保留(默认会将 resources.arsc 解码成具体的资源文件)

常用的用法就这么多,上述命令的执行结果如下图所示:

image-20221022172954424.png

这就说明反编译资源成功了

需要注意的是

1、上述 app-debug.apk,mac 的 terminal 会自动添加 .zip 后缀,大家别给误导了哈

2、另外生成的文件夹会在 apk-debug.apk.zip 的基础上在增加 .out 后缀:

image-20221022173342679.png

这种现象和 windows 系统表现不太一样,大家注意一下,如果看着不爽,可以使用上述讲的附加参数-o ,来对输出的文件夹进行重命名

3、建议大家新建一个文件夹来进行反编译的操作,例如上面我新建了一个 apktool_reverse 的文件夹,然后将 apk 资源放到下面,通过 terminal cd 到这个目录,最后执行解码的命令

4、如果我们执行解码命令 apktool d xxx.apk 成功后,想添加附加参数继续执行,如:apktool d -s -r xxx.apk,此时会报错:

image-20221022174758839.png

报错提示我们该文件夹已经存在了,因此在这种文件夹已经存在的情况下,大家应该加上附加参数-f强制删除现有文件夹

ok,看一下 apktool 反编译后生成的一些具体文件:

image-20221022180713615.png

1、AndroidManifest.xml:经过反编译还原后的 manifest 文件

2、original 文件夹:存放了未经反编译过、原始的 AndroidManifest.xml 文件

3、res 文件夹:存放了反编译出来的所有资源

4、smali 文件夹:存放了反编译出来的所有代码,只不过格式都是.smali类型的

看一眼反编译后的 AndroidManifest.xml 文件和 activity_main.xml 文件

AndroidManifest.xml 文件:

image-20221022180343979.png

activity_main.xml 文件:

image-20221022180428331.png

已经还原成我们看得懂的文件了,格式差点意思,你可以将内容复制出来放到 AndroidStudio 里面格式化一下就完美了,这样我们就把反编译资源的方法给掌握了

另外使用 apktool 反编译后的代码处于 smali 文件夹下,且都是.smali格式的,我们简单截取一段 MainActivity.smali 文件的代码:

image-20221022205951161.png

嗯,看不懂,如果你能看得懂,那么做的事情就多了,你可以随意修改应用程序内的逻辑,将其进行破解发布。

那怎么才能转换成能看懂的 Java 代码呢?

答:使用 dex2jar + jd-gui

1.2、dex2jar

作用:将 dex 文件转换成 jar 文件

下载地址:sourceforge.net/projects/de…

1.2.1、dex2jar 使用

将下载的 dex2jar 压缩包解压,可以看到如下内容:

image-20221021165416847.png

在 mac 中使用 d2j-dex2jar.sh 文件就 ok 了

1、将需要转换的 dex 文件复制到当前 dex2jar 目录:

image-20221021165712150.png

2、执行如下命令:

sh d2j-dex2jar.sh classes.dex

此时 terminal 会报错:Permission denied

这是因为文件权限不足导致的,执行如下命令提权即可:

chmod 777 d2j_invoke.sh

接着在执行上述反编译命令,过程如下:

image-20221021170548196.png

我们可以看到 dex2jar 多了两个压缩包:

image-20221021170810169.png

其中代码都处于 classes-dex2jar.jar 中, dex2jar 已经完成它的使命,接下来我们需要通过 jd-gui 去查看 jar 包下的内容

1.3、jd-gui

作用:查看 jar 包里面的具体类容

下载地址:java-decompiler.github.io/

打开下载链接如下图:

image-20221022212449198.png

根据自己的操作系统下载不同的压缩包即可,这里我下载的是 jd-gui-osx-1.6.6.tar,解压后你会看到下面 4 个文件:

image-20221022212625065.png

双击打开 JD-GUI ,你会发现系统给我们报了个错误:

ERROR launching 'JD-GUI'

No suitable Java version found on your system! This program requires Java 1.8+ Make sure you install the required Java version.

这是因为 universalJavaApplicationStub.sh 脚本在 Mac Big Sur 及以上版本有兼容性问题,我们需要对这个脚本的内容进行替换

1、双击 JD-GUI 显示包内容

image-20221022213637572.png

2、根据截图找到 universalJavaApplicationStub.sh

image-20221022213535766.png

3、将此文件内容替换为 github.com/tofi86/univ… 这个链接中的内容

注意:安装之前你要保证系统已经安装了 JDK 1.8 及以上版本

经过上面 3 步,你就可以正确的打开 JD-GUI 了:

image-20221022214020602.png

接着将需要打开的 jar 包给拖进去,查看 MainActivity:

image-20221022214433643.png

上述 MainActivity 我使用 AspectJ 在 onCreate 方法中插入了一些代码,效果符合我的预期

至此,我们就学会了如何反编译代码和资源了,简单的小结一下:

1、如果要反编译 app 的代码,就使用 dex2jar + jd-gui

2、如果要反编译 app 的资源,就使用 apktool

ok,还没结束,现在你还只会我在前言中提到的 1,2,3 点,对于第 4 点:反编译一个 app,将它打包成一个新的 app 你还不会,跟着我的步伐继续往下走

二、基于一个 app 打造一个新的 app

提醒:这里大家就站在一个技术的角度去学习,千万别干坏事

我们基于上述使用 apktool 反编译后的文件夹去做修改,先再看一眼:

image-20221022180713615.png

未修改前 activity_main.xml 文件的代码如下:

image-20221023094920363.png

我们这里就简单的对 activity_main.xml 文件进行一些修改然后打包,修改如下:

image-20221023095336625.png

接着使用 apktool 将我们反编译的app-debug.apk.zip.out文件夹重新打包成 apk,使用如下命令:

apktool b app-debug.apk.zip.out -o new_app_debug.apk

执行过程如下图:

image-20221023100440147.png

现在你会发现同级目录有了一个新的 apk 文件:

image-20221023100528479.png

结果猴急猴急的拿去安装,你会发现安装报错了:

adb: failed to install xxx/new_app_debug.apk: Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from /data/app/vmdl2142334632.tmp/base.apk: Attempt to get length of null array]

还是我们高兴的太早了,目前这个新 apk 是不能安装的,因为它还没有进行签名,那么如果这是别人的 app,我们从哪儿去整一个签名文件呢?很显然,拿别人的是不可能,因此我们需要自己去生成,使用 AndroidStudio 可以非常简单的生成一个签名文件,这里就不展开说了,不懂得自己去查一下

有了签名文件之后再 terminal 执行如下签名命令:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore 签名文件名 -storepass 签名密码 待签名的APK文件名 签名的别名

其中 jarsigner 命令文件是存放在 JDK 的 bin 目录下,需要将 bin 目录配置在系统的环境变量当中才可以在任何位置执行此命令

以我的为例:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore certificate -storepass erdai666 new_app_debug.apk key0

如果执行过程中没啥问题,就证明签名成功了,此时我们就可以把它安装到手机上了,不过在此之前,Android 还极度建议我们对签名后的 apk 文件进行一次对齐操作,因为这样可以使得我们的程序在 Android 系统中运行得更快。对齐操作使用的是 zipalign 工具,该工具存放于<Android SDK>/build-tools/<version>目录下,将这个目录配置到系统环境变量当中就可以在任何位置执行此命令了

zipalign 4 new_app_debug.apk new_app_debug_aligned.apk

其中 4 是固定的值,后面指定待对齐的 apk 文件名和对齐后的 apk 文件名,运行这段命令之后,会生成一个new_app_debug_aligned.apk文件,如下所示:

image-20221023102830691.png

接下来我们把这个签名对齐后的 apk 安装到手机上,效果如下图所示:

可以看到,当我们打开 app 后,页面的布局变成我们修改后的了,说明我们基于一个 app 打造一个新的 app 成功了

三、总结

本篇文章我讲了:

1、反编译资源,主要通过 apktool

2、反编译代码,主要通过 dex2jar + jd-gui

3、基于一个 app 打造一个新的 app,主要通过 apktool 反编译后,修改 activity_main.xml 文件,然后进行重新打包,签名,对齐,最后安装展示了预期的效果。当然这里你有能力看懂 .smali格式的代码,那么你可以做的事情就更加多

好了,本篇文章到这里就结束了,希望能给你带来帮助

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lihuayong/article/details/133973975

智能推荐

【浅谈JavaBean】-程序员宅基地

文章浏览阅读1.1k次,点赞3次,收藏3次。本文阐述了JavaBean的相关知识,涵盖发展、优点、实例等_javabean

数据结构 二叉搜索树的删除_请辞掉前面的搜索树-程序员宅基地

文章浏览阅读4.2k次,点赞4次,收藏16次。文章目录概述待删除的结点没有子树待删除的结点仅有一颗子树待删除的结点有两颗子树C代码实现概述这是一篇短文,专门考究一下二叉搜索树的删除。二叉搜索树的建立非常简单,如果不熟悉的见此文 树与二叉树。而删除则有数种情况:待删除的结点没有子树。待删除的结点仅有一颗子树。待删除的结点有两颗子树。下面逐一分析。待删除的结点没有子树如需删除下图中结点9:这是最简单的一种情况,它没有子..._请辞掉前面的搜索树

彻底弄懂乒乓操作与并行化_pingpong fifo-程序员宅基地

文章浏览阅读7.9k次,点赞21次,收藏154次。乒乓操作可以看做成另一种形式的流水线技术。乒乓缓存结构如下图所示。输入数据流通过输入数据选择单元时,时间等分地将数据流分配到两个数据缓冲模块。数据缓冲模块可以是RAM,FIFO等。通过将数据交替存放到数据缓冲模块1、数据缓冲模块2。并交替从数据缓冲模块1、数据缓冲模块2读取数据送入到数据流运算处理模块。工作过程如下: 第一段乒乓缓冲周期:将数据流缓存到数据缓冲模块1。..._pingpong fifo

linux pmap命令,linux中关于pmap的命令实例分析-程序员宅基地

文章浏览阅读316次。这篇文章主要介绍了linux中 pmap 命令详解,需要的朋友可以参考下通过查看帮助,返回了如下信息:Usage: pmap [options] pid [pid ...]Options:-x, --extended show details-X show even more detailsWARNING: format changes according to..._pmap返回3个数值都是什么意思

binwalk和foremost的使用。_binwalk和 foremost的使用-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏5次。一、binwalkbinwalk -e flag.png 直接分离出夹带的私货binwalk flag.png 查看有无夹带的私货会生成一个如下所示的文件夹二、foremostforemost flag.png 会生成一个:_binwalk和 foremost的使用

myeclipse项目导入IDEA中-程序员宅基地

文章浏览阅读1k次。 先把myeclipse下的项目拷贝到IDEA的部署目录中,把一些不用的配置文件删除,只留下一个干净的项目   打开IDEA,点击import Project,引入一个项目,选择IDEA部署目录下刚拷贝过去的项目 点击创建一个新的项目,然后下一步把jar包引入进来选择jdk版本IDEA自动寻找到在WebRoot下面的WEB-I..._myeclipse项目导入idea

随便推点

闰年的判断 输⼊⼀个1~7的数字,打印对应的星期⼏ 九九乘法表_1. 输 年份,闰年 2. 输 数字,星期 3. 打印九九乘法表。 4. 打印如下菱形-程序员宅基地

文章浏览阅读47次,点赞5次,收藏2次。闰年的判断 输⼊⼀个1~7的数字,打印对应的星期⼏ 九九乘法表_1. 输 年份,闰年 2. 输 数字,星期 3. 打印九九乘法表。 4. 打印如下菱形

php 封装的常用函数_php 封装常用函数-程序员宅基地

文章浏览阅读1k次。&lt;?php/** * Created by www. * * @FileName : functions.php * @Author : yzm &lt;[email protected]&gt; * @DateTime : 2017/12/21-12-21 10:52 *//** * 编码转换 * * @param $value * * @author yzm ..._php 封装常用函数

史上最全的Android基础教程+实战练习+经验技巧(建议收藏)|寻找C站宝藏_安卓实战教程-程序员宅基地

文章浏览阅读3.1w次,点赞138次,收藏1k次。有个专栏包含了Android基础教程和入门实战训练的Android项目,还有各种Android处理技巧。没错,就是我从一年前开始做的Android王国专栏。为什么叫王国呢?因为我觉得接触任何领域的第一步都是先打好基础,然后再实战演练建筑高楼,最后学会各种技巧建筑围墙,这样你的知识王国就建好了,当然这座王国还在不断更新加固。赶紧收藏起来吧,在这里,0基础学会做app!_安卓实战教程

低代码平台:企业IT管理的一剂“良方”_低代码三大引擎是哪三个-程序员宅基地

文章浏览阅读186次。当前,低代码还处于国内发展的初期阶段,但在软件产业供给远跟不上社会需求的今天,低代码不会成为昙花一现的概念,而将会作为新的软件开发模式,形成长远发展趋势,对软件产业乃至整个社会产生巨大影响。_低代码三大引擎是哪三个

xcode的bug-程序员宅基地

文章浏览阅读53次。2019独角兽企业重金招聘Python工程师标准>>> ..._xcode的bug

资深专家支招:2019年Linux运维工程师的高薪出路在哪?-程序员宅基地

文章浏览阅读305次。资深专家支招:2019年Linux运维工程师的高薪出路在哪?——优秀运维工程师的思维和应该的日常工作重心早在2015年国家就提出了“供给侧”改革思想,简言之,就是告诉企业里的Linux运维工程师要从以往平时人肉部署各种业务环境,处理各种故障(负载高、CPU高、服务宕机、被***),每天火烧眉毛、焦头烂额苦劳多功劳少的工作模式切换到下文更高效的工作模式了。优秀的Linux运维..._linux运维工程师工资怎么那么低