如何分析安卓程序

第一个安卓程序

已经上传至 github:https://github.com/shesl-meow/AndroidReverse.git

编译生成 .apk 文件,可以直接在 Android Studio 中进行操作。

破解第一个程序

反编译 APK 文件

安装 apktool,这是一个 github 的开源软件:https://github.com/iBotPeaches/Apktool

在 Windows 下,可以直接使用 choco 进行安装:

1
> choco install apktool

关于 apktool 的使用教程可以参考:apktool

分析 APK 文件

在目标文件夹下(与开发时的源码目录结构是一样的):

  • smali 目录存放了程序的所有反汇编代码
  • res 目录下存放了程序中所有的资源文件

以上的 Android 程序的分析步骤:

  1. res/values/strings.xml 被加密存储为 resources.arsc,当程序被反汇编成功后这个文件也被解密了出来。

    在这里存储了 Android 程序中存储使用的所有字符串。

    使用以下的命令查找 注册失败 的提示信息:

    1
    2
    
    $ cat ./res/values/strings.xml | grep 注册错误
    <string name="unsuccess_msg">注册错误</string>
    
  2. 所有的字符串都在 gen/<packagename>/R.java 文件的 String 类被表示,每个字符串都有唯一的 int 类型索引值。

    这个索引值经过 apktool 反汇编之后,都保存在与 string.xml 文件同目录下的 public.xml 文件中。

    使用以下命令查找 unsuccess_msg 对应的索引值:

    1
    2
    
    $ cat ./res/values/public.xml | grep unsuccess_msg
    <public type="string" name="unsuccess_msg" id="0x7f0b0027" />
    
  3. 然后在源代码中查找 0x7f0b0027 这个索引值调用的位置:

    1
    2
    3
    
    $ grep -rwn ./smali/ -e "0x7f0b0027"
    ./smali/com/example/reversetest/MainActivity$1.smali:97:    const v1, 0x7f0b0027
    ./smali/com/example/reversetest/R$string.smali:96:.field public static final unsuccess_msg:I = 0x7f0b0027
    
  4. 我们发现实现注册失败的逻辑存在于 MainActivity$1.smali 这个文件中,我们可以继续研究这个文件。暂时看不懂 smali 代码,此处略过。

  5. 打开任意的文本编辑器。将 if-nez p1, :cond_0 更改为 if-eqz p1, :cond_0

重新编译 apk 文件并签名

使用以下的 apktool 命令重新编译 apk 文件:

1
$ apktool b outdir

编译生成的 apk 文件还没有签名,不能安装测试,接下来需要使用 apksigner 命令行工具对 apk 文件进行签名(书中的旧版本使用 signapk.jar),使用细节见:apksigner

(签名之后似乎只是大小变大了)

通过以下的命令安装 apk 文件(adb 命令使用细节见 adb ):

1
$ adb install testapp.apk