Android动态调试

Android动态调试

四月 12, 2021

用jeb和Android Studio进行apk无源码动态调试,以攻防世界的Ph0en1x-100为例

jeb查看Java代码找到关键判断:

用getSecret()分别处理getFlag()和encrypt(sInput)后将两个值比较,sInput是输入,只需要让getFlag()和encrypt(sInput)的值相同即可,ida查看so文件发现encrypt()函数只是将输入字符串的每一位ascii码-1,而getFlag()函数没有输入,故返回值不变,可以通过动态调试得到返回值。

jeb+夜神模拟器

apktool解包在AndroidManifest.xml中加android:debuggable="true"后重新打包签名(略)

在模拟器中安装重新打包签名好的apk,adb连接模拟器

1
adb connect 127.0.0.1:62001

查看连接

1
adb devices

jeb找到getFlag()函数在smali中的位置下断点:

模拟器中打开app,jeb附加进程调试:

模拟器中输入数据点击确认,程序断下,查看数据:

move-result-object v1是将刚刚执行了的getFlag()的返回值赋给寄存器v1,在这里把v1的类型改成string就可以看到想要的返回值。

Android Studio

AS中安装smalidea插件,这里遇到问题,一直安装不上,最后把压缩包直接解压放进plugins文件夹重启即可,据说是因为我安装AS时把路径从C盘改成D盘。安装完成后会有这两个smali处理插件:

在设置中把Smali Support支持*.smali文件改成Smalieda支持*.smali文件:

之后就可以在smali代码中下断点了。

还是先apktool解包在AndroidManifest.xml中加android:debuggable="true"后重新打包签名(略)

AS的虚拟机不用adb手动连接端口,但是调试需要端口映射。

AS中选择Profile or Debug APK打开重新打包签名后的apk,新建一个remote调试配置:

记住端口号5005。

在虚拟机上运行app,获得包名/主activity名:

1
2
3
4
adb shell "dumpsys activity top | grep ACTIVITY"

# ACTIVITY com.android.launcher3/.Launcher 3f4d30e pid=2795
# ACTIVITY com.ph0en1x.android_crackme/.MainActivity df4d3f5 pid=5714

以调试模式启动app:

1
adb shell am start -D -n com.ph0en1x.android_crackme/.MainActivity

查看以调试模式启动的进程pid:

1
2
adb shell "ps | grep crackme"
#u0_a104 5777 1619 1840024 80608 futex_wait_queue_me 0 S com.ph0en1x.android_crackme

端口映射:

1
adb forward tcp:5005 jdwp:5777

在AS中附加进程即可开始调试

需要注意的点:

  1. AS有Google Play的虚拟机无法root,所以需要创建一个没有Google Play的虚拟机
  2. 我AS动态调试看不到寄存器的值