# XposedHook Demo
**Repository Path**: brozer/XposedHook-Demo
## Basic Information
- **Project Name**: XposedHook Demo
- **Description**: Xposed 框架学习demo实例
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 0
- **Created**: 2020-08-01
- **Last Updated**: 2025-11-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 一 什么是 hook
**hook 本质就是劫持函数调用**,但由于处于 linux 用户态,每个进程都有自己独立的进程空间,所以必须先注入到所要 hook 的进程空间,修改其内存中的进程代码,替换其过程表的符号地址。
**Android 中一般通过 ptrace 函数附加进程,然后向远程进程注入 so 库,从而达到监控以及远程进程关键函数挂钩。Hook 的难点在于寻找函数的入口点、替换函数,这就涉及到函数的连接与加载机制。**
# 二 Xposed
## 1、Xposed 框架实现 Hook 的原理介绍
zygote是Android 的核心,每运行一个App,Zygote 就会 fork 一个虚拟机实例来运行 app,Xposed
Framework 深入到了 Android 核心机制中,通过改造 Zygote 来实现一些很牛逼的功能。Zygote 的启
动配置在 /init.rc 脚 本 中 , 由 系 统 启 动 的 时 候 开 启 此 进 程,对应的执行文件是
/system/bin/app_process,这个文件完成类库加载及一些函数调用的工作。
当系统中安装了 Xposed Framework 之后,会对 app_process 进行扩展,也就是说,Xposed Framework
会拿自己实现的 app_process 覆盖掉 Android 原生提供的 app_process 文件,当系统启动的时候,
就会加载由 Xposed Framework 替换过的进程文件,并且,Xposed Framework 还定义了一个 jar 包,
系统启动的时候,也会加载这个包:
/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar
## 2、Xposed 框架运行的条件
1.Rooted Device / Emulator (已 root 的手机或者模拟器)
2.Xposed Installer (Xposed 安装程序下载)
3.Hooking Android App (要被 Hook 的目标 App)
Xposed Framework 就是一个 apk 包也就是上面下载的 Xposed 安装程序,下载后用下面的命令安装到手
机上或者模拟器:
adb install Xposed.apk
app
framework
C++
linux内核
linux内核 --> init --> app_process --> Zygote
Zygote进程在启动过程中,除了创建一个Dalvik虚拟机实例之外,还会将Java运行时库加载到进程中来,同时还会注册一些Android核心类的JNI方法到前面创建的Dalvik虚拟机实例中去。
一个应用程序被孵化出来的时候,其不仅会获得Zygote进程中的Dalvik虚拟机实例,还会与Zygote一起共享Java运行时库,这也是可以将XposedBridge.jar这个jar包加载到每一个Android应用中的原因。
Xposed_zygote进程启动后会初始化一些so文件(system/lib system/lib64),然后进入XposedBridge.jar中的XposedBridge中加载模块,初始化jar包完成对一些关键Android系统函数的hook。
Hook则是利用修改过的虚拟机将函数注册为native函数,然后再返回zygote中完成原本zygote需要做的工作。
META-INF/ 里面有文件配置脚本 flash-script.sh 配置各个文件安装位置。
system/bin/ 替换zygote进程等文件
system/framework/XposedBridge.jar jar包位置
system/lib system/lib64 一些so文件所在位置
xposed.prop xposed版本说明文件
下载XposedBridge地址:https://github.com/
现在安装Xposed比较方便,因为Xposed作者开发了一个Xposed Installer App,下载后按照提示傻瓜式安装(前提是root手机)。其实它的安装过程是这个样子的:首先探测手机型号,然后按照手机版本下载不同的刷机包,最后把Xposed刷机包刷入手机重启就好。
# 三 模块 和 实现一个模块
本例中的 module 叫 axht.trade.xposed, 下面是这个实例的 AndroidManifest.xml 文件,注意其中定义了三项 meta-data:
- 1. Module name
- 2. Module Description
- 3. Module Minimum Version
```
```
其中 xposedminversion 是指 XposedBridge library 的版本,需要将 Xposed Library 复制到 lib目录 ( **注意是 lib 目录不是 libs 目录**),然后将这个 jar 包添加到 Build PATH 中,[jar 包可以在这里下载](http://forum.xda-developers.com/attachment.php?attachmentid=2748878&d=1400342298)。
然后在 src 目录下面建立一个 java 文件,就叫 bypass.java 吧,并在 assets 目录中新建一个叫 xposed_init 的文件,里面写上刚才建立的 java 文件的包路径,这样,我们的 apk 就可以被识别为一个 Xposed 模块了
`axht.trade.xposed.Test`
现在来看看要 hook 的 apk 包,要 hook,关键是要知道 hook 的点,即要明确要 hook 的函数名,实际使用中可以用 jeb 等反编译工具得到需要 hook 的函数名,我们这里就直接看样例 app 的源码吧:
```
package axht.trade.xposed;
import android.view.View;
import android.widget.EditText;
import java.lang.reflect.Field;
import java.security.MessageDigest;
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 Test implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam pparam) throws Throwable {
// pparam.processName 获取应用程序包名
// XposedBridge.log("当前启动的应用程序是:"+pparam.processName);
if (pparam.packageName.equals("com.qianyu.zhuceji")) {
XposedBridge.log("进入包名:"+pparam.packageName);
//hook 普通方法、静态方法
XposedHelpers.findAndHookMethod(
"com.qianyu.zhuceji.MainActivity", //包名+类名
pparam.classLoader, //类的加载器
"checkSN", //方法名
String.class, //参数列表
String.class,
new XC_MethodHook() {
/**
* HOOK之前
* 打印参数信息、修改参数
* */
@Override
protected void beforeHookedMethod(MethodHookParam param)
throws Throwable {
super.beforeHookedMethod(param);
XposedBridge.log("修改之前userName:" + param.args[0]);
XposedBridge.log("修改之前sn:" + param.args[1]);
String userName = (String) param.args[0];
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(userName.getBytes());
//主动调用方法
String hexstr = (String) XposedHelpers.callStaticMethod(
param.thisObject.getClass(), //获取类
"toHexString",
new Object[]{digest.digest(), ""});
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hexstr.length(); i += 2) {
sb.append(hexstr.charAt(i));
}
//修改参数
//param.args[0]="ke.yijincc.com";
//param.args[1]="3192850648@qq.com";
param.args[1] = sb.toString();
XposedBridge.log("修改之后sn:" + param.args[1]);
/**
* java反射机制
* */
// 获取类
Class> clazz=param.thisObject.getClass();
//XposedBridge.log("clazz:"+clazz);
// 获取字段
Field sn=clazz.getDeclaredField("edit_sn");
// 设置可见
sn.setAccessible(true);// 注意
EditText et_sn=(EditText) sn.get(param.thisObject);
et_sn.setText(sb.toString());
}
/**
* HOOK之后
* 打印返回值信息、修改返回值
* */
@Override
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("返回值:" + param.getResult());
//修改返回值之后
//param.setResult(true);
}
});
//hook 匿名内部类
XposedHelpers.findAndHookMethod(
"com.qianyu.zhuceji.MainActivity$1",
pparam.classLoader,
"onClick",
View.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param)
throws Throwable {
super.beforeHookedMethod(param);
View view = (View) param.args[0];
XposedBridge.log("view:" + view.getId());
}
});
}
}
}
```
**实现模块还要完成下面几个步骤**
- 1.实现 IXposedHookLoadPackage接口
- 2.指定要 hook 的包名(这里是com.attify.vuln)
- 3.判断当前加载的包是否是指定的包(在接口方法中判断
- 4.指定要 hook 的方法名
- 5.实现beforeHookedMethod方法和afterHookedMethod方法(hook的具体功能)
# 四 安装模块并重启
将需要被hook的app安装到模拟器或真机。将步骤三的模块安装到手机上面。打开 Xposed Installer 应用,点击模块,此时会发现模块列表已经检测到了XposedHookDeme。勾选模块,并返回主界面,点击框架,选中安装/更新,会提示重启手机。重启手机后,就能注入指定包名的app进程劫持对应的函数了。