Xposed-Hook学习

前言

笔者羡慕那些即学即用的佬,自己没这么强的手搓能力。一个一个脚步踏实学习也是旅途的一大乐趣,感谢正己大佬的安卓逆向教学。

环境配置

demoapk: 52pojie
Lsposed
Android Studio
雷电模拟器
XposedBridgeAPI-89.jar
可自己论坛寻找

引言

介绍

Xposed是一款可以在不修改APK的情况下影响程序运行的框架,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。在这个框架下,我们可以编写并加载自己编写的插件APP,实现对目标apk的注入拦截等。

原理

用自己实现的app_process替换掉了系统原本提供的app_process,加载一个额外的jar包,入口从原来的: com.android.internal.osZygoteInit.main()被替换成了: de.robv.android.xposed.XposedBridge.main()
创建的Zygote进程就变成Hook的Zygote进程了,从而完成对zygote进程及其创建的Dalvik/ART虚拟机的劫持(zytoge注入)

hook

搭建

1.Android Studio创建新项目
2.将下载的xposedBridgeApi.jar包拖进libs文件夹
3.右击jar包,选择add as library

4.修改xml文件配置

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 是否是xposed模块,xposed根据这个来判断是否是模块 -->
<meta-data
android:name="xposedmodule"
android:value="true" />
<!-- 模块描述,显示在xposed模块列表那里第二行 -->
<meta-data
android:name="xposeddescription"
android:value="这是一个Xposed模块" />
<!-- 最低xposed版本号(lib文件名可知) -->
<meta-data
android:name="xposedminversion"
android:value="89" />

5.修改build.gradle,将此处修改为compileOnly 默认的是implementation

注:\\改/
implementation 使用该方式依赖的库将会参与编译和打包
compileOnly 只在编译时有效,不会参与打包
6.新建–>Folder–>Assets Folder,Assets Folder下创建xposed_init文件(不要后缀名):只有一行代码,就是说明入口类


7.新建Hook类,实现IXposedHookLoadPackage接口,然后在handleLoadPackage函数内编写Hook逻辑

1
2
3
4
5
6
7
8
9
10
package com.example.xposeddemo; //前面的导入包
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Hook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

}
}

继承了IXposedHookLoadPackag便拥有了hook的能力

hook简单方法和返回值

简单方法

打开模拟器logcat连接,目标:hook所选普通方法

对应jadx分析,右键复制为xposed片段

1
2
3
public final String a(String str) {
return "这是一个" + str + "方法";
}

接着在环境配置中的Hook类进行代码编写,缺的库可以alt + Enter快速补全导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.example.xposeddemo;
import android.util.Log;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Hook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals("com.zj.wuaipojie")){
return;
}
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "a", /*java.lang.可省略,根据具体类型定义*/String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
XposedBridge.log(param.args[0].toString()); //lsposed软件日志查看
Log.e("zj2595",param.args[0].toString()); //android自带Log
//d-debug e-error
String a = "pt";
param.args[0] = a;
Log.e("zj2595",param.args[0].toString());
}

@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
}
}

点击运行,之后Lsposed点击加载的xposeddemo,系统模块以及wuaipojie权限开下写入
无日志显示重启再打开wupojie.apk

返回值

1
2
3
4
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d("zj2595",param.getResult().toString());
param.setResult("123456");

复杂&自定义

1
2
3
private final void complexParameterFunc(String str, HashMap<Object, Object> map) {
Log.d(Tag, "这是复杂参数方法 || " + str);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.example.xposeddemo;
import android.util.Log;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Hook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals("com.zj.wuaipojie")){
return;
}
// XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "a", /*java.lang.可省略,根据具体类型定义*/String.class, new XC_MethodHook() {
// @Override
// protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// super.beforeHookedMethod(param);
//// XposedBridge.log(param.args[0].toString()); //lsposed软件日志查看
//// Log.d("zj2595",param.args[0].toString()); //android自带Log
//// //d-debug e-error
//// String a = "pt";
//// param.args[0] = a;
//// Log.d("zj2595",param.args[0].toString());
// }
//
// @Override
// protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// super.afterHookedMethod(param);
//// Log.d("zj2595",param.getResult().toString());
//// param.setResult("123456");
//
// }
// });
Class a = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedBridge.hookAllMethods(a, "complexParameterFunc", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.e("zj2595",param.args[0].toString());
}
});
}
}

替换函数

1
2
3
private final void repleaceFunc() {
Log.d(Tag, "这是替换函数");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.example.xposeddemo;
import android.util.Log;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Hook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (!loadPackageParam.packageName.equals("com.zj.wuaipojie")) {
return;
}
Class a = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedBridge.hookAllMethods(a, "repleaceFunc", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return "";
}
});

}
}


hook加固

借助application attach实现,有点像是hookmethod的二次嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.example.xposeddemo;

import android.app.Application;
import android.content.Context;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Hook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (!loadPackageParam.packageName.equals("com.zj.wuaipojie")) {
return;
}
XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Context context = (Context) param.args[0];
ClassLoader classLoader = context.getClassLoader();
//hook逻辑在这里面写
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", classLoader, "a", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
//log.e();
}

@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
//log.e();
}
});
}
});
}
}

Xposed-Hook学习
https://alenirving.github.io/2025/09/01/Xposed-Hook学习/
作者
Ma5k
发布于
2025年9月1日
许可协议