由于博主的主要工作是游戏SDK的开发和维护,所以博主经常遇到CP反馈的奇奇怪怪的问题。有的时候常规的方法无法让你找到问题出现的原因,而这时候往往需要CP来帮助你打log,先不说这效率如何,CP往往还不一定会理你,因为大家都很忙;而去找CP要源码那更是不切实际的,这时候代码注入便是最高效的debug的方法了。

一、所需工具

工欲善其事,必先利其器,首先需要下载一个名为APKDB的软件,该软件几乎已经集成了所有反编译需要的工具了,并且支持鼠标右键直接反编译。

APKDB传送门
当然,你也可以使用apktool,然后手动输入命令。

二、反编译APK

接下来我们随便创建一个简单的apk,代码很简单,只有一句hello world!,现在要做的是在onCreate中添加一句Log打印

2.1 将APK反编译为smali

在androi的java虚拟机中读取的是dex文件,但是手动修改dex文件是不切实际的,幸运的是,android提供一个baksmali.jardx.jar工具,让dex和smali的互转。
而smali是很容易修改的,因此便给代码注入带来了可能。

反编译后的文件夹,主要是修改smali文件

2.2 找到需要修改的smali文件

借助反编译工具,我们很容易便能获取到apk的smali文件了,接下来就是要找到需要修改的smali文件,以便达到注入的目的。
这一步往往是最具挑战,最考验耐心的,因为很多APP除了自身的代码外,再加上各种依赖库,类、包多达成百上千,并且APP一般都会加上混淆;往往希望找到特定的代码,将消耗大量的时间。至于如何快速定位代码需要的就是大量的经验了,本文在此不讨论定位技巧。

由于demo是我们自己写的,所以我们可以很快找到需要修改的文件

2.3 修改smali文件

在上一步中,我们已经找到了需要修改的MainActivity.smali文件,用编辑器打开它,并查找onCreate,如下图所示:

为了在onCreate中添加一句Log,我们需要修改的便是红框框中的代码.line 表示的是代码java代码对应的行数,如

便是setContentView(R.layout.activity_main);

1
2
.line 12
return-void

表示的方法代码块结束,对应的是}
因此我们可以在.line 12上一行添加Log打印的smali语句,如下所示:

1
2
3
const-string/jumbo v0, "TAG"
const-string/jumbo v1, "代码被注解了"
invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

对应的便是

1
Log.d("TAG", "代码被注解了");

smali 语法

三、编译apk

修改好了代码后,我们可以直接使用APKDB直接将smali编译为apk

编译成功后:

直接安装apk

3.1 验证

四、如何快速生成smali语句

正常写smali语句是会要人命的,在idea上我们可以下载java2smali 将Java代码转换为smali语言
1.编写一个最简单的java文件。比如下面这样的。

然后我们点击Build->Compile to smali

稍等几秒钟后就会得到smali文件。