GKLBB

当你经历了暴风雨,你也就成为了暴风雨

导航

应用安全 --- 调试安卓so的所有方法分类

调试安卓原生共享库(.so文件,通常是C/C++代码)需要特定的工具和方法。以下是全面的安卓SO调试方法,涵盖主要工具和技术:


一、 核心调试工具链

  1. Android Studio + LLDB (推荐)

    • 配置:

      • 确保build.gradle中启用调试支持:
        android { defaultConfig { ndk { debuggable true } } }

      • CMakeLists.txt中设置调试符号:
        set(CMAKE_BUILD_TYPE Debug) 或 add_compile_options(-g)

    • 操作:

      • 点击Debug 'app'按钮 ▶️

      • Debug窗口选择LLDB标签

      • 设置断点、查看寄存器/内存、调用栈追踪

    • 优势: 图形化界面,与Java/Kotlin调试无缝集成

  2. 命令行调试 (ADB + LLDB/GDB)

    • 前置步骤:

      bash
       
      adb push $NDK/prebuilt/android-arm64/gdbserver/gdbserver /data/local/tmp
      adb shell chmod 755 /data/local/tmp/gdbserver
    • 启动调试:

      bash
       
      # 在设备上启动gdbserver
      adb shell /data/local/tmp/gdbserver :5039 --attach <PID>
      
      # 在主机上启动LLDB
      lldb
      (lldb) platform select remote-android
      (lldb) platform connect connect://<设备IP>:5039
      (lldb) target create /path/to/your/app.so

二、 日志与跟踪

  1. Android Logcat (原生日志)

    • 代码中插入:

      c
       
      #include <android/log.h>
      #define TAG "NativeLib"
      __android_log_write(ANDROID_LOG_DEBUG, TAG, "Debug message");
    • 查看: adb logcat | grep "NativeLib"

  2. Simpleperf (CPU性能分析)

    • 记录性能数据:

      bash
       
      adb shell simpleperf record -p <PID> --call-graph fp -o /data/local/tmp/perf.data
      adb pull /data/local/tmp/perf.data
    • 生成报告:

      bash
       
      python3 $NDK/simpleperf/report_html.py perf.data
  3. Perfetto (系统级跟踪)

    • 启用: 设备开发者选项 → 系统跟踪

    • 记录: 使用Perfetto命令行或Web UI捕获trace

    • 分析: 加载.perfetto-trace文件到 ui.perfetto.dev


三、 内存调试

  1. AddressSanitizer (ASan)

    • 启用 (CMake):

      cmake
       
      set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
    • 运行时: 自动检测内存越界、use-after-free错误,日志输出到logcat

  2. Valgrind (需Root)

    • 交叉编译Valgrind: 使用NDK编译arm版

    • 运行:

      bash
       
      adb shell valgrind --tool=memcheck /path/to/app
  3. Malloc Debug (Android原生)

    • 启用:

      bash
       
      adb shell setprop wrap.<package_name> '"LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper"'
    • 分析: 崩溃时生成/data/tombstones/tombstone_XX文件


四、 崩溃分析

  1. Tombstone 文件

    • 位置: /data/tombstones/tombstone_XX

    • 获取:

      bash
       
      adb pull /data/tombstones/tombstone_XX
    • 分析工具:

      bash
       
      $NDK/ndk-stack -sym /path/to/symbols -dump tombstone_XX
  2. Breakpad (Google崩溃收集)

    • 集成: 编译Breakpad库到项目

    • 生成符号: 使用dump_syms工具

    • 分析: 用minidump_stackwalk解析崩溃报告


五、 动态分析与逆向

  1. Frida (动态插桩)

    • Hook Native函数:

      javascript
       
      // hook libnative.so中的foo函数
      Interceptor.attach(Module.getExportByName("libnative.so", "foo"), {
        onEnter: function(args) {
          console.log("foo called with: " + args[0].toInt32());
        }
      });
    • 使用: frida -U -l script.js com.example.app

  2. IDA Pro/Ghidra (反汇编调试)

    • 远程调试:

      1. IDA加载.so文件

      2. 菜单: Debugger → Attach → Remote ARM Linux/Android debugger

      3. 配置主机IP和端口(需提前启动android_server

    • 用途: 无源码调试、漏洞分析、恶意代码研究


六、 高级技巧

  1. 检查OpenGL ES调用

    • 启用: adb shell setprop debug.egl.trace 1

    • 日志: GLES错误会输出到logcat

  2. 调试JNI调用

    • 启用JNI检查:

      bash
       
      adb shell setprop dalvik.vm.checkjni true
      adb shell setprop debug.checkjni 1
    • 常见错误: JNI DETECTED ERROR IN APPLICATION

  3. 无源码调试

    • 关键: 保留带符号的.so文件(obj/local/armeabi-v7a/libapp.so

    • LLDB加载符号:

      bash
       
      (lldb) target create --no-dependents --arch arm libapp.so

工具链对比表

工具用途优势限制
Android Studio+LLDB 源码级调试 图形化集成,断点/变量查看 需完整工程
Simpleperf CPU性能分析 低开销,火焰图生成 仅支持Android 5.0+
ASan 内存错误检测 实时检测内存漏洞 性能开销约2倍
Frida 动态Hook 无需重启APP,脚本灵活 需注入进程
IDA Pro 逆向与无源码调试 强大的反汇编能力 商业软件,学习曲线陡峭

关键注意事项

  1. ABI匹配: 确保调试器(lldb/gdb)与设备架构(arm64/x86)一致

  2. 符号文件: 保留编译生成的obj/local/<abi>/下的未strip的.so文件

  3. Android版本: NDK工具链版本需兼容目标系统API级别

  4. Root权限: 部分工具(如Valgrind)需root设备

建议从Android Studio + LLDB开始,再逐步使用Simpleperf/ASan进行深度优化。逆向场景选择Frida/IDA Pro组合。

 

 

两种调试方式的本质区别

特性附加调试 (Attach)调试模式启动 (Start in Debug Mode)
启动方式 附加到已运行进程 以调试模式启动新进程
调试时机 可调试运行中的代码 从APP入口点开始调试
JNI_OnLoad调试 可能错过早期初始化 可调试JNI_OnLoad等初始化函数
操作复杂度 简单直接 需要端口转发+jdb恢复执行
进程状态 进程已初始化完成 进程暂停在等待调试器状态
适用场景 运行时触发的函数调试 初始化过程/反调试绕过

核心区别图示:

text
 
附加调试: [APP已运行] → IDA附加 → 调试当前状态
调试启动: [启动命令] → APP暂停 → IDA附加 → jdb恢复 → 调试完整生命周期



调试方法选择矩阵

场景推荐方法工具组合
JNI_OnLoad调试 调试模式启动 + IDA IDA + jdb
运行时函数分析 附加调试 + Frida Hook Frida + IDA
算法还原 GDB指令级调试 GDB + GEF插件
内存取证 内存Dump + 静态分析 dd + 010 Editor
自动化分析 Frida脚本化调试 Frida + Python
源码级调试 LLDB集成调试

Android Studio + LLDB

 

 

 

 

 

posted on 2025-08-16 09:07  GKLBB  阅读(47)  评论(0)    收藏  举报