应用宝、酷安的android APK脱壳过程
找到一个实现了自动拨打和接听微信语音、视频的软件、以及低电量报警,并自带老年桌面的一个launcher应用,下载下来后发现使用dextools、jadx、apktool均无法获取到包里的内容,仅可读R.java,猜测可能上架应用市场后由应用市场进行了加壳。
环境准备
根据Google到的知识,可以使用将apk安装后加载到内存后进行dump脱壳。使用如下技术:
-
frida
-
frida-tools
-
frida-server (android)
-
dextools + jad 对脱壳后的dex进行反编译
-
apktool 对资源进行反编译
PC上安装frida工具
pip install frida
pip install frida-tools
宿主机安装frida-server
选择对应的CPU架构的frida-server动态库,并确保宿主机已经root
首先查看cpu架构,我使用的emulator,所以我选择的是x86_64的架构, android版本为R(11),在AVD中选中R(11) Google APIs(一定要带APIs的,否则不能root,frida-server不能启用)。
adb shell getprop ro.product.cpu.abi
x86_64
然后到GitHub发布的Releases · frida/frida中下载对应的CPU处理架构的frida-server,frida-server与frida的版本要尽可能一致。完成后进行解压,。我这儿为frida-server-16.4.7-android-x86_64.xz
。
将frida-server-16.4.7-android-x86_64
拷贝至宿主机(拷贝前确保宿主机能获取到root权限),为frida-server赋予执行的权限。
adb root
adb push <path>/frida-server-16.4.7-android-x86_64 /data/local/tmp
rem 使用adb切换到shell
adb shell
为frida-server赋予执行的权限,并运行。
chmod +x /data/local/tmp/frida-server-16.4.7-android-x86_64
cd /data/local/tmp
./frida-server-16.4.7-android-x86_64
验证frida是否成功
在PC上新创建一个命令行窗口,输入以下命令来查看当前手机进程列表
frida-ps -U
case1. 如果出现以下错误提示,则需要将手机数据线拔下来重新插一次,然后重新运行一遍上面的命令即可。
Failed to enumerate processes: unable to handle 64-bit processes due to build configuration
case2. 如果出现以下错误提示,证明端口被占用了,可以重启一下手机。
Unable to start: Could not listen on address 127.0.0.1, port 27042: Error binding to address 127.0.0.1:27042: Address already in use
case3. 如果出现以下列表,则表示frida已经安装成功。
PID Name
---- -------------------------------------------------------------
4480 Gmail
1654 Google
4815 Google Play Movies & TV
2731 Phone
5412 Photos
6527 Settings
6327 adbd
213 android.hardware.atrace@1.0-service
298 android.hardware.audio.service.ranchu
299 android.hardware.authsecret@1.0-service
446 android.hardware.biometrics.face@1.0-service.example
447 android.hardware.biometrics.fingerprint@2.1-service
最后再进行端口映射
adb forward tcp:27042 tcp:27042
使用frida脚本进行脱壳
我这儿是在github上找的frida脱壳脚本,如果对frida熟悉的可以自行编写脚本,或自行寻找能用的脚本。前往GitHub下载frida_dump/dump_dex.js。
rem dump_dex.js为下载的frida脚本文件,--no-pause我这儿找不到该命令,可以不填
frida -U -f <packageName> -l dump_dex.js --no-pause
case 1. 因MagiskHide导致的执行失败
Failed to spawn: unable to access PID 765 (zygote64) while preparing for app launch; try disabling Magisk Hide in case it is active
解决办法
Magisk 管理器 -> 设置 -> Magisk 选项 -> MagiskHide(关闭即可)
rem 或使用adb进行关闭
adb shell "su -c magiskhide disable"
rem 完事后可以执行该命令进行开启
adb shell "su -c magiskhide enable"
case 2. 因脚本报错
C:\Users\MORTAT\Desktop\launcher> frida -U -f com.ant.helper.launcher -l .\OpenMemory.js
____
/ _ | Frida 16.4.7 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to Android Emulator 5554 (id=emulator-5554)
Spawned `com.ant.helper.launcher`. Resuming main thread!
Error: expected a pointer
at value (frida/runtime/core.js:408)
at <eval> (C:\Users\MORTAT\Desktop\launcher\OpenMemory.js:32)
替换你的frida脚本。
case3. 执行成功
C:\Users\MORTAT\Desktop\launcher> frida -U -f com.ant.helper.launcher -l .\dump_dex.js
____
/ _ | Frida 16.4.7 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to Android Emulator 5554 (id=emulator-5554)
Spawning `com.ant.helper.launcher`...
_ZN3art11ClassLinker11DefineClassEPNS_6ThreadEPKcmNS_6HandleINS_6mirror11ClassLoaderEEERKNS_7DexFileERKNS_3dex8ClassDefE 0x78dc7b58ac90
[DefineClass:] 0x78dc7b58ac90
Spawned `com.ant.helper.launcher`. Resuming main thread!
[Android Emulator 5554::com.ant.helper.launcher ]-> [find dex]: /data/data/<pre-initialized>/files/dump_dex_<pre-initialized>/class.dex
Error: No such file or directory
at onEnter (C:\Users\MORTAT\Desktop\launcher\dump_dex.js:96)
[find dex]: /data/data/<pre-initialized>/files/dump_dex_<pre-initialized>/class.dex
Error: No such file or directory
at onEnter (C:\Users\MORTAT\Desktop\launcher\dump_dex.js:96)
[find dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class.dex
[dump dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class.dex
[find dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class2.dex
[dump dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class2.dex
[find dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class3.dex
[dump dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class3.dex
[find dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class4.dex
[dump dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class4.dex
[find dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class5.dex
[dump dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class5.dex
[find dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class6.dex
[dump dex]: /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher/class6.dex
将dump后的dex文件拷贝到本机使用jadx反编译。
adb pull /data/data/com.ant.helper.launcher/files/dump_dex_com.ant.helper.launcher F:/dump_dex