APK动态调试和Log插桩

使用工具

  • 教程Demo
  • MT管理器/NP管理器
  • jeb:pc端既能静态分析又能动态调试的反编译工具
  • 雷电模拟器
  • XappDebug:用于动态调试的一个工具

真正要搞逆向的话还是要搞台测试机

配置Java环境

  • 下面不用看了,配出问题了,直接重新安装配置了jdk19

  • 这个就不多说了,在学Java已经配过一次了。为了解决Jdk版本问题,我搞了个win11的虚拟机,重新配置了一下环境。

  • 由于虚拟机不支持再开启虚拟化,所以仅在虚拟机里面配置Java环境用于搭建逆向软件,然后对apk文件进行逆向分析

  • 没在虚拟机搭建java环境了,在宿主机找到了一个管理java版本的开源项目,搭了个环境。具体过程可以上网搜索或者查看我学习java的那篇博客,有进行介绍

  • 找到课件的jdk,课件里面的jdk版本是jdk-11.0.15.1_windows-x64_bin.exe,这里直接切换到比该java版本高,但是和他接近的版本

image-20240915092909145

  • 这里我下载了jdk11,但是比该jdk版本更高一点的版本,这里在切换版本的时候出现了一个问题,详细请看问题1。

下载LSPosed

  • 将LSPosed拖入雷电模拟器中安装,具体步骤不多说

image-20240916221628297

  • 安装好后点击去,会出现提示,点击如下按钮

image-20240916221714130

下载jeb

  • 解压该压缩包

image-20240917125658088

  • 点击这个文件
image-20240917125753190
  • 运行后会弹出如下界面
image-20240917125958660

image-20240917130024161

下载XAppdebug

  • 拖进去就可以安装了,比较简单

动态调试1–jeb+端口转发

  • 动态调试是指自带的调试器跟踪自己软件的运行,可以在调试过程中知道参数或者局部变量的值以及知道代码运行的先后顺序,多用于爆破注册码

修改debug权限

  • 修改debug的方法有三个

    • 方法一:在AndroidManifest.xml里添加可调试权限
    • 方法二:XappDebug模块hook对应的app,下载地址https://github.com/Palatis/XAppDebug
    • 方法三:使用Magisk工具输入如下命令(但是重启后会失效)
    1
    2
    3
    4
    adb Shell # adb进入命令模式
    su # 切换至超级用户
    magisk resetprop ro.debuggable 1
    stop;start; # 一定要通过该方式重启
    • 方法四:刷入MagiskHide Props Config模块(永久有效)
  • AndroidManifest.xml添加可调试权限

  • 使用MT管理器,提取安装包,定位,查看AndroidManifest.xml,

  • application中,添加语句android:debuggable="true",然后保存修改重新安装

image-20240916222843036

端口转发开启adb权限

  • 雷电模拟器自带端口转发,不需要再转发一次。
  • 需要开启开发者模式,才能开启adb调试权限
  • 点击设置->关于平板电脑->版本号,连续点击版本号7次即可进入开发者模式
image-20240916223303043
  • 然后返回,然后系统->高级->开发者选项,往下滑会出现USB调试
image-20240916223514046

jeb逆向

  • 将Demo教程拖入jeb,会出现如下界面

image-20240917131153944

  • 接下来打开雷电模拟器的Demo教材,选择关卡四,关卡四会让你输入密钥

image-20240917131308750

  • 随便输入后点击验证按钮,会出现密钥错误哦,再想想!
image-20240917131403753
  • 这时我们再jeb中使用(下方)搜索框,搜索对应字符串,找到后点击搜索结果,会跳转到相应的字符串中

image-20240917131639793

  • 点击后就会出现smali的代码,使用右键,点击解析,将其转换为java代码

image-20240917131927238

  • 然后认真解读反编译后的代码
    • 这边有一个check方法,将获取的文本进行检查
    • 检查正确了就会弹出密钥正确,而错误就会显示出密钥错误,然后出现弹窗

image-20240917132340774

  • 然后双击check这个方法,可以查看check方法具体做了什么操作,从箭头所指向的地方开始解读
    • 该方法传入了一个字符串参数
    • 然后先使用startsWith$default方法,判断该参数的头是否为flag{
    • 再使用endsWith$default方法,判断该参数的尾是否为},如果不满足那么就返 回错误
image-20240917132641501
  • 下滑到该方法的最后,return的这个位置,查看代码
    • 这是将arr_b经过base64编码后的结果与传入参数s1经过加密算法后进行比较,如果相等就返回真,不等就返回假

image-20240917133026511

  • 这时我们来进行动态调试,先转换到smali代码的界面,在该位置打下断点按下CTRL+b即可,下完断点左边就会出现一个红点

image-20240917133650915

