目录
  1. 1. 一、Xposed 框架原理
  2. 2. 二、XposedBridge API 详解
    1. 2.1. XposedHelpers
    2. 2.2. XC_MethodHook
    3. 2.3. XC_MethodReplacement
  3. 3. 三、Xposed 模块开发
  4. 4. 四、实战案例
    1. 4.1. 绕过 String.equals 检测
    2. 4.2. Hook 加密操作
    3. 4.3. 绕过 Root 检测
  5. 5. 五、Xposed vs EdXposed vs LSPosed
  6. 6. 面试常考问题
【逆向安全技术-工具篇】Hook神器XPosed

一、Xposed 框架原理

Xposed 是目前最强大的 Android Java 层 Hook 框架。其核心原理是劫持 Zygote 进程 —— 在 Android 启动过程中,Zygote 是所有应用进程的父进程,Xposed 向 Zygote 注入自己的 app_process,使得每个新应用进程启动时都会加载 XposedBridge.jar

# 加载链路(AOSP 源码参考)
/system/bin/app_process → Xposed 修改后的 app_process
→ ZygoteInit.java (frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
→ XposedBridge.jar 加载
→ 读取模块列表 → 为每个已注册的 Hook 方法安装拦截器

二、XposedBridge API 详解

Xposed 的核心 API 在 de.robv.android.xposed 包中:

XposedHelpers

// 查找类和方法
Class<?> cls = XposedHelpers.findClass("com.target.MyClass", classLoader);
XposedHelpers.findAndHookMethod("com.target.MyClass", classLoader,
"targetMethod", String.class, int.class, new XC_MethodHook() { ... });

XC_MethodHook

// 方法拦截回调
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// 方法执行前:查看/修改参数
String arg0 = (String) param.args[0];
XposedBridge.log("Called with arg: " + arg0);
param.args[0] = "modified_value"; // 修改参数
}

@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// 方法执行后:查看/修改返回值
boolean originalResult = (boolean) param.getResult();
param.setResult(true); // 强制改变返回值
}
};

XC_MethodReplacement

// 完全替换方法实现
XposedHelpers.findAndHookMethod("com.target.MyClass", classLoader,
"checkLicense", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) {
return true; // 直接返回 true,跳过原始逻辑
}
});

三、Xposed 模块开发

一个完整的 Xposed 模块包含:

1. 模块 Manifest 声明:

<application>
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="Bypass license check for TargetApp" />
<meta-data
android:name="xposedminversion"
android:value="82" />
</application>

2. Hook 入口类:

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

XposedHelpers.findAndHookMethod(
"com.target.app.VerifyActivity",
lpparam.classLoader,
"verify",
String.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
param.setResult("success"); // 强制返回 "success"
}
}
);
}
}

3. 声明入口(assets/xposed_init):

com.example.xposedmodule.MainHook

四、实战案例

绕过 String.equals 检测

// Hook String.equals 监控所有字符串比较
XposedHelpers.findAndHookMethod(String.class, "equals", Object.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
XposedBridge.log("String.equals: [" + param.thisObject
+ "] vs [" + param.args[0] + "]");
}
});

Hook 加密操作

// Hook Cipher.init 获取加密密钥
XposedHelpers.findAndHookMethod(
"javax.crypto.Cipher", lpparam.classLoader,
"init", int.class, Key.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
SecretKeySpec key = (SecretKeySpec) param.args[1];
XposedBridge.log("Cipher key: " + bytesToHex(key.getEncoded()));
}
});

绕过 Root 检测

// 大多数 root 检测通过 Runtime.exec("su") 或检查 /system/app/Superuser.apk
XposedHelpers.findAndHookMethod(File.class, "exists",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
String path = ((File) param.thisObject).getAbsolutePath();
if (path.contains("su") || path.contains("Superuser")) {
param.setResult(false); // 返回文件不存在
}
}
});

五、Xposed vs EdXposed vs LSPosed

特性 Xposed (Original) EdXposed LSPosed
原理 替换 app_process Riru / Zygisk 注入 Zygisk 注入
Android 版本 5.0 - 8.x 9 - 12 8.1 - 14
检测难度 极易被检测 中等 较难检测
维护状态 停止更新 停止更新 活跃维护
仓库 - github.com/ElderDrivers/EdXposed github.com/LSPosed/LSPosed

面试常考问题

Q1:Xposed Hook 和 Frida Hook 的区别?各自适用场景?
A:Xposed 工作在 Zygote 层,模块生命周期与应用绑定,Hook 是持久化的,更适合长期监控和模块化发布。Frida 通过注入 JS 引擎实现动态 Hook,无需重启设备,更灵活,适合临时调试和快速验证。Xposed 适合开发可复用的 Hook 模块,Frida 适合逆向分析时的即时探索。此外,Xposed 仅支持 Java 层,Frida 同时支持 Java 层和 Native 层。

Q2:为什么有些应用能检测到 Xposed?如何绕过?
A:常见检测方式:(1)检查 ClassLoader 中是否加载了 de.robv.android.xposed.XposedBridge;(2)通过 PackageManager 查找 Xposed Installer 包名;(3)检测 /system/lib/libxposed_art.so 等文件存在性;(4)抛异常检查调用栈中是否包含 Xposed 相关类。绕过手段:使用 LSPosed(支持隐藏)、Magisk + Shamiko 隐藏 Xposed 特征、在模块中 Hook 检测方法返回假值。

Q3:beforeHookedMethod 和 afterHookedMethod 的执行顺序是怎样的?如果多个模块 Hook 了同一个方法?
A:beforeHookedMethod 在原始方法执行前调用,afterHookedMethod 在原始方法执行后调用。多个模块 Hook 同一方法时,Xposed 按模块加载顺序链式调用:模块A的 before → 模块B的 before → 原始方法 → 模块B的 after → 模块A的 after。注意在 beforeHookedMethod 中调用 param.setResult() 会跳过原始方法和后续 Hook 链的 before。

打赏
  • 微信
  • 支付宝

评论