第七节 动态调试入门
(第2章 安卓逆向基础)
学习目标
学完本节,希望你能够:
- 说出动态调试 在干啥:在应用运行时 观察和修改行为,和静态分析(只看反编译代码)的区别。
- 会用 adb logcat 看应用日志、过滤包名/标签,能根据日志分析崩溃或关键逻辑。
- 会用 Frida Hook Java 方法(如 isVIP、getPackageInfo),修改返回值;了解用 GDB/LLDB 调试 Native 层的大致步骤。
- 理解反调试是啥:应用检测调试器或 Frida,发现就退出;知道常见绕过思路(Hook ptrace、isDebuggerConnected 等),仅限授权环境。
阅读提示 :涉及 Hook、绕过反调试,仅限授权环境、学习与安全研究;不得对他人应用做未授权调试或传播。
常见疑问:动态调试和静态分析有啥区别?静态是「看代码」,动态是「跑起来看、改着看」;两者配合用效果最好。
一、动态调试是啥?
动态调试 (Dynamic Debugging)说白了就是在应用运行时去分析和修改它的行为 :设断点、看变量、改返回值、看日志等。和静态分析(反编译后只看代码)相比,动态能拿到真实参数、真实执行路径,还能在不改 APK 的前提下临时改行为。
动态 vs 静态一句话
| 方式 | 在干啥 | 好处 | 坏处 |
|---|---|---|---|
| 静态分析 | 反编译看代码,不运行 | 直接看结构、逻辑 | 看不到运行时数据,混淆难读 |
| 动态调试 | 运行时 Hook、断点、日志 | 真实数据、可改行为 | 要附加进程,可能触发反调试 |
记一句:静态搭骨架,动态填血肉------先静态理清逻辑,再动态验证、改行为。
二、用 adb logcat 看应用在干啥
在干啥:看应用打的日志,分析行为或崩溃
logcat 是 Android 的系统日志,应用里 Log.d / System.out.println 等会打到这儿。用 adb logcat 可以按包名、标签、级别过滤。
一般怎么干
bash
adb logcat -s "com.example.app"
adb logcat | grep "Hello Debugging"
adb logcat *:E
-s按标签过滤;grep按关键字过滤;*:E只看错误级别。
看崩溃时重点看 Exception 、FATAL 、at com.xxx 等堆栈。
三、用 Frida 做动态 Hook
在干啥:运行时替换方法实现,改返回值或打印参数
Frida 能在应用进程里注入脚本,Hook (挂钩)Java 或 Native 方法,在调用前后执行你的代码,例如让 isVIP() 恒返回 true、让 getPackageInfo 绕过签名校验。
一般怎么干:装 Frida Server + 写脚本
- 设备上跑 frida-server ,PC 上装 frida-tools。
- 写 JS 脚本,用 Java.use 、implementation Hook 目标类和方法。
- 用 frida -U -n 包名 -l 脚本 附加到应用并执行脚本。
示例:Hook isVIP() 恒返回 true
js
Java.perform(function() {
var MainActivity = Java.use("com.example.MainActivity");
MainActivity.isVIP.implementation = function() {
console.log("[*] Bypassing VIP check...");
return true;
};
});
bash
frida -U -n com.example.app -l hook.js --no-pause
Hook 签名校验(示例)
js
Java.perform(function() {
var PackageManager = Java.use("android.content.pm.PackageManager");
PackageManager.getPackageInfo.overload("java.lang.String", "int").implementation = function(pkg, flags) {
console.log("[*] Bypassing signature check for:", pkg);
return this.getPackageInfo(pkg, flags);
};
});
注意:仅限授权环境。
四、用 GDB/LLDB 调试 Native 层(了解即可)
在干啥:对 so 里的 C/C++ 函数下断点、看寄存器、单步执行
GDB 、LLDB 是调试 Native (so)的常用工具。步骤大致是:拿到进程 PID → 用 gdb -p <pid> 或 lldb -p <pid> 附加 → 在 so 里下断点(如 strcmp)→ 继续执行、看参数和返回值。
bash
adb shell ps | grep com.example.app
gdb -p <pid>
(gdb) b strcmp
(gdb) c
(这块入门阶段了解即可,以 Frida Hook Java 为主。)
五、反调试是啥?怎么绕?(仅限授权环境)
在干啥:应用检测是否被调试,检测到就退出或拒绝运行
常见手段:调 ptrace 防止被附加、调 Debug.isDebuggerConnected() 看是否连了调试器、检测 Frida 相关特征。绕过思路:不让检测函数「说实话」------用 Frida Hook 掉,让 ptrace 不生效、让 isDebuggerConnected 恒返回 false。
Hook ptrace(Native)
js
Interceptor.attach(Module.findExportByName(null, "ptrace"), {
onEnter: function(args) {
console.log("[*] Bypassing ptrace anti-debugging");
args[0] = ptr(0);
}
});
Hook isDebuggerConnected(Java)
js
Java.perform(function() {
var Debug = Java.use("android.os.Debug");
Debug.isDebuggerConnected.implementation = function() {
return false;
};
});
注意:仅限授权、合规环境;不得对他人应用做未授权调试或传播。
本节小结
你只要记住这几条就行:
- 动态调试 = 运行时观察和修改;和静态分析配合用,先静态理结构,再动态看数据、改行为。
- adb logcat 看应用日志;按包名、标签、级别过滤,崩溃时看堆栈。
- Frida Hook Java 方法:Java.use + implementation,可改返回值、打日志;GDB/LLDB 用于 Native 断点调试(入门了解即可)。
- 反调试:应用检测调试器/Frida;绕过思路是 Hook 检测函数(ptrace、isDebuggerConnected 等),仅限授权环境。
本节术语速查
| 术语 | 一句话解释 |
|---|---|
| 动态调试 | 在应用运行时观察、修改行为(断点、Hook、日志)。 |
| logcat | Android 系统日志,应用 Log 输出在这里。 |
| Hook | 运行时替换方法/函数实现,改变行为。 |
| ptrace | Linux 系统调用,常被用来防附加、做反调试。 |
本节思考与练习
- 概念:动态调试和静态分析分别解决什么问题?为啥说「静态搭骨架,动态填血肉」?
- 应用:若应用一打开就闪退,你会先用什么命令看大概原因?
- 动手:用 adb logcat 过滤一个应用的包名,打开应用并操作几下,看能否找到一条和业务相关的日志。
- 动手 :用 Frida Hook 一个应用的 isVIP() 或 checkLogin(),让返回值恒为 true,观察界面或功能是否变化。
下一节预告 :下一节讲使用 Frida Hook Java 方法 ,会细说 Java.use 、implementation 、overload、打印参数和返回值等,并练习多种 Hook 场景。