Android动态调试合集

[TOC]

JEB动态调试smali

  1. 选中smali代码后,Ctrl B下断点

  2. 启动app

    1. 以debug模式启动Activity(调试一启动就执行的方法)

      1
      adb shell am start -D -n [package_name]/[activity_name]
    2. 调试可以手动触发(不着急)的方法,手动打开app或者去掉上述命令的-D参数

  3. JEB附加进程

    1. 菜单栏【调试器】下选择【开始】(不能开启ddms或AndroidStudio
    2. 弹出对话框,选择设备、进程后,点击【附上】。app会被附加,运行到断点断下。

使用AndroidStudio配合Smalidea插件来动态调试smali

  1. Smalidea安装
    1. github地址:JesusFreke/smalidea: smalidea is a smali language plugin for IntelliJ IDEA (github.com)
    2. 下载后在插件页导入安装即可
    3. 配置及使用:
      1. (0.6版本已可以自动配置)检查Settings->Editor->File Types中,除了Smali外多了一个smali Files,内有内容*.smali
      2. 菜单栏File下多了【Profile or Debug Apk】;可以方便的选择一个apk来反编译成项目、或使用apktool d反编译然后导入也可以
  2. 获得反编译apk后的smali文件夹
    1. 方法一:apktool d反编译apk得到文件夹
    2. 方法二:使用菜单栏File下的【Profile or Debug Apk】

方法一:

  1. AS准备调试

    1. 使用AndroidStudio选择**【Import Project(导入项目)】**,并选择该文件夹;会提示不是项目,然后选择创建新项目
    2. 添加运行配置【Add Configuration...】
      1. 选择模板【Remote JVM Debug】,端口设置为8700
    3. 设置反编译后文件夹的根目录,右键,【Mark Directory as】选择【Sources Root】 (貌似可选)
    4. 在smali相应处下断点
  2. 开始调试

    1. 点击【运行】右侧的【调试】按钮,程序开始运行,运行到断点断下

    2. 左上角选择【停止】按钮左侧的【Attach Debugger to Android Process】附加按钮

      1. 以debug模式启动Activity(调试一启动就执行的方法)

        1
        adb shell am start -D -n [package_name]/[activity_name]
      2. 转发app运行端口到8700(可选)

        1. 命令方式

          1
          adb forward tcp:8700 jdwp:[app_port]
        2. 使用ddms(monitor);位于Sdk\tools\monitor.bat(需下载)

          1. 打开monitor,选中app包名所在进程,该进程的port后会出现/8700
      3. 点击【附加】按钮选择设备下的进程,点击OK,即可开始调试

方法二:

可直接【运行】、【调试】、【附加】

IDA动态调试so

  • IDA修改默认监听端口号(-p参数)

    1
    ./server -p 12345

调试app一启动就执行的native函数

JNI_OnLoad.init_proc.init_array

调试此类函数需要以debug模式启动app

  1. 启动android_server

    1. 复制IDA\dbgsrv\下的对应的android_server到手机的如/data/local/tmp/目录下,并给予执行权限
    2. su下运行server启动监听
  2. 开启端口转发(将设备与客户机间的23946端口连通

    1
    adb forward tcp:23946 tcp:23946
  3. 以debug模式启动Activity

    1
    adb shell am start -D -n [package_name]/[activity_name]
  4. 转发app运行端口到8700(可选,详见【步骤6】)

    1. 命令方式

      1
      adb forward tcp:8700 jdwp:[app_port]
    2. 使用ddms(monitor);位于Sdk\tools\monitor.bat(需下载)

      1. 打开monitor,选中app包名所在进程,该进程的port后会出现/8700
  5. IDA准备、附加进程

    1. IDA载入so,在native方法所需处下断点(可选)
    2. 配置调试器选项
      1. 选择调试器[Remote ARM Linux/ Android debugger]
      2. 菜单栏[Debugger][Process options]中,配置主机为localhost127.0.0.1(即本机),端口为默认23946(同server监听端口)
      3. 菜单栏[Debugger][Debugger options]中,可根据需要勾选Suspend on process entry point,Suspend on thread start/exit,Suspend on library load/unload
    3. 附加进程
      1. 选择菜单栏[Debugger][Attach to process],之后弹出一个可调试应用包名的窗口,ctrl F可以搜索,选择调试的应用包名,点击OK进行附加
  6. jdwp使app开始运行,此处的8700为【步骤4】中转发端口(若未执行步骤4,可使用ddms的最后一列数字)

    1
    jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700
  7. 返回IDA,

    1. 寻找加载的so

      1. 如果在【步骤5.2.3】中勾选了中断设置,先查看module窗口(ctrl+s)是否加载了所需的so,如果没有、需要F9运行程序再次查看,如此反复(或者查看IDA是否弹出【same】对话框?)

        如果没有勾选,F9运行则会直接弹出same对话框(记得在【步骤5.1】下断点);确定后会卡住一段时间

      2. 加载时,IDA会询问远程的so文件与本地的是否相同,选择【same】(选择后,so文件就被加载进来了)

      3. 加载后,双击so的module,会弹出module方法窗口,选择相应的方法如JNI_onLoad,并在相应地址如函数开头下断点

    2. 当被调试so加载进来并且下好断点后,F9运行,即可断在JNI_onLoad开头处

  8. 完成,可以愉快的调试啦。记得根据需要取消【步骤5.2.3】,不然会一直断下

调试可以手动触发的函数

自然也可以按照上面那种方式,但是比较慢,因为app要加载

或者

  1. 【如上步骤1】
  2. 【如上步骤2】
  3. 手动启动app,命令adb shell am start -n [package_name]/[activity_name](即去掉-D参数)
  4. 【如上步骤5】,一般不需要【步骤5.2.3】(根据自己情况)
  5. 【步骤4】附加完成后,会弹出【same】窗口,之后点击运行、触发断点,即可开始调试

错误踩坑解决

Smalidea调试

【附加】时无设备或进程

没有设备进程供选择,点击菜单栏【File】的【Invalidate Caches / Restart…】来清理缓存并重新启动AS

DDMS

DDMS总是启动失败

  • 切换java版本为1.8
  • 或者,拷贝java1.8的jre一份,放到Sdk\tools\lib\monitor-x86_64\jre

此外

debuggable属性

app在清单中添加debuggable属性

AndroidManifest.xmlapplication标签中添加android:debuggable="true"

修改设备的ro.debuggable=1

安装magisk后

1
2
3
magisk resetprop ro.debuggable 1
magisk resetprop ro.secure 0
magisk resetprop ro.adb.secure 0

重启设备后失效

magisk安装MagiskHide Props Config模块

主页:Magisk-Modules-Repo/MagiskHidePropsConf: MagiskHidePropsConf (github.com),最新版

使用命令props来修改

选择5 - Add/edit custom props

根据需要修改相应ro标志位,先输入key,y确定后再输入值

之后需要重启手机