安卓动态调试程序的4种方法
字数 1684 2025-08-22 12:22:24

安卓动态调试程序的4种方法详解

一、smalidea动态调试smali

1. 安装smalidea插件

2. 解包并配置AS

  1. 使用apktool反编译APK:
    apktool d 应用调试.apk
    
  2. 用Android Studio打开反编译后的smali目录

3. 配置调试环境

  1. 启动安卓模拟器
  2. 安装待调试程序:
    adb install aaa.apk
    
  3. 开启调试状态:
    adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity
    
  4. 转发端口:
    # 查看待调试程序pid
    adb shell ps | grep hfdcxy
    # 转发端口([pid]为实际pid值)
    adb forward tcp:8700 jdwp:[pid]
    

4. 开始调试

  1. 在AS中设置断点
  2. 点击调试按钮开始调试

二、Frida动态调试

1. 安装配置

  1. 安装Frida:

    sudo pip install frida
    
  2. 下载frida-server:

    • 真机: frida-server-版本-android-arm.xz
    • 模拟器: frida-server-版本-android-x86.xz
    • 64位系统选择带_64后缀的文件
  3. 推送并运行frida-server:

    adb push "frida-server文件路径" data/local/tmp
    adb shell
    su
    cd data/local/tmp
    chmod 777 frida-server
    ./frida-server
    

2. 使用Frida进行hook

  1. 端口转发:
    adb forward tcp:27042 tcp:27042
    
  2. 运行hook脚本示例:
    import frida, sys
    
    jscode = """
    Java.perform(function(){
        var hook_cls = Java.use('hfdcxy.com.myapplication.MainActivity')
        hook_cls.check.implementation = function(a,b){
            console.log("Hook Start...");
            send(arguments);
            a = "hfdcxy";
            b = "1234";
            send("Success!");
            send("name:" + a +" "+ "passwaord:" + b);
            return this.check(a,b);
        }
    });
    """
    
    def message(message, data):
        if message["type"] == 'send':
            print("[*] {0}".format(message["payload"]))
        else:
            print(message)
    
    device = frida.get_usb_device()
    pid = device.spawn("hfdcxy.com.myapplication")
    process = device.attach(pid)
    script = process.create_script(jscode)
    script.on("message", message)
    script.load()
    device.resume(pid)
    sys.stdin.read()
    

三、JEB动态调试APK

  1. 以调试模式启动APK:
    adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity
    
  2. 打开JEB,选择对应进程进行调试
  3. 可查看寄存器和内存信息

四、IDA动态调试.so文件

1. 准备环境

  1. 推送调试服务器到设备:
    adb push xxx/xxx/android_x86_server /data/local/tmp/
    
  2. 设置权限并启动:
    adb shell
    cd /data/local/tmp
    chmod 755 android_x86_server
    ./android_x86_server
    
  3. 端口转发:
    adb forward tcp:23946 tcp:23946
    

2. 调试步骤

  1. 以调试模式启动Activity:
    adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity
    
  2. 在IDA中选择Debugger -> Attach process
  3. 选择目标进程进行附加调试
  4. 可在汇编代码中下断点进行调试

五、smali语言基础

1. 基本语法

  • .field private isFlag:z - 定义变量
  • .method - 方法开始
  • .parameter - 方法参数
  • .prologue - 方法开始标记
  • .line 12 - 代码行号
  • invoke-super - 调用父类方法
  • const/high16 v0, 0x7fo3 - 赋值操作
  • return-void - 返回void
  • .end method - 方法结束

