图文详解 | Android APK反编译实战

1. 为什么要反编译?


场景一

产品经理:xxx,反编译xxx的播放器,看看他们是怎么实现的?

场景二

测试:这个APP怎么一在我们手机上运行就会crash呀,xxx手机就不会

场景三

APP用户:这个APP有汉化版的吗?

为什么要反编译
  • 在日常工作中,遇到最多的情况应该就是这三种了。接下来以第二种情况为例,来看下通过反编译APK分析和解决Bug的过程。

2. 问题描述

使用硬件版本为T2的手机运行StabilityTest.apk进行'CPU+GPU STABLITY TEST'测试,每隔一段时间就会弹'Preparing scene.Please wait...'的提示框,而使用T1的硬件,不会出现该问题。

Preparing scene.Please wait...的提示框

从问题描述上来看,应该是硬件差异导致的,和软件无关。那为什么这个提示框总是一直弹出呢?一直弹也很讨厌啦。由于是第三方APK,没有源码无法分析,所以先要对StabilityTest.apk进行反编译,才能查看Dialog调用的流程。


3. 反编译流程

  • 反编译的整体流程
反编译的整体流程

3.1 准备工具

1. 工具介绍

反编译工具

2. Tip

除了上面提到的工具,还需要保证Java 1.7已经安装成功,并且环境变量配置正确。

3. 获取方法

  • ApkTool
    组成:
    由apktool.jar & apktool.bat两支文件组成

    HomePage: http://ibotpeaches.github.io/Apktool/
    官网上有最新apktool.jar可供下载,apktool.bat需要到Install Instructions页面下载。

    HomePage

Install Instructions: https://ibotpeaches.github.io/Apktool/install/
apktool.bat其实就是一个用来运行apktool.jar的脚本,按照Install Instructions里面提示下载即可。

获取apktool.bat

  • dex2jar
    说明: 前面有提到dex2jar是可选的工具,dex2jar是和JD-GUI配合使用的,将smali代码转换为可读的java代码,如果你能看懂smali代码就不需要获取dex2jar了。

获取地址: https://sourceforge.net/projects/dex2jar/

下载dex2jar最新版本
  • JD-GUI
    HomePage: http://jd.benow.ca/
    和dex2jar一样,JD-GUI为可选软件。从官网上获取最新JD-GUI版本。

    下载对应JD-GUI版本

  • signAPK
    获取路径: https://github.com/appium/sign
    在github上去下载sign.jar,然后执行java -jar sign.jar my.apk就可以进行签名。

Tip: 你也可以下载signapk.jar,但是在签名时需要执行的命令不一样:

java -jar SignApk.jar testkey.x509.pem testkey.pk8 my.apk my.s.apk

这组命令和上面的命令是等价,相比之下,java -jar sign.jar my.apk要简单得多。

signAPK

3.2 使用Apktool反解APK

  • 执行命令apktool.bat d apk名称
    反解成功后,我们就可以得到AndroidManifest.xml、smali源码和res等文件

  • smali是Android Dalvik虚拟机内部执行的核心代码

    apktool.bat d StabilityTest.apk

  • 目录结构

反解后的目录结构

3.3 使用dex2jar将classes.dex转换为jar包

通过第一步反编译出来的是smali文件,没有smali语法基础,阅读起来很晦涩。通常我们会先去查看java代码,然后再去对比看相应的smali文件,要轻松得多。

  • 用压缩软件打开StabilityTest.apk,然后解压出位于根目录下的classes.dex
解压apk得到classes.dex
  • 使用dex2jar将classes.dex转换为jar包,我是直接把classes.dex放到dex2jar-2.0目录下的,然后执行命令:
    d2j-dex2jar.bat classes.dex
d2j-dex2jar.bat classes.dex
  • 生成的classes-dex2jar.jar就在dex2jar-2.0目录下
    classes-dex2jar.jar

3.4 使用jd-gui打开classes-dex2jar.jar

  • 如果觉得jd-gui查看代码不方便,还可以通过File->Save All Sources导出一个classes-dex2jar.src.zip,将classes-dex2jar.src.zip解压以后,导入到Sublime阅读代码。
Save All Sources

3.5 分析代码 & log

  • 在代码中搜字符串
    在整个工程中搜索关键字Preparing scene.Please wait...定位到dismiss和show Dialog都是在TestGPU.java里的handleMessage中处理,只有在onSurfaceChanged时才会发message去显示dialog

  • 分析log
    只从上面定位到的代码,好像也看不出来什么原因才会一直去调onSurfaceChanged。
    只有先去看下log了,看看程序本身会不会打印出一些异常信息。果然log中报了一个异常,而且是不断地在打印这个异常。

    log
  • 再次check代码
    发现这些log是在获取系统频率TestGPU.update()出错时打印,导致屏幕上还
    会提示"bogomips"的信息,一直在调update。

调用过程:
TestGPU.update->getFrequencyCore0->eventLoop.sleep(500L)->TestGPU.update()

但是,这个看起来好像还是和onSurfaceChanged没有关系。观察弹提示框时,会显示一个异常的字符串,正常情况应该会显示cpu频率。

bogomips

搜索这个字符串,发现也是和update有关,在获取cpu频率失败后,会去
cat proc/loadavg,然后将得到的结果设置给bogomipsTextView,就出现了这个字符串。

  • 找到疑点
    怀疑是由于bogomipsTextView显示的内容太长,上面灰色区域显示不下,导致影响了下面的3D显示区域,然后去调用了onSurfaceChanged方法发送"load" message给handler,handler接收到message以后,一直会去显示提示框。

3.6 修改smali源码

  • 为了验证上面的猜测,试着设置一个短的字符串给bogomipsTextView,看看还会不会有这种情况
    将反解以后的smali文件导入到Sublime,通过搜索字串"bogomipsTextView",找到TextView赋值的地方,将"BogoMIPS"赋值给这个TextView。
    修改方法如下图,只需要添加一句代码:

const-string v3, "BogoMIPS"

smali源码

对应java代码其实只有这么几句:

对应java代码
  • Tip: 有细心的朋友会发现JAVA代码里面有这么一句

self.getText(2130968587)

那2130968587对应字符串的值怎么找?

Step 1. 在classes-dex2jar.src.zip里面搜索"2130968587"

在classes-dex2jar.src.zip里面搜索"2130968587"

Step 2. 在反解后的apk目录里面搜"cpu_text",最后发现cpu_text的
id = 0x7f04000b,转为10进制,就是2130968587

String id.png

Step 3. 结论: 213096858的值为"bogomips:"


3.7 重新生成apk

  • 修改完smali源码后,使用apktool重新打包生成apk
    执行命令:apktool.bat b 反解后的apk文件夹名称
apktool.bat b StabilityTest
  • 打包后的apk位于StabilityTest\dist目录下
    打包后的apk.png

3.8 apk签名

  • 使用sign.jar进行签名
    执行java -jar sign.jar xxxx.apk就可以进行签名,签名以后的APK被重命名为xxxx.s.apk
    java -jar sign.jar StabilityTest.apk

3.9 验证效果

  • 必须要卸载掉之前的apk,然后再安装新的apk。可以看到修改已经生效,没有再弹出提示框,证明了我们的猜测是正确的。

验证效果

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容