使用 Apktool 逆向 Android APK

Apktool 是对 smali/baksmali 的一个封装,smali 和 baksmali 可以看做是 Android 的 assembler 和 disassembler,Apktool 在其基础上提供了更便捷的使用方法。

1. 建立测试工程

  首先来建立一个测试工程。新建一个 Android APP 工程,只包含一个 TextView,在 MainActivity 中创建一个名为 name 的 String,其值为 “Foo”,并通过 TextView 显示一行消息:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView textView = (TextView) findViewById(R.id.tv_text);

    String name = "Foo";
    textView.setText(getString(R.string.hello) + name);
}

  该应用在运行时会显示一行文字:“Hello, Foo”,如图1所示。

图1

图1

2. baksmali

  把上一步得到的 APK 取出来,假设名为 app-debug.apk,运行

apktool d app-debug.apk

  之后会在同目录下得到一个名为 app-debug 的文件夹,找到

/app-debug/smali/your_package_name/MainActivity.smali

并用编辑器打开,搜索“Foo”,可以找到这样一段:

.line 16
.local v1, "textView":Landroid/widget/TextView;
const-string v0, "Foo"

这里把 const-string v0, “Foo” 修改为 const-string v0, “Bar” ,即:

.line 16
.local v1, "textView":Landroid/widget/TextView;
const-string v0, "Bar"

  .smali 是介于 .dex 和 .java 的中间产物,在这里有一段比较详细的介绍。.smali 可读性较差,但由于字面值不会被修改,搜索字面值可以快速定位目标代码。

3. smali

  保存修改后,运行:

apktool b app-debug

  在 /app-debug/dist 下面可以找到一个 app-debug.apk,这个就是修改后重新打包的产物了。

4. 签名

  要安装这个包,首先要进行签名,如果没有 keystore,可以使用下面的命令快速建立一个:

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

  建立 keystore 过程中需要先输入两次密码,然后填写一些信息,再输入 yes 确认,注意看清文字,不要一路 Enter 下去。

  然后对 app-debug.apk 进行签名:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore app-debug.apk alias_name

  如果没有使用同一个签名,就无法覆盖/升级安装,需要先卸载之前安装的应用,才能安装修改后的版本。打开之后,可以看到消息已经变成了 “Hello, Bar”,如图2。

图2

图2