动态调试

  • 下完断点之后,就要使用debug模式启动app,使用命令adb shell am start -D -n 应用包名/类名,应用包名和类名如下
  • 所以需要输入的指令为adb shell am start -D -n com.zj.wuaipojie/.ui.MainActivity
image-20240917133946776 image-20240917134208524
  • 使用win + R输入cmd,打开命令行,输入命令adb shell am start -D -n com.zj.wuaipojie/.ui.MainActivity

  • 在输入该指令前必须要开启端口转发

  • 我这边出现adb命令找不到的问题,原因是我没下载APK_Platform_toolsSDK 平台工具版本说明 | Android Studio | Android Developers,下载好后解压将adb所在路径添加到用户环境变量中的path

    • 使用adb version检查是否添加成功
    • 再输入adb shell am start -D -n com.zj.wuaipojie/.ui.MainActivity即可
image-20240917200121788
  • 出现如下提示就表明成功
1
2
adb shell am start -D -n com.zj.wuaipojie/.ui.MainActivity
Starting: Intent { cmp=com.zj.wuaipojie/.ui.MainActivity }
  • 模拟器也会出现这样的情况

image-20240917200950193

  • 然后切换到jeb的这个图标,即为调试

image-20240917201038099

  • 在这边出现了一个问题,具体看问题2

  • 然后点击附上

image-20240917203823726
  • 然后会弹出来这个窗口,我们只需要关注局部变量即可

image-20240917203929174

  • 接下来我们需要触发代码逻辑,输入这个点击验证,然后查看局部变量

image-20240917204519361

  • 我们可以看到局部变量这边有我们输入的值

image-20240917204645848

  • 然后注意这段代码,其最终会返回v0的值

image-20240917204838181

  • 然后选中这一行,点击进入,查看方法内部的代码
image-20240917204935544
  • 之后就会跳转到加密的具体代码,右边的值也会相应的改变

image-20240917205031365

  • 然后按这个按钮跳过,程序就会逐行的往下走
image-20240917205106087
  • 调试到下图位置,p1的值就会出现完整的base64编码过后的值

image-20240917205246965

  • DAsG字符串复制下来,然后再终止程序

image-20240917205350857

  • 然后在模拟器中输入该字符串,验证一下是不是我们所需要的密码,结果发现验证成功

image-20240917205845486

动态调试2–XAppdebug

  • 先进入LSPosed应用,将XAppdebug进行激活
image-20240917210641449
  • 将这俩个都勾选上
image-20240917210720202
  • 接着重启模拟器,该系统框架才会生效
  • 然后打开XAPPdebug,将要hook的软件勾选上,这样即使没有加入这个语句也可以进行debug调试android:debuggable="true"

image-20240917211102902

动态调试3–Magisk命令

动态调试4–刷入MagiskHide Props Config模块

  • 该种方式就是可以获取永久debug权限

Log插桩

  • 定义:Log插桩指的是反编译APK文件时,在对应的smali文件里面,添加相应的smali代码,将程序中关键信息,以log日志的形式进行输出

  • 调试命令invoke-static {对应寄存器}, Lcom/mtools/LogUtils;->v(Ljava/lang/Object;)v

  • 打开共享文件将这个文件移动到共享文件夹里面

image-20240917211835325

  • 然后打开模拟器端的MT管理器,将插桩的文件塞进apk安装包里面,还要将插桩文件进行统一的命名规则

image-20240917212241747

  • 然后再classes.dex文件中加入调入命令,找到相应的文件

image-20240917212555474

  • 然后找到对应语句,我们要获取v0的值,就加入对应的语句invoke-static {v0}, Lcom/mtools/LogUtils;->v(Ljava/lang/Object;)V

image-20240917212537831

  • 然后重新安装,安装好后先不启动,先打开LSPosed,中的算法助手,勾选该应用
image-20240917212916751
  • 然后打开算法助手,打开下图这几个东西

image-20240917213147905

image-20240917213209698

  • 然后点击右上角的开始按钮

image-20240917213804554

  • 启动之后进入关卡,输入flag{123},然后点击验证,验证完就会在算法助手里面出现日志

image-20240917213949483

image-20240917213958880

  • 即可获得参数值

image-20240917214039435

问题

问题1

  • 在切换java版本的时候出现如下错误提示,已在终端管理员运行该命令
1
2
PS E:\app2\java_manager\jvms_v2.1.6_amd64> .\jvms.exe switch jdk_11.0.23
Switch jdk failed, please manually remove E:\app2\Java_manager\jvms_v2.1.6_amd64\store
  • 这里找到github上的issue,得以解决

image-20240915164029160

  • 先找到在c盘的Program下的文件,然后删除该文件,再执行命令

问题2

  • 在附加调试的时候并没有出现设备,原因是jeb常用5555端口,但是雷电模拟器默认5554端口,最后重启一下jeb再进行调试就可以看到了

image-20240917202839686