2. 数据类型

  • 基本类型:
    • B - byte
    • C - char
    • D - double
    • F - float
    • I - int
    • J - long
    • S - short
    • V - void
    • Z - boolean
  • 对象类型: Lxxx/yyy/zzz;
  • 数组类型: [I表示int数组,[[I表示二维int数组

3. 寄存器与变量

  • 寄存器命名:
    • v - 本地寄存器
    • p - 参数寄存器
  • 寄存器分配示例:
    .registers 6  # 总寄存器数
    .locals 2     # 本地寄存器数
    # 寄存器分配:
    # v0 - 第一个本地寄存器
    # v1 - 第二个本地寄存器
    # v2=p0 (this)
    # v3=p1 - 第一个参数
    # v4=p2 - 第二个参数
    # v5=p3 - 第三个参数
    

4. 方法签名

  • 格式: methodName(III)Lpackage/name/ObjectName;
  • 示例: Lpackage/name/ObjectName;->methodName(III)Z 表示:
    boolean methodName(int a, int b, int c) {
        // 方法体
    }
    

5. 条件跳转指令

  • if-eq vA, vB, :cond_x - 等于跳转
  • if-ne vA, vB, :cond_x - 不等于跳转
  • if-lt vA, vB, :cond_x - 小于跳转
  • if-ge vA, vB, :cond_x - 大于等于跳转
  • if-gt vA, vB, :cond_x - 大于跳转
  • if-le vA, vB, :cond_x - 小于等于跳转
  • if-eqz vA, :cond_x - 等于0跳转
  • if-nez vA, :cond_x - 不等于0跳转

六、常用ADB命令

  • 启动模拟器:
    emulator -avd 666 -writable-system
    
  • 获取root权限:
    adb root
    adb remount
    
  • 安装APK:
    adb install /xxx/xxx.apk
    
  • 文件传输:
    adb push /pc/path /device/path
    adb pull /device/path /pc/path
    
  • 查看进程:
    adb shell ps | grep 包名
    

七、总结

四种动态调试方法各有优势:

  1. smalidea: 适合调试smali代码
  2. Frida: 适合hook Java方法
  3. JEB: 适合查看寄存器和内存信息
  4. IDA: 适合调试native代码(.so文件)

根据实际需求选择合适的调试方法,或组合使用多种方法进行综合分析。

安卓动态调试程序的4种方法详解 一、smalidea动态调试smali 1. 安装smalidea插件 下载地址: https://bitbucket.org/JesusFreke/smali/downloads/smalidea-0.05.zip 安装步骤: 打开Android Studio 进入Settings->Plugins 点击"Install plugin from disk" 选择下载好的压缩包进行安装 2. 解包并配置AS 使用apktool反编译APK: 用Android Studio打开反编译后的smali目录 3. 配置调试环境 启动安卓模拟器 安装待调试程序: 开启调试状态: 转发端口: 4. 开始调试 在AS中设置断点 点击调试按钮开始调试 二、Frida动态调试 1. 安装配置 安装Frida: 下载frida-server: 真机: frida-server-版本-android-arm.xz 模拟器: frida-server-版本-android-x86.xz 64位系统选择带_ 64后缀的文件 推送并运行frida-server: 2. 使用Frida进行hook 端口转发: 运行hook脚本示例: 三、JEB动态调试APK 以调试模式启动APK: 打开JEB,选择对应进程进行调试 可查看寄存器和内存信息 四、IDA动态调试.so文件 1. 准备环境 推送调试服务器到设备: 设置权限并启动: 端口转发: 2. 调试步骤 以调试模式启动Activity: 在IDA中选择Debugger -> Attach process 选择目标进程进行附加调试 可在汇编代码中下断点进行调试 五、smali语言基础 1. 基本语法 .field private isFlag:z - 定义变量 .method - 方法开始 .parameter - 方法参数 .prologue - 方法开始标记 .line 12 - 代码行号 invoke-super - 调用父类方法 const/high16 v0, 0x7fo3 - 赋值操作 return-void - 返回void .end method - 方法结束 2. 数据类型 基本类型: B - byte C - char D - double F - float I - int J - long S - short V - void Z - boolean 对象类型: Lxxx/yyy/zzz; 数组类型: [I 表示int数组, [[I 表示二维int数组 3. 寄存器与变量 寄存器命名: v - 本地寄存器 p - 参数寄存器 寄存器分配示例: 4. 方法签名 格式: methodName(III)Lpackage/name/ObjectName; 示例: Lpackage/name/ObjectName;->methodName(III)Z 表示: 5. 条件跳转指令 if-eq vA, vB, :cond_x - 等于跳转 if-ne vA, vB, :cond_x - 不等于跳转 if-lt vA, vB, :cond_x - 小于跳转 if-ge vA, vB, :cond_x - 大于等于跳转 if-gt vA, vB, :cond_x - 大于跳转 if-le vA, vB, :cond_x - 小于等于跳转 if-eqz vA, :cond_x - 等于0跳转 if-nez vA, :cond_x - 不等于0跳转 六、常用ADB命令 启动模拟器: 获取root权限: 安装APK: 文件传输: 查看进程: 七、总结 四种动态调试方法各有优势: smalidea: 适合调试smali代码 Frida: 适合hook Java方法 JEB: 适合查看寄存器和内存信息 IDA: 适合调试native代码(.so文件) 根据实际需求选择合适的调试方法,或组合使用多种方法进行综合分析。