Android 调试无源码的 APK 应用
购买了《游戏机实用技术》的《塞尔达传说 旷野之息 中文版完全攻略本》电子版本,需要使用手机上的 UCG
应用才能阅读,但是其阅读体验不是很友好,结合其阅读前需要预下载,猜测是一个 PDF 文件,故想提取到电脑上进行查看。
经过一番搜索,发现这个 PDF 文件是被加密的,又刚巧碰上公司内部举办 CTF
比赛,故借此机会研究一下 Android 逆向调试的方法。这里再说明一下,自己购买了使用权,解密 PDF 文件后,仅自己使用不传播不分享,我认为是没有问题的。《游戏机实用技术》杂志作为一个老牌刊物,目前碰到一些政策上的问题,多多支持正版也可以为其挺过难关尽一份微薄之力。
反编译源代码
这里推荐一个非常好用的工具 jadx,可以直接打开一个 APK
文件,支持查找用例
、跳到声明
等功能,甚至可以一键导出 Gradle 工程。
刚开始反编译后,找不到任何有关 PDF 的代码,才发现 UCG
经过今年的风波,重新做了一个新版本 App,其不再采用本地下载 PDF 的方式,而是通过接口下载每一页的图片,目前 Android 端和微信小程序已上线,iOS 尚无,因此需要找到一个旧版本的 APK
安装包。新版本的包名是 com.bard.ucgm
,旧版本的包名是 com.bard.vgmagazine
,最新版本似乎是 1.9.1
尚能正常使用。
这里找到最关键的计算密码的方法是:将商品的两个变量和一个常量拼接计算 MD5
然后再拼接一个 /
符号,因此接下来的目标就是通过调试找到这两个变量的值。
1 |
this.core.authenticatePassword(MD5Util.MD5(this.a + this.b + "c") + "/");
|
重新打包 APK 文件
这里需要预先准备一个 APK
解包工具 Apktool。
- 解包 APK:
apktool.bat d "ucg_v1.9.1.apk" -o ucg
- 编辑
AndroidManifest.xml
文件,在application
节点中加入android:debuggable="true"
属性:<application android:debuggable="true" ... />
- 重新打包 APK:
apktool.bat b -d "./ucg/" -o unsigned.apk
- 创建签名密钥:
keytool -genkeypair -v -keystore debug.keystore -alias debug -keyalg RSA -keysize 2048 -validity 10000
,这个keytool
是 JDK 提供的工具 - 验证 APK:
zipalign -f -v 4 unsigned.apk ready.apk
,这个zipalign
在 Android SDK 的 build-tools 中 - 签名 APK:
apksigner sign --ks debug.keystore --ks-key-alias debug --out signed.apk ready.apk
,这个apksigner
也在 Android SDK 的 build-tools 中 - 安装 APK:
adb install signed.apk
- 调试 APK:开发人员选项 -> 等待调试器 -> 选择待调试应用
使用 Android Sutdio 调试
- 首先要安装 smalidea 插件
- 使用 Android Studio 打开 “重新打包 APK 文件” 中第①步导出的目录
- 将
smali
目录设为Sources Root
- 在合适的位置设置断点
- 手机上启动 App
- Android Studio 选择附加到进程
- 手机上执行流程
- 命中断点,成功找到变量
a
和b
获取 PDF 文件
- Android:可以参考附录的参考文献
- iOS:同理,用越狱过的 iPhone,访问 App 的目录获取 PDF 文件
删除 PDF 文件的密码
- 使用 Adobe Acrobat 打开
- 保护
- 高级选项
- 删除安全性设置
- 保存
预览: