type
status
date
slug
summary
tags
category
icon
password
 
 

一、调试器

JPDA(Java Platform Debugger Architecture) 是 Java 平台调试体系结构的缩写,通过 JPDA 提供的 API,开发人员可以方便灵活的搭建 Java 调试应用程序。
JPDA 主要由三个部分组成:Java虚拟机工具接口(JVMTI),Java 调试线协议(JDWP),以及 Java 调试接口(JDI)
 

二、IDA调试So流程

一般情况下使用IDA进行so的调试,而且较多情况下为了绕过反调试或者消除混淆,需要在APP加载so时就需要完成调试器附加操作,而非当加载完成后再进行附加。因此本流程全面展示APP启动到加载完成so的全过程。
  • 启动DDMS
  • 然后需要将IDA对应版本的调试服务端拷贝到真机或模拟机中的任意目录下,给予可执行权限并启动需要调试的so版本对应的IDA调试服务端。
    • notion image
  • 除此之外,需要执行adb端口转发,将调试设备的23946端口转发到计算机的23946端口
    • 检查对应apk的属性,需要满足以下两个属性均为true,可以通过使用apktool解包后修改重新打包实现,也可以使用面具模块或xposed模块实现。
      • 💡
        android:extractNativeLibs = "true"时,gradle打包时会对工程中的so库进行压缩,最终生成apk包的体积会减小。但用户在手机端进行apk安装时,系统会对压缩后的so库进行解压,一般解压到/data/app/某一目录下,从而造成用户安装apk的时间变长。如果为false则不会解压到该目录。 minSdkVersion >= 23 并且 Android Gradle plugin >= 3.6.0情况下,打包时默认android:extractNativeLibs=false 如果该属性为false,虽然IDA可以正常附加,但是无法加载对应的so进行调试,所以如果未开启so压缩会直接导致程序执行的时候ida不能够识别到响应的so加载,导致无法定位到so中的代码从而无法停在断点。对于未开启so压缩的情况需要通过重打包来修改该字段以便可以定位到so。 针对性的,也有相应的模块,用于Hook安卓的安装器,让其在安装时将该属性的值设为true,从而能够正确的调试,例如项目
        ForceExtractNativeLibs
        AlienwareHeUpdated May 17, 2024
        AlienwareHe/ForceExtractNativeLibs: Force extractNativeLibs attr to true when pms parse apk (github.com)),即通过Xposed进行Hook在安装时重置该属性。
        💡
        如果不想这么复杂,直接把so 复制到/data/app/包名/lib里面,就会优先加载这个目录里面的so,或者直接在IDA中的module中选择base.apk,然后定位到需要调试的地址,然后手动按P将其转为code,然后就可以下断点调试
    • 然后使用adb命令使得待调试APP等待调试器附加
      notion image
      • IDA先与调试器服务端相连,这里host就为127.0.0.1 端口为23946
        • notion image
       
      • 当连接成功后,先设置调试器的选项,使得能够在入口、线程以及加载或卸载时自动段下来,除此之外就是自己设置几个断点。
        • notion image
      • 完成后使用IDA的附加Attach to process附加到对应的app
        • notion image
      • 附加完成后IDA会断到其他原生库的位置,例如libc.so,直接继续运行,直到不能继续运行为止,即到running状态。
        • notion image
      • 在完成该项工作后,打开DDMS查看端口,一般为8600,使用jdb进行调试协议的连接,使程序从等待调试的状态变为正在调试。
        • notion image
          除了使用DDMS查看端口外,也可以使用adb forward tcp:任意端口(一般8600/8700) jdwp:APPpid 进行端口转发,该操作不需要在开始启动DDMS。
      notion image
      • 完成上述操作后,IDA会再次断下来,此时只需要一直继续运行,IDA会自动断到各种入口或者个人设置的断点位置。如果前置步骤都没问题,在继续运行的过程中IDA会弹一个窗要求告知要调试的so是否和设备内的so是一样的,如果出现该弹窗说明成功,继续运行即可。然后就会断在linker的位置,之后就可以自己发挥了,因为so的加载过程是linker->.init -> .init array -> JNI_Onload -> java_com_xxx
        • notion image
          notion image
           
      ByteCTF2021 BabyDroid复现Zygisk源码分析
      • Twikoo