6、Hook框架入门(Xposed/Frida)

说到移动安全逆向,Hook 技术是绕不开的核心技能。我做了这么多年逆向,可以负责任地说——不会 Hook,你连 App 的门都摸不到。

这一章我们重点讲两个主流框架:Xposed 和 Frida。它们各有千秋,但都能让你在运行时“拦截”App 的方法调用,修改参数、返回值,甚至替换整个函数逻辑。

嗯,先别急着写代码。我们得先搞清楚它们是怎么工作的。

Xposed 框架原理与安装

Xposed 的原理,说白了就是替换了 Android 系统的 zygote 进程。zygote 是所有 App 的父进程,Xposed 在它启动时注入自己的代码,从而能 Hook 任意 App 的任意方法。

我个人习惯把 Xposed 理解为“系统级别的代理”。它修改了 ART 虚拟机的方法调用入口,让每个方法在被调用前都会经过 Xposed 的检查。

核心原理:Xposed 通过替换 app_process 二进制文件,在 zygote 启动时加载 XposedBridge.jar,从而获得对所有 App 的控制权。

安装步骤(以 Android 模拟器为例)

  1. 下载 Xposed Installer APK(建议用 3.1.5 版本,我踩过新版兼容性的坑)
  2. 在 Recovery 模式下刷入 Xposed 框架 ZIP 包
  3. 重启后打开 Xposed Installer,看到“框架已激活”就成功了

注意:Xposed 需要 Root 权限。而且 Android 7.0 以上版本兼容性较差,我建议用 Android 5.0~6.0 的模拟器学习。

编写第一个 Xposed 模块

写一个 Xposed 模块其实很简单。你只需要创建一个 Android 工程,添加 Xposed 的 API 依赖,然后实现 IXposedHookLoadPackage 接口。

我曾经帮一个朋友调试某社交 App 的加密参数,就是用 Xposed 直接 Hook 了加密方法的返回值。来看代码:

public class MainHook implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
        if (!lpparam.packageName.equals("com.example.target"))
            return;

        findAndHookMethod(
            "com.example.target.MainActivity",
            lpparam.classLoader,
            "getSecretKey",
            new XC_MethodReplacement() {
                @Override
                protected Object replaceHookedMethod(MethodHookParam param) {
                    // 直接返回我们自己的密钥
                    return "my_hacked_key_123";
                }
            }
        );
    }
}

这段代码做了什么?它 Hook 了 MainActivitygetSecretKey 方法,不管原来返回什么,现在都返回 "my_hacked_key_123"

小技巧:调试 Xposed 模块时,建议用 XposedBridge.log() 输出日志,比 Logcat 更直观。

Frida 框架原理与安装

Frida 和 Xposed 的思路完全不同。Frida 是动态注入,它通过 ptrace 或 frida-server 把 JavaScript 引擎注入到目标进程里。

说白了,Frida 更像是一个“运行时手术刀”。你不需要重启 App,甚至不需要修改任何系统文件。我特别喜欢这一点——调试效率高太多了。

安装步骤

  1. PC 端安装 Frida 工具:pip install frida-tools
  2. 手机端运行 frida-server(注意架构匹配,我吃过 arm64 和 arm 不匹配的亏)
  3. 端口转发:adb forward tcp:27042 tcp:27042
  4. 测试连接:frida-ps -U 能看到进程列表就对了

Frida JavaScript API 详解

Frida 的 JavaScript API 非常强大。我挑三个最常用的场景讲:拦截、调用、替换。

拦截方法调用

Java.perform(function() {
    var MainActivity = Java.use('com.example.target.MainActivity');
    MainActivity.getSecretKey.implementation = function() {
        console.log('[+] getSecretKey 被调用了');
        return 'hacked_by_frida';
    };
});

你看,比 Xposed 简洁不少吧?而且不需要编译,直接写 JS 就行。

调用原始方法

Java.perform(function() {
    var MainActivity = Java.use('com.example.target.MainActivity');
    // 先调用原始方法,再修改返回值
    var original = MainActivity.getSecretKey.implementation;
    MainActivity.getSecretKey.implementation = function() {
        var result = original.call(this);
        console.log('[+] 原始返回值: ' + result);
        return result + '_modified';
    };
});

替换整个方法

Java.perform(function() {
    var String = Java.use('java.lang.String');
    String.equals.implementation = function(other) {
        console.log('[+] equals 被调用: ' + other);
        // 让所有 equals 都返回 true
        return true;
    };
});

核心区别:Xposed 是静态 Hook(需要重启),Frida 是动态 Hook(实时注入)。Frida 的灵活性更高,但 Xposed 在系统级 Hook 上更稳定。

Frida 与 Xposed 对比分析

我经常被问到:“到底学哪个?” 我的答案是——两个都要会,但根据场景选。

对比维度 Xposed Frida
原理 替换 zygote 进程 动态注入 JS 引擎
是否需要 Root 是(frida-server 需要)
是否需要重启 每次修改模块需要重启 不需要,实时生效
开发语言 Java/Kotlin JavaScript
调试效率 低(编译+重启) 高(即时修改)
系统兼容性 Android 4.0~8.0 较好 Android 4.0~14 都支持
稳定性 高(系统级注入) 中等(可能被检测)

我个人习惯是:做系统级分析、写稳定模块用 Xposed;做快速调试、逆向分析用 Frida。你想想看,Frida 改一行代码就能看到效果,Xposed 还得编译安装重启——效率差距太大了。

避坑指南:我曾经在 Android 10 上折腾 Xposed 折腾了两天,最后发现官方早就停止维护了。现在新设备上,Frida 几乎是唯一选择。

知识体系总览

下面这张图是我自己整理的 Hook 框架知识结构,帮你快速建立全局认知:

Hook 框架知识体系 Hook 框架 Xposed Frida 替换 zygote Java 模块 需重启生效 动态注入 JS 脚本 实时生效 选择建议 系统级分析 → Xposed | 快速调试 → Frida | 新设备 → Frida

这张图把两个框架的核心差异和适用场景都标出来了。你保存下来,以后选框架时看一眼就明白了。

我的建议:初学者先学 Frida。门槛低、反馈快,能快速建立成就感。等你对 Hook 机制熟悉了,再回头研究 Xposed 的源码实现,理解会更深刻。


公众号:蓝海资料掘金营,微信deep3321